Merge JDK-8200758-branch
authorherrick
Thu, 10 Oct 2019 10:57:42 -0400
branchJDK-8200758-branch
changeset 58539 327232be010c
parent 58538 12c965587689 (current diff)
parent 58537 30a9612a657d (diff)
child 58581 657e25d9e4e4
Merge
src/java.base/share/native/libjava/verify_stub.c
src/java.base/share/native/libverify/check_format.c
src/java.base/unix/native/libjava/jdk_util_md.c
src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/JMXServiceProvider.java
src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/package-info.java
test/hotspot/jtreg/compiler/graalunit/EA9Test.java
test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/JLModule.java
test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineDeleteJmethod.java
test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/libRedefineDeleteJmethod.c
--- a/.hgtags	Wed Oct 09 10:58:20 2019 -0400
+++ b/.hgtags	Thu Oct 10 10:57:42 2019 -0400
@@ -589,3 +589,5 @@
 9c250a7600e12bdb1e611835250af3204d4aa152 jdk-13-ga
 778fc2dcbdaa8981e07e929a2cacef979c72261e jdk-14+15
 d29f0181ba424a95d881aba5eabf2e393abcc70f jdk-14+16
+5c83830390baafb76a1fbe33443c57620bd45fb9 jdk-14+17
+e84d8379815ba0d3e50fb096d28c25894cb50b8c jdk-14+18
--- a/make/CreateJmods.gmk	Wed Oct 09 10:58:20 2019 -0400
+++ b/make/CreateJmods.gmk	Thu Oct 10 10:57:42 2019 -0400
@@ -86,16 +86,18 @@
 # from there. These files were explicitly filtered or modified in <module>-copy
 # targets. For the rest, just pick up everything from the source legal dirs.
 LEGAL_NOTICES := \
-    $(SUPPORT_OUTPUTDIR)/modules_legal/common \
+    $(wildcard $(SUPPORT_OUTPUTDIR)/modules_legal/common) \
     $(if $(wildcard $(SUPPORT_OUTPUTDIR)/modules_legal/$(MODULE)), \
       $(wildcard $(SUPPORT_OUTPUTDIR)/modules_legal/$(MODULE)), \
       $(call FindModuleLegalSrcDirs, $(MODULE)) \
     )
 
-LEGAL_NOTICES_PATH := $(call PathList, $(LEGAL_NOTICES))
-DEPS += $(call FindFiles, $(LEGAL_NOTICES))
+ifneq ($(strip $(LEGAL_NOTICES)), )
+  LEGAL_NOTICES_PATH := $(call PathList, $(LEGAL_NOTICES))
+  DEPS += $(call FindFiles, $(LEGAL_NOTICES))
 
-JMOD_FLAGS += --legal-notices $(LEGAL_NOTICES_PATH)
+  JMOD_FLAGS += --legal-notices $(LEGAL_NOTICES_PATH)
+endif
 
 ifeq ($(filter-out jdk.incubator.%, $(MODULE)), )
   JMOD_FLAGS += --do-not-resolve-by-default
--- a/make/autoconf/version-numbers	Wed Oct 09 10:58:20 2019 -0400
+++ b/make/autoconf/version-numbers	Thu Oct 10 10:57:42 2019 -0400
@@ -35,7 +35,7 @@
 DEFAULT_VERSION_DATE=2020-03-17
 DEFAULT_VERSION_CLASSFILE_MAJOR=58  # "`$EXPR $DEFAULT_VERSION_FEATURE + 44`"
 DEFAULT_VERSION_CLASSFILE_MINOR=0
-DEFAULT_ACCEPTABLE_BOOT_VERSIONS="12 13 14"
+DEFAULT_ACCEPTABLE_BOOT_VERSIONS="13 14"
 DEFAULT_JDK_SOURCE_TARGET_VERSION=14
 DEFAULT_PROMOTED_VERSION_PRE=ea
 
--- a/make/conf/jib-profiles.js	Wed Oct 09 10:58:20 2019 -0400
+++ b/make/conf/jib-profiles.js	Thu Oct 10 10:57:42 2019 -0400
@@ -365,7 +365,7 @@
         };
     };
 
-    common.boot_jdk_version = "12";
+    common.boot_jdk_version = "13";
     common.boot_jdk_build_number = "33";
     common.boot_jdk_home = input.get("boot_jdk", "install_path") + "/jdk-"
         + common.boot_jdk_version
--- a/make/gensrc/Gensrc-jdk.internal.vm.compiler.management.gmk	Wed Oct 09 10:58:20 2019 -0400
+++ b/make/gensrc/Gensrc-jdk.internal.vm.compiler.management.gmk	Thu Oct 10 10:57:42 2019 -0400
@@ -73,7 +73,7 @@
 	($(CD) $(GENSRC_DIR)/META-INF/providers && \
 	    p=""; \
 	    impl=""; \
-	    for i in $$($(GREP) '^' * | $(SORT) -t ':' -k 2 | $(SED) 's/:.*//'); do \
+	    for i in $$($(NAWK) '$$0=FILENAME" "$$0' * | $(SORT) -k 2 | $(SED) 's/ .*//'); do \
 	      c=$$($(CAT) $$i | $(TR) -d '\n\r'); \
 	      if test x$$p != x$$c; then \
                 if test x$$p != x; then \
--- a/make/lib/CoreLibraries.gmk	Wed Oct 09 10:58:20 2019 -0400
+++ b/make/lib/CoreLibraries.gmk	Thu Oct 10 10:57:42 2019 -0400
@@ -23,8 +23,6 @@
 # questions.
 #
 
-WIN_VERIFY_LIB := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libverify/verify.lib
-
 # Hook to include the corresponding custom file, if present.
 $(eval $(call IncludeCustomExtension, lib/CoreLibraries.gmk))
 
@@ -110,14 +108,14 @@
     LDFLAGS_macosx := -L$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/, \
     LDFLAGS_windows := -delayload:shell32.dll, \
     LIBS := $(BUILD_LIBFDLIBM_TARGET), \
-    LIBS_unix := -ljvm -lverify, \
+    LIBS_unix := -ljvm, \
     LIBS_linux := $(LIBDL), \
     LIBS_solaris := -lsocket -lnsl -lscf $(LIBDL), \
     LIBS_aix := $(LIBDL) $(LIBM),\
     LIBS_macosx := -framework CoreFoundation \
         -framework Foundation \
         -framework SystemConfiguration, \
-    LIBS_windows := jvm.lib $(WIN_VERIFY_LIB) \
+    LIBS_windows := jvm.lib \
         shell32.lib delayimp.lib \
         advapi32.lib version.lib, \
 ))
--- a/src/hotspot/cpu/aarch64/aarch64.ad	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/aarch64.ad	Thu Oct 10 10:57:42 2019 -0400
@@ -2513,17 +2513,8 @@
     __ INSN(REG, as_Register(BASE));                                    \
   }
 
-typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr);
-typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr);
-typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
-                                  MacroAssembler::SIMD_RegVariant T, const Address &adr);
-
-  // Used for all non-volatile memory accesses.  The use of
-  // $mem->opcode() to discover whether this pattern uses sign-extended
-  // offsets is something of a kludge.
-  static void loadStore(MacroAssembler masm, mem_insn insn,
-                         Register reg, int opcode,
-                         Register base, int index, int size, int disp)
+
+static Address mem2address(int opcode, Register base, int index, int size, int disp)
   {
     Address::extend scale;
 
@@ -2542,16 +2533,34 @@
     }
 
     if (index == -1) {
-      (masm.*insn)(reg, Address(base, disp));
+      return Address(base, disp);
     } else {
       assert(disp == 0, "unsupported address mode: disp = %d", disp);
-      (masm.*insn)(reg, Address(base, as_Register(index), scale));
+      return Address(base, as_Register(index), scale);
     }
   }
 
+
+typedef void (MacroAssembler::* mem_insn)(Register Rt, const Address &adr);
+typedef void (MacroAssembler::* mem_insn2)(Register Rt, Register adr);
+typedef void (MacroAssembler::* mem_float_insn)(FloatRegister Rt, const Address &adr);
+typedef void (MacroAssembler::* mem_vector_insn)(FloatRegister Rt,
+                                  MacroAssembler::SIMD_RegVariant T, const Address &adr);
+
+  // Used for all non-volatile memory accesses.  The use of
+  // $mem->opcode() to discover whether this pattern uses sign-extended
+  // offsets is something of a kludge.
+  static void loadStore(MacroAssembler masm, mem_insn insn,
+                        Register reg, int opcode,
+                        Register base, int index, int size, int disp)
+  {
+    Address addr = mem2address(opcode, base, index, size, disp);
+    (masm.*insn)(reg, addr);
+  }
+
   static void loadStore(MacroAssembler masm, mem_float_insn insn,
-                         FloatRegister reg, int opcode,
-                         Register base, int index, int size, int disp)
+                        FloatRegister reg, int opcode,
+                        Register base, int index, int size, int disp)
   {
     Address::extend scale;
 
@@ -2573,8 +2582,8 @@
   }
 
   static void loadStore(MacroAssembler masm, mem_vector_insn insn,
-                         FloatRegister reg, MacroAssembler::SIMD_RegVariant T,
-                         int opcode, Register base, int index, int size, int disp)
+                        FloatRegister reg, MacroAssembler::SIMD_RegVariant T,
+                        int opcode, Register base, int index, int size, int disp)
   {
     if (index == -1) {
       (masm.*insn)(reg, T, Address(base, disp));
@@ -3791,7 +3800,7 @@
     static const int hi[Op_RegL + 1] = { // enum name
       0,                                 // Op_Node
       0,                                 // Op_Set
-      OptoReg::Bad,                       // Op_RegN
+      OptoReg::Bad,                      // Op_RegN
       OptoReg::Bad,                      // Op_RegI
       R0_H_num,                          // Op_RegP
       OptoReg::Bad,                      // Op_RegF
@@ -6923,7 +6932,7 @@
 instruct loadP(iRegPNoSp dst, memory mem)
 %{
   match(Set dst (LoadP mem));
-  predicate(!needs_acquiring_load(n));
+  predicate(!needs_acquiring_load(n) && (n->as_Load()->barrier_data() == 0));
 
   ins_cost(4 * INSN_COST);
   format %{ "ldr  $dst, $mem\t# ptr" %}
@@ -7616,6 +7625,7 @@
 instruct loadP_volatile(iRegPNoSp dst, /* sync_memory*/indirect mem)
 %{
   match(Set dst (LoadP mem));
+  predicate(n->as_Load()->barrier_data() == 0);
 
   ins_cost(VOLATILE_REF_COST);
   format %{ "ldar  $dst, $mem\t# ptr" %}
@@ -8552,6 +8562,7 @@
 instruct compareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
 
   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
+  predicate(n->as_LoadStore()->barrier_data() == 0);
   ins_cost(2 * VOLATILE_REF_COST);
 
   effect(KILL cr);
@@ -8665,7 +8676,7 @@
 
 instruct compareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
 
-  predicate(needs_acquiring_load_exclusive(n));
+  predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
   match(Set res (CompareAndSwapP mem (Binary oldval newval)));
   ins_cost(VOLATILE_REF_COST);
 
@@ -8796,6 +8807,7 @@
 %}
 
 instruct compareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+  predicate(n->as_LoadStore()->barrier_data() == 0);
   match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
   ins_cost(2 * VOLATILE_REF_COST);
   effect(TEMP_DEF res, KILL cr);
@@ -8895,7 +8907,7 @@
 %}
 
 instruct compareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
-  predicate(needs_acquiring_load_exclusive(n));
+  predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
   match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
   ins_cost(VOLATILE_REF_COST);
   effect(TEMP_DEF res, KILL cr);
@@ -8996,6 +9008,7 @@
 %}
 
 instruct weakCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+  predicate(n->as_LoadStore()->barrier_data() == 0);
   match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
   ins_cost(2 * VOLATILE_REF_COST);
   effect(KILL cr);
@@ -9103,8 +9116,8 @@
 %}
 
 instruct weakCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
-  predicate(needs_acquiring_load_exclusive(n));
   match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
+  predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
   ins_cost(VOLATILE_REF_COST);
   effect(KILL cr);
   format %{
@@ -9154,6 +9167,7 @@
 %}
 
 instruct get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev) %{
+  predicate(n->as_LoadStore()->barrier_data() == 0);
   match(Set prev (GetAndSetP mem newv));
   ins_cost(2 * VOLATILE_REF_COST);
   format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
@@ -9197,7 +9211,7 @@
 %}
 
 instruct get_and_setPAcq(indirect mem, iRegP newv, iRegPNoSp prev) %{
-  predicate(needs_acquiring_load_exclusive(n));
+  predicate(needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == 0));
   match(Set prev (GetAndSetP mem newv));
   ins_cost(VOLATILE_REF_COST);
   format %{ "atomic_xchg_acq  $prev, $newv, [$mem]" %}
--- a/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/compiledIC_aarch64.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -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.
  * Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -162,16 +162,12 @@
   // Creation also verifies the object.
   NativeMovConstReg* method_holder
     = nativeMovConstReg_at(stub + NativeInstruction::instruction_size);
-#ifndef PRODUCT
-  NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
 
-  // read the value once
-  volatile intptr_t data = method_holder->data();
-  assert(data == 0 || data == (intptr_t)callee(),
-         "a) MT-unsafe modification of inline cache");
-  assert(data == 0 || jump->jump_destination() == entry,
-         "b) MT-unsafe modification of inline cache");
+#ifdef ASSERT
+  NativeGeneralJump* jump = nativeGeneralJump_at(method_holder->next_instruction_address());
+  verify_mt_safe(callee, entry, method_holder, jump);
 #endif
+
   // Update stub.
   method_holder->set_data((intptr_t)callee());
   NativeGeneralJump::insert_unconditional(method_holder->next_instruction_address(), entry);
--- a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -24,22 +24,23 @@
 #include "precompiled.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "code/codeBlob.hpp"
+#include "code/vmreg.inline.hpp"
 #include "gc/z/zBarrier.inline.hpp"
 #include "gc/z/zBarrierSet.hpp"
 #include "gc/z/zBarrierSetAssembler.hpp"
 #include "gc/z/zBarrierSetRuntime.hpp"
+#include "gc/z/zThreadLocalData.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/sharedRuntime.hpp"
+#include "utilities/macros.hpp"
 #ifdef COMPILER1
 #include "c1/c1_LIRAssembler.hpp"
 #include "c1/c1_MacroAssembler.hpp"
 #include "gc/z/c1/zBarrierSetC1.hpp"
 #endif // COMPILER1
-
-#include "gc/z/zThreadLocalData.hpp"
-
-ZBarrierSetAssembler::ZBarrierSetAssembler() :
-    _load_barrier_slow_stub(),
-    _load_barrier_weak_slow_stub() {}
+#ifdef COMPILER2
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#endif // COMPILER2
 
 #ifdef PRODUCT
 #define BLOCK_COMMENT(str) /* nothing */
@@ -66,7 +67,7 @@
   assert_different_registers(rscratch1, rscratch2, src.base());
   assert_different_registers(rscratch1, rscratch2, dst);
 
-  RegSet savedRegs = RegSet::range(r0,r28) - RegSet::of(dst, rscratch1, rscratch2);
+  RegSet savedRegs = RegSet::range(r0, r28) - RegSet::of(dst, rscratch1, rscratch2);
 
   Label done;
 
@@ -206,7 +207,8 @@
 
   // The Address offset is too large to direct load - -784. Our range is +127, -128.
   __ mov(tmp, (long int)(in_bytes(ZThreadLocalData::address_bad_mask_offset()) -
-      in_bytes(JavaThread::jni_environment_offset())));
+              in_bytes(JavaThread::jni_environment_offset())));
+
   // Load address bad mask
   __ add(tmp, jni_env, tmp);
   __ ldr(tmp, Address(tmp));
@@ -294,12 +296,12 @@
   __ prologue("zgc_load_barrier stub", false);
 
   // We don't use push/pop_clobbered_registers() - we need to pull out the result from r0.
-  for (int i = 0; i < 32; i +=2) {
-    __ stpd(as_FloatRegister(i), as_FloatRegister(i+1), Address(__ pre(sp,-16)));
+  for (int i = 0; i < 32; i += 2) {
+    __ stpd(as_FloatRegister(i), as_FloatRegister(i + 1), Address(__ pre(sp,-16)));
   }
 
-  RegSet saveRegs = RegSet::range(r0,r28) - RegSet::of(r0);
-  __ push(saveRegs, sp);
+  const RegSet save_regs = RegSet::range(r1, r28);
+  __ push(save_regs, sp);
 
   // Setup arguments
   __ load_parameter(0, c_rarg0);
@@ -307,98 +309,161 @@
 
   __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), 2);
 
-  __ pop(saveRegs, sp);
+  __ pop(save_regs, sp);
 
-  for (int i = 30; i >0; i -=2) {
-      __ ldpd(as_FloatRegister(i), as_FloatRegister(i+1), Address(__ post(sp, 16)));
-    }
+  for (int i = 30; i >= 0; i -= 2) {
+    __ ldpd(as_FloatRegister(i), as_FloatRegister(i + 1), Address(__ post(sp, 16)));
+  }
 
   __ epilogue();
 }
 #endif // COMPILER1
 
+#ifdef COMPILER2
+
+OptoReg::Name ZBarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) {
+  if (!OptoReg::is_reg(opto_reg)) {
+    return OptoReg::Bad;
+  }
+
+  const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
+  if (vm_reg->is_FloatRegister()) {
+    return opto_reg & ~1;
+  }
+
+  return opto_reg;
+}
+
 #undef __
-#define __ cgen->assembler()->
+#define __ _masm->
+
+class ZSaveLiveRegisters {
+private:
+  MacroAssembler* const _masm;
+  RegSet                _gp_regs;
+  RegSet                _fp_regs;
+
+public:
+  void initialize(ZLoadBarrierStubC2* stub) {
+    // Create mask of live registers
+    RegMask live = stub->live();
 
-// Generates a register specific stub for calling
-// ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
-// ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
-//
-// The raddr register serves as both input and output for this stub. When the stub is
-// called the raddr register contains the object field address (oop*) where the bad oop
-// was loaded from, which caused the slow path to be taken. On return from the stub the
-// raddr register contains the good/healed oop returned from
-// ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
-// ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
-static address generate_load_barrier_stub(StubCodeGenerator* cgen, Register raddr, DecoratorSet decorators) {
-  // Don't generate stub for invalid registers
-  if (raddr == zr || raddr == r29 || raddr == r30) {
-    return NULL;
+    // Record registers that needs to be saved/restored
+    while (live.is_NotEmpty()) {
+      const OptoReg::Name opto_reg = live.find_first_elem();
+      live.Remove(opto_reg);
+      if (OptoReg::is_reg(opto_reg)) {
+        const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
+        if (vm_reg->is_Register()) {
+          _gp_regs += RegSet::of(vm_reg->as_Register());
+        } else if (vm_reg->is_FloatRegister()) {
+          _fp_regs += RegSet::of((Register)vm_reg->as_FloatRegister());
+        } else {
+          fatal("Unknown register type");
+        }
+      }
+    }
+
+    // Remove C-ABI SOE registers, scratch regs and _ref register that will be updated
+    _gp_regs -= RegSet::range(r19, r30) + RegSet::of(r8, r9, stub->ref());
+  }
+
+  ZSaveLiveRegisters(MacroAssembler* masm, ZLoadBarrierStubC2* stub) :
+      _masm(masm),
+      _gp_regs(),
+      _fp_regs() {
+
+    // Figure out what registers to save/restore
+    initialize(stub);
+
+    // Save registers
+    __ push(_gp_regs, sp);
+    __ push_fp(_fp_regs, sp);
   }
 
-  // Create stub name
-  char name[64];
-  const bool weak = (decorators & ON_WEAK_OOP_REF) != 0;
-  os::snprintf(name, sizeof(name), "zgc_load_barrier%s_stub_%s", weak ? "_weak" : "", raddr->name());
+  ~ZSaveLiveRegisters() {
+    // Restore registers
+    __ pop_fp(_fp_regs, sp);
+    __ pop(_gp_regs, sp);
+  }
+};
+
+#undef __
+#define __ _masm->
 
-  __ align(CodeEntryAlignment);
-  StubCodeMark mark(cgen, "StubRoutines", os::strdup(name, mtCode));
-  address start = __ pc();
+class ZSetupArguments {
+private:
+  MacroAssembler* const _masm;
+  const Register        _ref;
+  const Address         _ref_addr;
+
+public:
+  ZSetupArguments(MacroAssembler* masm, ZLoadBarrierStubC2* stub) :
+      _masm(masm),
+      _ref(stub->ref()),
+      _ref_addr(stub->ref_addr()) {
 
-  // Save live registers
-  RegSet savedRegs = RegSet::range(r0,r18) - RegSet::of(raddr);
-
-  __ enter();
-  __ push(savedRegs, sp);
-
-  // Setup arguments
-  if (raddr != c_rarg1) {
-    __ mov(c_rarg1, raddr);
+    // Setup arguments
+    if (_ref_addr.base() == noreg) {
+      // No self healing
+      if (_ref != c_rarg0) {
+        __ mov(c_rarg0, _ref);
+      }
+      __ mov(c_rarg1, 0);
+    } else {
+      // Self healing
+      if (_ref == c_rarg0) {
+        // _ref is already at correct place
+        __ lea(c_rarg1, _ref_addr);
+      } else if (_ref != c_rarg1) {
+        // _ref is in wrong place, but not in c_rarg1, so fix it first
+        __ lea(c_rarg1, _ref_addr);
+        __ mov(c_rarg0, _ref);
+      } else if (_ref_addr.base() != c_rarg0 && _ref_addr.index() != c_rarg0) {
+        assert(_ref == c_rarg1, "Mov ref first, vacating c_rarg0");
+        __ mov(c_rarg0, _ref);
+        __ lea(c_rarg1, _ref_addr);
+      } else {
+        assert(_ref == c_rarg1, "Need to vacate c_rarg1 and _ref_addr is using c_rarg0");
+        if (_ref_addr.base() == c_rarg0 || _ref_addr.index() == c_rarg0) {
+          __ mov(rscratch2, c_rarg1);
+          __ lea(c_rarg1, _ref_addr);
+          __ mov(c_rarg0, rscratch2);
+        } else {
+          ShouldNotReachHere();
+        }
+      }
+    }
   }
 
-  __ ldr(c_rarg0, Address(raddr));
+  ~ZSetupArguments() {
+    // Transfer result
+    if (_ref != r0) {
+      __ mov(_ref, r0);
+    }
+  }
+};
+
+#undef __
+#define __ masm->
 
-  // Call barrier function
-  __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), c_rarg0, c_rarg1);
+void ZBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, ZLoadBarrierStubC2* stub) const {
+  BLOCK_COMMENT("ZLoadBarrierStubC2");
+
+  // Stub entry
+  __ bind(*stub->entry());
 
-  // Move result returned in r0 to raddr, if needed
-  if (raddr != r0) {
-    __ mov(raddr, r0);
+  {
+    ZSaveLiveRegisters save_live_registers(masm, stub);
+    ZSetupArguments setup_arguments(masm, stub);
+    __ mov(rscratch1, stub->slow_path());
+    __ blr(rscratch1);
   }
 
-  __ pop(savedRegs, sp);
-  __ leave();
-  __ ret(lr);
-
-  return start;
+  // Stub exit
+  __ b(*stub->continuation());
 }
 
 #undef __
 
-static void barrier_stubs_init_inner(const char* label, const DecoratorSet decorators, address* stub) {
-  const int nregs = 28;              // Exclude FP, XZR, SP from calculation.
-  const int code_size = nregs * 254; // Rough estimate of code size
-
-  ResourceMark rm;
-
-  CodeBuffer buf(BufferBlob::create(label, code_size));
-  StubCodeGenerator cgen(&buf);
-
-  for (int i = 0; i < nregs; i++) {
-    const Register reg = as_Register(i);
-    stub[i] = generate_load_barrier_stub(&cgen, reg, decorators);
-  }
-}
-
-void ZBarrierSetAssembler::barrier_stubs_init() {
-  barrier_stubs_init_inner("zgc_load_barrier_stubs", ON_STRONG_OOP_REF, _load_barrier_slow_stub);
-  barrier_stubs_init_inner("zgc_load_barrier_weak_stubs", ON_WEAK_OOP_REF, _load_barrier_weak_slow_stub);
-}
-
-address ZBarrierSetAssembler::load_barrier_slow_stub(Register reg) {
-  return _load_barrier_slow_stub[reg->encoding()];
-}
-
-address ZBarrierSetAssembler::load_barrier_weak_slow_stub(Register reg) {
-  return _load_barrier_weak_slow_stub[reg->encoding()];
-}
+#endif // COMPILER2
--- a/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -24,6 +24,12 @@
 #ifndef CPU_AARCH64_GC_Z_ZBARRIERSETASSEMBLER_AARCH64_HPP
 #define CPU_AARCH64_GC_Z_ZBARRIERSETASSEMBLER_AARCH64_HPP
 
+#include "code/vmreg.hpp"
+#include "oops/accessDecorators.hpp"
+#ifdef COMPILER2
+#include "opto/optoreg.hpp"
+#endif // COMPILER2
+
 #ifdef COMPILER1
 class LIR_Assembler;
 class LIR_OprDesc;
@@ -32,14 +38,13 @@
 class ZLoadBarrierStubC1;
 #endif // COMPILER1
 
+#ifdef COMPILER2
+class Node;
+class ZLoadBarrierStubC2;
+#endif // COMPILER2
+
 class ZBarrierSetAssembler : public ZBarrierSetAssemblerBase {
-private:
-  address _load_barrier_slow_stub[RegisterImpl::number_of_registers];
-  address _load_barrier_weak_slow_stub[RegisterImpl::number_of_registers];
-
 public:
-  ZBarrierSetAssembler();
-
   virtual void load_at(MacroAssembler* masm,
                        DecoratorSet decorators,
                        BasicType type,
@@ -83,10 +88,13 @@
                                              DecoratorSet decorators) const;
 #endif // COMPILER1
 
-  virtual void barrier_stubs_init();
+#ifdef COMPILER2
+  OptoReg::Name refine_register(const Node* node,
+                                OptoReg::Name opto_reg);
 
-  address load_barrier_slow_stub(Register reg);
-  address load_barrier_weak_slow_stub(Register reg);
+  void generate_c2_load_barrier_stub(MacroAssembler* masm,
+                                     ZLoadBarrierStubC2* stub) const;
+#endif // COMPILER2
 };
 
 #endif // CPU_AARCH64_GC_Z_ZBARRIERSETASSEMBLER_AARCH64_HPP
--- a/src/hotspot/cpu/aarch64/gc/z/zGlobals_aarch64.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/gc/z/zGlobals_aarch64.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -40,7 +40,7 @@
 //  +--------------------------------+ 0x0000014000000000 (20TB)
 //  |         Remapped View          |
 //  +--------------------------------+ 0x0000010000000000 (16TB)
-//  |     (Reserved, but unused)     |
+//  .                                .
 //  +--------------------------------+ 0x00000c0000000000 (12TB)
 //  |         Marked1 View           |
 //  +--------------------------------+ 0x0000080000000000 (8TB)
@@ -75,7 +75,7 @@
 //  +--------------------------------+ 0x0000280000000000 (40TB)
 //  |         Remapped View          |
 //  +--------------------------------+ 0x0000200000000000 (32TB)
-//  |     (Reserved, but unused)     |
+//  .                                .
 //  +--------------------------------+ 0x0000180000000000 (24TB)
 //  |         Marked1 View           |
 //  +--------------------------------+ 0x0000100000000000 (16TB)
@@ -110,7 +110,7 @@
 //  +--------------------------------+ 0x0000500000000000 (80TB)
 //  |         Remapped View          |
 //  +--------------------------------+ 0x0000400000000000 (64TB)
-//  |     (Reserved, but unused)     |
+//  .                                .
 //  +--------------------------------+ 0x0000300000000000 (48TB)
 //  |         Marked1 View           |
 //  +--------------------------------+ 0x0000200000000000 (32TB)
--- a/src/hotspot/cpu/aarch64/gc/z/zGlobals_aarch64.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/gc/z/zGlobals_aarch64.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -36,7 +36,6 @@
 //  ------------------------------------------------------------------
 //
 const size_t ZPlatformGranuleSizeShift      = 21; // 2MB
-const size_t ZPlatformMaxHeapSizeShift      = 46; // 16TB
 const size_t ZPlatformNMethodDisarmedOffset = 4;
 const size_t ZPlatformCacheLineSize         = 64;
 
--- a/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/gc/z/z_aarch64.ad	Thu Oct 10 10:57:42 2019 -0400
@@ -24,155 +24,244 @@
 source_hpp %{
 
 #include "gc/z/c2/zBarrierSetC2.hpp"
+#include "gc/z/zThreadLocalData.hpp"
 
 %}
 
 source %{
 
-#include "gc/z/zBarrierSetAssembler.hpp"
-
-static void z_load_barrier_slow_reg(MacroAssembler& _masm, Register dst, 
-                                    Register base, int index, int scale, 
-                                    int disp, bool weak) {
-  const address stub = weak ? ZBarrierSet::assembler()->load_barrier_weak_slow_stub(dst)
-                            : ZBarrierSet::assembler()->load_barrier_slow_stub(dst);
+static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) {
+  ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, weak);
+  __ ldr(tmp, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+  __ andr(tmp, tmp, ref);
+  __ cbnz(tmp, *stub->entry());
+  __ bind(*stub->continuation());
+}
 
-  if (index == -1) {
-    if (disp != 0) {
-      __ lea(dst, Address(base, disp));
-    } else {
-       __ mov(dst, base);
-    }
-  } else {
-    Register index_reg = as_Register(index);
-    if (disp == 0) {
-      __ lea(dst, Address(base, index_reg, Address::lsl(scale)));
-    } else {
-      __ lea(dst, Address(base, disp));
-      __ lea(dst, Address(dst, index_reg, Address::lsl(scale)));
-    }
-  }
-
-  __ far_call(RuntimeAddress(stub));
+static void z_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) {
+  ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, false /* weak */);
+  __ b(*stub->entry());
+  __ bind(*stub->continuation());
 }
 
 %}
 
-//
-// Execute ZGC load barrier (strong) slow path
-//
-instruct loadBarrierSlowReg(iRegP dst, memory src, rFlagsReg cr,
-    vRegD_V0 v0, vRegD_V1 v1, vRegD_V2 v2, vRegD_V3 v3, vRegD_V4 v4,
-    vRegD_V5 v5, vRegD_V6 v6, vRegD_V7 v7, vRegD_V8 v8, vRegD_V9 v9,
-    vRegD_V10 v10, vRegD_V11 v11, vRegD_V12 v12, vRegD_V13 v13, vRegD_V14 v14,
-    vRegD_V15 v15, vRegD_V16 v16, vRegD_V17 v17, vRegD_V18 v18, vRegD_V19 v19,
-    vRegD_V20 v20, vRegD_V21 v21, vRegD_V22 v22, vRegD_V23 v23, vRegD_V24 v24,
-    vRegD_V25 v25, vRegD_V26 v26, vRegD_V27 v27, vRegD_V28 v28, vRegD_V29 v29,
-    vRegD_V30 v30, vRegD_V31 v31) %{
-  match(Set dst (LoadBarrierSlowReg src dst));
-  predicate(!n->as_LoadBarrierSlowReg()->is_weak());
+// Load Pointer
+instruct zLoadP(iRegPNoSp dst, memory mem, rFlagsReg cr)
+%{
+  match(Set dst (LoadP mem));
+  predicate(UseZGC && !needs_acquiring_load(n) && (n->as_Load()->barrier_data() == ZLoadBarrierStrong));
+  effect(TEMP dst, KILL cr);
 
-  effect(KILL cr,
-     KILL v0, KILL v1, KILL v2, KILL v3, KILL v4, KILL v5, KILL v6, KILL v7,
-     KILL v8, KILL v9, KILL v10, KILL v11, KILL v12, KILL v13, KILL v14,
-     KILL v15, KILL v16, KILL v17, KILL v18, KILL v19, KILL v20, KILL v21,
-     KILL v22, KILL v23, KILL v24, KILL v25, KILL v26, KILL v27, KILL v28,
-     KILL v29, KILL v30, KILL v31);
+  ins_cost(4 * INSN_COST);
 
-  format %{ "lea $dst, $src\n\t"
-            "call #ZLoadBarrierSlowPath" %}
+  format %{ "ldr  $dst, $mem" %}
 
   ins_encode %{
-    z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$base$$Register,
-                            $src$$index, $src$$scale, $src$$disp, false);
+    const Address ref_addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
+    __ ldr($dst$$Register, ref_addr);
+    if (barrier_data() != ZLoadBarrierElided) {
+      z_load_barrier(_masm, this, ref_addr, $dst$$Register, rscratch2 /* tmp */, false /* weak */);
+    }
   %}
-  ins_pipe(pipe_slow);
+
+  ins_pipe(iload_reg_mem);
 %}
 
-//
-// Execute ZGC load barrier (weak) slow path
-//
-instruct loadBarrierWeakSlowReg(iRegP dst, memory src, rFlagsReg cr,
-    vRegD_V0 v0, vRegD_V1 v1, vRegD_V2 v2, vRegD_V3 v3, vRegD_V4 v4,
-    vRegD_V5 v5, vRegD_V6 v6, vRegD_V7 v7, vRegD_V8 v8, vRegD_V9 v9,
-    vRegD_V10 v10, vRegD_V11 v11, vRegD_V12 v12, vRegD_V13 v13, vRegD_V14 v14,
-    vRegD_V15 v15, vRegD_V16 v16, vRegD_V17 v17, vRegD_V18 v18, vRegD_V19 v19,
-    vRegD_V20 v20, vRegD_V21 v21, vRegD_V22 v22, vRegD_V23 v23, vRegD_V24 v24,
-    vRegD_V25 v25, vRegD_V26 v26, vRegD_V27 v27, vRegD_V28 v28, vRegD_V29 v29,
-    vRegD_V30 v30, vRegD_V31 v31) %{
-  match(Set dst (LoadBarrierSlowReg src dst));
-  predicate(n->as_LoadBarrierSlowReg()->is_weak());
+// Load Weak Pointer
+instruct zLoadWeakP(iRegPNoSp dst, memory mem, rFlagsReg cr)
+%{
+  match(Set dst (LoadP mem));
+  predicate(UseZGC && !needs_acquiring_load(n) && (n->as_Load()->barrier_data() == ZLoadBarrierWeak));
+  effect(TEMP dst, KILL cr);
 
-  effect(KILL cr,
-     KILL v0, KILL v1, KILL v2, KILL v3, KILL v4, KILL v5, KILL v6, KILL v7,
-     KILL v8, KILL v9, KILL v10, KILL v11, KILL v12, KILL v13, KILL v14,
-     KILL v15, KILL v16, KILL v17, KILL v18, KILL v19, KILL v20, KILL v21,
-     KILL v22, KILL v23, KILL v24, KILL v25, KILL v26, KILL v27, KILL v28,
-     KILL v29, KILL v30, KILL v31);
+  ins_cost(4 * INSN_COST);
 
-  format %{ "lea $dst, $src\n\t"
-            "call #ZLoadBarrierSlowPath" %}
+  format %{ "ldr  $dst, $mem" %}
 
   ins_encode %{
-    z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$base$$Register,
-                            $src$$index, $src$$scale, $src$$disp, true);
+    const Address ref_addr = mem2address($mem->opcode(), as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp);
+    __ ldr($dst$$Register, ref_addr);
+    z_load_barrier(_masm, this, ref_addr, $dst$$Register, rscratch2 /* tmp */, true /* weak */);
   %}
-  ins_pipe(pipe_slow);
+
+  ins_pipe(iload_reg_mem);
 %}
 
+// Load Pointer Volatile
+instruct zLoadPVolatile(iRegPNoSp dst, indirect mem /* sync_memory */, rFlagsReg cr)
+%{
+  match(Set dst (LoadP mem));
+  predicate(UseZGC && needs_acquiring_load(n) && n->as_Load()->barrier_data() == ZLoadBarrierStrong);
+  effect(TEMP dst, KILL cr);
 
-// Specialized versions of compareAndExchangeP that adds a keepalive that is consumed
-// but doesn't affect output.
+  ins_cost(VOLATILE_REF_COST);
 
-instruct z_compareAndExchangeP(iRegPNoSp res, indirect mem,
-                               iRegP oldval, iRegP newval, iRegP keepalive,
-                               rFlagsReg cr) %{
-  match(Set res (ZCompareAndExchangeP (Binary mem keepalive) (Binary oldval newval)));
-  ins_cost(2 * VOLATILE_REF_COST);
-  effect(TEMP_DEF res, KILL cr);
-  format %{
-    "cmpxchg $res = $mem, $oldval, $newval\t# (ptr, weak) if $mem == $oldval then $mem <-- $newval"
+  format %{ "ldar  $dst, $mem\t" %}
+
+  ins_encode %{
+    __ ldar($dst$$Register, $mem$$Register);
+    if (barrier_data() != ZLoadBarrierElided) {
+      z_load_barrier(_masm, this, Address($mem$$Register), $dst$$Register, rscratch2 /* tmp */, false /* weak */);
+    }
   %}
-  ins_encode %{
-    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register,
-               Assembler::xword, /*acquire*/ false, /*release*/ true,
-               /*weak*/ false, $res$$Register);
-  %}
-  ins_pipe(pipe_slow);
+
+  ins_pipe(pipe_serial);
 %}
 
-instruct z_compareAndSwapP(iRegINoSp res,
-                           indirect mem,
-                           iRegP oldval, iRegP newval, iRegP keepalive,
-                            rFlagsReg cr) %{
-
-  match(Set res (ZCompareAndSwapP (Binary mem keepalive) (Binary oldval newval)));
-  match(Set res (ZWeakCompareAndSwapP (Binary mem keepalive) (Binary oldval newval)));
+instruct zCompareAndSwapP(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+  match(Set res (CompareAndSwapP mem (Binary oldval newval)));
+  match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
+  predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+  effect(KILL cr, TEMP_DEF res);
 
   ins_cost(2 * VOLATILE_REF_COST);
 
-  effect(KILL cr);
+  format %{ "cmpxchg $mem, $oldval, $newval\n\t"
+            "cset    $res, EQ" %}
 
- format %{
-    "cmpxchg $mem, $oldval, $newval\t# (ptr) if $mem == $oldval then $mem <-- $newval"
-    "cset $res, EQ\t# $res <-- (EQ ? 1 : 0)"
- %}
-
- ins_encode(aarch64_enc_cmpxchg(mem, oldval, newval),
-            aarch64_enc_cset_eq(res));
+  ins_encode %{
+    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+               false /* acquire */, true /* release */, false /* weak */, rscratch2);
+    __ cset($res$$Register, Assembler::EQ);
+    if (barrier_data() != ZLoadBarrierElided) {
+      Label good;
+      __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+      __ andr(rscratch1, rscratch1, rscratch2);
+      __ cbz(rscratch1, good);
+      z_load_barrier_slow_path(_masm, this, Address($mem$$Register), rscratch2 /* ref */, rscratch1 /* tmp */);
+      __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+                 false /* acquire */, true /* release */, false /* weak */, rscratch2);
+      __ cset($res$$Register, Assembler::EQ);
+      __ bind(good);
+    }
+  %}
 
   ins_pipe(pipe_slow);
 %}
 
+instruct zCompareAndSwapPAcq(iRegINoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+  match(Set res (CompareAndSwapP mem (Binary oldval newval)));
+  match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
+  predicate(UseZGC && needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong));
+  effect(KILL cr, TEMP_DEF res);
 
-instruct z_get_and_setP(indirect mem, iRegP newv, iRegPNoSp prev,
-                        iRegP keepalive) %{
-  match(Set prev (ZGetAndSetP mem (Binary newv keepalive)));
+  ins_cost(2 * VOLATILE_REF_COST);
+
+ format %{ "cmpxchg $mem, $oldval, $newval\n\t"
+           "cset    $res, EQ" %}
+
+  ins_encode %{
+    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+               true /* acquire */, true /* release */, false /* weak */, rscratch2);
+    __ cset($res$$Register, Assembler::EQ);
+    if (barrier_data() != ZLoadBarrierElided) {
+      Label good;
+      __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+      __ andr(rscratch1, rscratch1, rscratch2);
+      __ cbz(rscratch1, good);
+      z_load_barrier_slow_path(_masm, this, Address($mem$$Register), rscratch2 /* ref */, rscratch1 /* tmp */ );
+      __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+                 true /* acquire */, true /* release */, false /* weak */, rscratch2);
+      __ cset($res$$Register, Assembler::EQ);
+      __ bind(good);
+    }
+  %}
+
+  ins_pipe(pipe_slow);
+%}
+
+instruct zCompareAndExchangeP(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+  match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
+  predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+  effect(TEMP_DEF res, KILL cr);
 
   ins_cost(2 * VOLATILE_REF_COST);
-  format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
+
+  format %{ "cmpxchg $res = $mem, $oldval, $newval" %}
+
+  ins_encode %{
+    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+               false /* acquire */, true /* release */, false /* weak */, $res$$Register);
+    if (barrier_data() != ZLoadBarrierElided) {
+      Label good;
+      __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+      __ andr(rscratch1, rscratch1, $res$$Register);
+      __ cbz(rscratch1, good);
+      z_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, rscratch1 /* tmp */);
+      __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+                 false /* acquire */, true /* release */, false /* weak */, $res$$Register);
+      __ bind(good);
+    }
+  %}
+
+  ins_pipe(pipe_slow);
+%}
+
+instruct zCompareAndExchangePAcq(iRegPNoSp res, indirect mem, iRegP oldval, iRegP newval, rFlagsReg cr) %{
+  match(Set res (CompareAndExchangeP mem (Binary oldval newval)));
+  predicate(UseZGC && needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+  effect(TEMP_DEF res, KILL cr);
+
+  ins_cost(2 * VOLATILE_REF_COST);
+
+  format %{ "cmpxchg $res = $mem, $oldval, $newval" %}
+
   ins_encode %{
-    __ atomic_xchg($prev$$Register, $newv$$Register, as_Register($mem$$base));
+    guarantee($mem$$index == -1 && $mem$$disp == 0, "impossible encoding");
+    __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+               true /* acquire */, true /* release */, false /* weak */, $res$$Register);
+    if (barrier_data() != ZLoadBarrierElided) {
+      Label good;
+      __ ldr(rscratch1, Address(rthread, ZThreadLocalData::address_bad_mask_offset()));
+      __ andr(rscratch1, rscratch1, $res$$Register);
+      __ cbz(rscratch1, good);
+      z_load_barrier_slow_path(_masm, this, Address($mem$$Register), $res$$Register /* ref */, rscratch1 /* tmp */);
+      __ cmpxchg($mem$$Register, $oldval$$Register, $newval$$Register, Assembler::xword,
+                 true /* acquire */, true /* release */, false /* weak */, $res$$Register);
+      __ bind(good);
+    }
+  %}
+
+  ins_pipe(pipe_slow);
+%}
+
+instruct zGetAndSetP(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
+  match(Set prev (GetAndSetP mem newv));
+  predicate(UseZGC && !needs_acquiring_load_exclusive(n) && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+  effect(TEMP_DEF prev, KILL cr);
+
+  ins_cost(2 * VOLATILE_REF_COST);
+
+  format %{ "atomic_xchg  $prev, $newv, [$mem]" %}
+
+  ins_encode %{
+    __ atomic_xchg($prev$$Register, $newv$$Register, $mem$$Register);
+    if (barrier_data() != ZLoadBarrierElided) {
+      z_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, rscratch2 /* tmp */, false /* weak */);
+    }
+  %}
+
+  ins_pipe(pipe_serial);
+%}
+
+instruct zGetAndSetPAcq(indirect mem, iRegP newv, iRegPNoSp prev, rFlagsReg cr) %{
+  match(Set prev (GetAndSetP mem newv));
+  predicate(UseZGC && needs_acquiring_load_exclusive(n) && (n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong));
+  effect(TEMP_DEF prev, KILL cr);
+
+  ins_cost(VOLATILE_REF_COST);
+
+  format %{ "atomic_xchg_acq  $prev, $newv, [$mem]" %}
+
+  ins_encode %{
+    __ atomic_xchgal($prev$$Register, $newv$$Register, $mem$$Register);
+    if (barrier_data() != ZLoadBarrierElided) {
+      z_load_barrier(_masm, this, Address(noreg, 0), $prev$$Register, rscratch2 /* tmp */, false /* weak */);
+    }
   %}
   ins_pipe(pipe_serial);
 %}
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -2132,6 +2132,65 @@
 
   return count;
 }
+
+// Push lots of registers in the bit set supplied.  Don't push sp.
+// Return the number of words pushed
+int MacroAssembler::push_fp(unsigned int bitset, Register stack) {
+  int words_pushed = 0;
+
+  // Scan bitset to accumulate register pairs
+  unsigned char regs[32];
+  int count = 0;
+  for (int reg = 0; reg <= 31; reg++) {
+    if (1 & bitset)
+      regs[count++] = reg;
+    bitset >>= 1;
+  }
+  regs[count++] = zr->encoding_nocheck();
+  count &= ~1;  // Only push an even number of regs
+
+  // Always pushing full 128 bit registers.
+  if (count) {
+    stpq(as_FloatRegister(regs[0]), as_FloatRegister(regs[1]), Address(pre(stack, -count * wordSize * 2)));
+    words_pushed += 2;
+  }
+  for (int i = 2; i < count; i += 2) {
+    stpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2));
+    words_pushed += 2;
+  }
+
+  assert(words_pushed == count, "oops, pushed != count");
+  return count;
+}
+
+int MacroAssembler::pop_fp(unsigned int bitset, Register stack) {
+  int words_pushed = 0;
+
+  // Scan bitset to accumulate register pairs
+  unsigned char regs[32];
+  int count = 0;
+  for (int reg = 0; reg <= 31; reg++) {
+    if (1 & bitset)
+      regs[count++] = reg;
+    bitset >>= 1;
+  }
+  regs[count++] = zr->encoding_nocheck();
+  count &= ~1;
+
+  for (int i = 2; i < count; i += 2) {
+    ldpq(as_FloatRegister(regs[i]), as_FloatRegister(regs[i+1]), Address(stack, i * wordSize * 2));
+    words_pushed += 2;
+  }
+  if (count) {
+    ldpq(as_FloatRegister(regs[0]), as_FloatRegister(regs[1]), Address(post(stack, count * wordSize * 2)));
+    words_pushed += 2;
+  }
+
+  assert(words_pushed == count, "oops, pushed != count");
+
+  return count;
+}
+
 #ifdef ASSERT
 void MacroAssembler::verify_heapbase(const char* msg) {
 #if 0
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -442,12 +442,18 @@
   int push(unsigned int bitset, Register stack);
   int pop(unsigned int bitset, Register stack);
 
+  int push_fp(unsigned int bitset, Register stack);
+  int pop_fp(unsigned int bitset, Register stack);
+
   void mov(Register dst, Address a);
 
 public:
   void push(RegSet regs, Register stack) { if (regs.bits()) push(regs.bits(), stack); }
   void pop(RegSet regs, Register stack) { if (regs.bits()) pop(regs.bits(), stack); }
 
+  void push_fp(RegSet regs, Register stack) { if (regs.bits()) push_fp(regs.bits(), stack); }
+  void pop_fp(RegSet regs, Register stack) { if (regs.bits()) pop_fp(regs.bits(), stack); }
+
   // Push and pop everything that might be clobbered by a native
   // runtime call except rscratch1 and rscratch2.  (They are always
   // scratch, so we don't have to protect them.)  Only save the lower
--- a/src/hotspot/cpu/aarch64/register_aarch64.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/register_aarch64.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -230,6 +230,11 @@
     return *this;
   }
 
+  RegSet &operator-=(const RegSet aSet) {
+    *this = *this - aSet;
+    return *this;
+  }
+
   static RegSet of(Register r1) {
     return RegSet(r1);
   }
--- a/src/hotspot/cpu/arm/abstractInterpreter_arm.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/arm/abstractInterpreter_arm.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -27,6 +27,7 @@
 #include "interpreter/bytecode.hpp"
 #include "interpreter/interpreter.hpp"
 #include "oops/constMethod.hpp"
+#include "oops/klass.inline.hpp"
 #include "oops/method.hpp"
 #include "prims/methodHandles.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/hotspot/cpu/arm/compiledIC_arm.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/arm/compiledIC_arm.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -115,16 +115,7 @@
   // Creation also verifies the object.
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
-
-#ifdef ASSERT
-  // read the value once
-  volatile intptr_t data = method_holder->data();
-  volatile address destination = jump->jump_destination();
-  assert(data == 0 || data == (intptr_t)callee(),
-         "a) MT-unsafe modification of inline cache");
-  assert(destination == (address)-1 || destination == entry,
-         "b) MT-unsafe modification of inline cache");
-#endif
+  verify_mt_safe(callee, entry, method_holder, jump);
 
   // Update stub.
   method_holder->set_data((intptr_t)callee());
--- a/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/ppc/abstractInterpreter_ppc.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -26,6 +26,7 @@
 #include "precompiled.hpp"
 #include "interpreter/interpreter.hpp"
 #include "oops/constMethod.hpp"
+#include "oops/klass.inline.hpp"
 #include "oops/method.hpp"
 #include "runtime/frame.inline.hpp"
 #include "utilities/debug.hpp"
--- a/src/hotspot/cpu/ppc/compiledIC_ppc.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/ppc/compiledIC_ppc.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -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.
  * Copyright (c) 2012, 2015 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -178,15 +178,7 @@
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + IC_pos_in_java_to_interp_stub);
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
 
-#ifdef ASSERT
-  // read the value once
-  volatile intptr_t data = method_holder->data();
-  volatile address destination = jump->jump_destination();
-  assert(data == 0 || data == (intptr_t)callee(),
-         "a) MT-unsafe modification of inline cache");
-  assert(destination == (address)-1 || destination == entry,
-         "b) MT-unsafe modification of inline cache");
-#endif
+  verify_mt_safe(callee, entry, method_holder, jump);
 
   // Update stub.
   method_holder->set_data((intptr_t)callee());
--- a/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/s390/abstractInterpreter_s390.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -26,6 +26,7 @@
 #include "precompiled.hpp"
 #include "interpreter/interpreter.hpp"
 #include "oops/constMethod.hpp"
+#include "oops/klass.inline.hpp"
 #include "oops/method.hpp"
 #include "runtime/frame.inline.hpp"
 #include "utilities/debug.hpp"
--- a/src/hotspot/cpu/s390/compiledIC_s390.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/s390/compiledIC_s390.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -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.
  * Copyright (c) 2016 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -104,19 +104,7 @@
   // Creation also verifies the object.
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub + NativeCall::get_IC_pos_in_java_to_interp_stub());
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
-
-#ifdef ASSERT
-  // A generated lambda form might be deleted from the Lambdaform
-  // cache in MethodTypeForm.  If a jit compiled lambdaform method
-  // becomes not entrant and the cache access returns null, the new
-  // resolve will lead to a new generated LambdaForm.
-  volatile intptr_t data = method_holder->data();
-  volatile address destination = jump->jump_destination();
-  assert(data == 0 || data == (intptr_t)callee() || callee->is_compiled_lambda_form(),
-         "a) MT-unsafe modification of inline cache");
-  assert(destination == (address)-1 || destination == entry,
-         "b) MT-unsafe modification of inline cache");
-#endif
+  verify_mt_safe(callee, entry, method_holder, jump);
 
   // Update stub.
   method_holder->set_data((intptr_t)callee(), relocInfo::metadata_type);
--- a/src/hotspot/cpu/sparc/abstractInterpreter_sparc.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/sparc/abstractInterpreter_sparc.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "interpreter/interpreter.hpp"
 #include "oops/constMethod.hpp"
+#include "oops/klass.inline.hpp"
 #include "oops/method.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/frame.inline.hpp"
--- a/src/hotspot/cpu/sparc/compiledIC_sparc.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/sparc/compiledIC_sparc.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -104,16 +104,7 @@
   // Creation also verifies the object.
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
-
-#ifdef ASSERT
-  // read the value once
-  volatile intptr_t data = method_holder->data();
-  volatile address destination = jump->jump_destination();
-  assert(data == 0 || data == (intptr_t)callee(),
-         "a) MT-unsafe modification of inline cache");
-  assert(destination == (address)-1 || destination == entry,
-         "b) MT-unsafe modification of inline cache");
-#endif
+  verify_mt_safe(callee, entry, method_holder, jump);
 
   // Update stub.
   method_holder->set_data((intptr_t)callee());
--- a/src/hotspot/cpu/x86/abstractInterpreter_x86.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/abstractInterpreter_x86.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "ci/ciMethod.hpp"
 #include "interpreter/interpreter.hpp"
+#include "oops/klass.inline.hpp"
 #include "runtime/frame.inline.hpp"
 
 
--- a/src/hotspot/cpu/x86/compiledIC_x86.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/compiledIC_x86.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -157,16 +157,7 @@
   // Creation also verifies the object.
   NativeMovConstReg* method_holder = nativeMovConstReg_at(stub);
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
-
-#ifdef ASSERT
-  Method* old_method = reinterpret_cast<Method*>(method_holder->data());
-  address destination = jump->jump_destination();
-  assert(old_method == NULL || old_method == callee() ||
-         !old_method->method_holder()->is_loader_alive(),
-         "a) MT-unsafe modification of inline cache");
-  assert(destination == (address)-1 || destination == entry,
-         "b) MT-unsafe modification of inline cache");
-#endif
+  verify_mt_safe(callee, entry, method_holder, jump);
 
   // Update stub.
   method_holder->set_data((intptr_t)callee());
--- a/src/hotspot/cpu/x86/gc/z/zArguments_x86.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/gc/z/zArguments_x86.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -23,20 +23,7 @@
 
 #include "precompiled.hpp"
 #include "gc/z/zArguments.hpp"
-#include "runtime/globals.hpp"
-#include "runtime/globals_extension.hpp"
-#include "utilities/debug.hpp"
 
 void ZArguments::initialize_platform() {
-#ifdef COMPILER2
-  // The C2 barrier slow path expects vector registers to be least
-  // 16 bytes wide, which is the minimum width available on all
-  // x86-64 systems. However, the user could have speficied a lower
-  // number on the command-line, in which case we print a warning
-  // and raise it to 16.
-  if (MaxVectorSize < 16) {
-    warning("ZGC requires MaxVectorSize to be at least 16");
-    FLAG_SET_DEFAULT(MaxVectorSize, 16);
-  }
-#endif
+  // Does nothing
 }
--- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -24,22 +24,22 @@
 #include "precompiled.hpp"
 #include "asm/macroAssembler.inline.hpp"
 #include "code/codeBlob.hpp"
+#include "code/vmreg.inline.hpp"
 #include "gc/z/zBarrier.inline.hpp"
 #include "gc/z/zBarrierSet.hpp"
 #include "gc/z/zBarrierSetAssembler.hpp"
 #include "gc/z/zBarrierSetRuntime.hpp"
 #include "memory/resourceArea.hpp"
-#include "runtime/stubCodeGenerator.hpp"
+#include "runtime/sharedRuntime.hpp"
 #include "utilities/macros.hpp"
 #ifdef COMPILER1
 #include "c1/c1_LIRAssembler.hpp"
 #include "c1/c1_MacroAssembler.hpp"
 #include "gc/z/c1/zBarrierSetC1.hpp"
 #endif // COMPILER1
-
-ZBarrierSetAssembler::ZBarrierSetAssembler() :
-    _load_barrier_slow_stub(),
-    _load_barrier_weak_slow_stub() {}
+#ifdef COMPILER2
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#endif // COMPILER2
 
 #ifdef PRODUCT
 #define BLOCK_COMMENT(str) /* nothing */
@@ -344,137 +344,327 @@
 
 #endif // COMPILER1
 
+#ifdef COMPILER2
+
+OptoReg::Name ZBarrierSetAssembler::refine_register(const Node* node, OptoReg::Name opto_reg) {
+  if (!OptoReg::is_reg(opto_reg)) {
+    return OptoReg::Bad;
+  }
+
+  const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
+  if (vm_reg->is_XMMRegister()) {
+    opto_reg &= ~15;
+    switch (node->ideal_reg()) {
+      case Op_VecX:
+        opto_reg |= 2;
+        break;
+      case Op_VecY:
+        opto_reg |= 4;
+        break;
+      case Op_VecZ:
+        opto_reg |= 8;
+        break;
+      default:
+        opto_reg |= 1;
+        break;
+    }
+  }
+
+  return opto_reg;
+}
+
+// We use the vec_spill_helper from the x86.ad file to avoid reinventing this wheel
+extern int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
+                            int stack_offset, int reg, uint ireg, outputStream* st);
+
 #undef __
-#define __ cgen->assembler()->
+#define __ _masm->
+
+class ZSaveLiveRegisters {
+private:
+  struct XMMRegisterData {
+    XMMRegister _reg;
+    int         _size;
+
+    // Used by GrowableArray::find()
+    bool operator == (const XMMRegisterData& other) {
+      return _reg == other._reg;
+    }
+  };
+
+  MacroAssembler* const          _masm;
+  GrowableArray<Register>        _gp_registers;
+  GrowableArray<XMMRegisterData> _xmm_registers;
+  int                            _spill_size;
+  int                            _spill_offset;
 
-// Generates a register specific stub for calling
-// ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
-// ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
-//
-// The raddr register serves as both input and output for this stub. When the stub is
-// called the raddr register contains the object field address (oop*) where the bad oop
-// was loaded from, which caused the slow path to be taken. On return from the stub the
-// raddr register contains the good/healed oop returned from
-// ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded() or
-// ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded().
-static address generate_load_barrier_stub(StubCodeGenerator* cgen, Register raddr, DecoratorSet decorators) {
-  // Don't generate stub for invalid registers
-  if (raddr == rsp || raddr == r15) {
-    return NULL;
+  static int xmm_compare_register_size(XMMRegisterData* left, XMMRegisterData* right) {
+    if (left->_size == right->_size) {
+      return 0;
+    }
+
+    return (left->_size < right->_size) ? -1 : 1;
+  }
+
+  static int xmm_slot_size(OptoReg::Name opto_reg) {
+    // The low order 4 bytes denote what size of the XMM register is live
+    return (opto_reg & 15) << 3;
+  }
+
+  static uint xmm_ideal_reg_for_size(int reg_size) {
+    switch (reg_size) {
+    case 8:
+      return Op_VecD;
+    case 16:
+      return Op_VecX;
+    case 32:
+      return Op_VecY;
+    case 64:
+      return Op_VecZ;
+    default:
+      fatal("Invalid register size %d", reg_size);
+      return 0;
+    }
+  }
+
+  bool xmm_needs_vzeroupper() const {
+    return _xmm_registers.is_nonempty() && _xmm_registers.at(0)._size > 16;
+  }
+
+  void xmm_register_save(const XMMRegisterData& reg_data) {
+    const OptoReg::Name opto_reg = OptoReg::as_OptoReg(reg_data._reg->as_VMReg());
+    const uint ideal_reg = xmm_ideal_reg_for_size(reg_data._size);
+    _spill_offset -= reg_data._size;
+    vec_spill_helper(__ code(), false /* do_size */, false /* is_load */, _spill_offset, opto_reg, ideal_reg, tty);
+  }
+
+  void xmm_register_restore(const XMMRegisterData& reg_data) {
+    const OptoReg::Name opto_reg = OptoReg::as_OptoReg(reg_data._reg->as_VMReg());
+    const uint ideal_reg = xmm_ideal_reg_for_size(reg_data._size);
+    vec_spill_helper(__ code(), false /* do_size */, true /* is_load */, _spill_offset, opto_reg, ideal_reg, tty);
+    _spill_offset += reg_data._size;
+  }
+
+  void gp_register_save(Register reg) {
+    _spill_offset -= 8;
+    __ movq(Address(rsp, _spill_offset), reg);
+  }
+
+  void gp_register_restore(Register reg) {
+    __ movq(reg, Address(rsp, _spill_offset));
+    _spill_offset += 8;
   }
 
-  // Create stub name
-  char name[64];
-  const bool weak = (decorators & ON_WEAK_OOP_REF) != 0;
-  os::snprintf(name, sizeof(name), "zgc_load_barrier%s_stub_%s", weak ? "_weak" : "", raddr->name());
+  void initialize(ZLoadBarrierStubC2* stub) {
+    // Create mask of caller saved registers that need to
+    // be saved/restored if live
+    RegMask caller_saved;
+    caller_saved.Insert(OptoReg::as_OptoReg(rax->as_VMReg()));
+    caller_saved.Insert(OptoReg::as_OptoReg(rcx->as_VMReg()));
+    caller_saved.Insert(OptoReg::as_OptoReg(rdx->as_VMReg()));
+    caller_saved.Insert(OptoReg::as_OptoReg(rsi->as_VMReg()));
+    caller_saved.Insert(OptoReg::as_OptoReg(rdi->as_VMReg()));
+    caller_saved.Insert(OptoReg::as_OptoReg(r8->as_VMReg()));
+    caller_saved.Insert(OptoReg::as_OptoReg(r9->as_VMReg()));
+    caller_saved.Insert(OptoReg::as_OptoReg(r10->as_VMReg()));
+    caller_saved.Insert(OptoReg::as_OptoReg(r11->as_VMReg()));
+    caller_saved.Remove(OptoReg::as_OptoReg(stub->ref()->as_VMReg()));
 
-  __ align(CodeEntryAlignment);
-  StubCodeMark mark(cgen, "StubRoutines", os::strdup(name, mtCode));
-  address start = __ pc();
+    // Create mask of live registers
+    RegMask live = stub->live();
+    if (stub->tmp() != noreg) {
+      live.Insert(OptoReg::as_OptoReg(stub->tmp()->as_VMReg()));
+    }
+
+    int gp_spill_size = 0;
+    int xmm_spill_size = 0;
+
+    // Record registers that needs to be saved/restored
+    while (live.is_NotEmpty()) {
+      const OptoReg::Name opto_reg = live.find_first_elem();
+      const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
+
+      live.Remove(opto_reg);
 
-  // Save live registers
-  if (raddr != rax) {
-    __ push(rax);
-  }
-  if (raddr != rcx) {
-    __ push(rcx);
-  }
-  if (raddr != rdx) {
-    __ push(rdx);
-  }
-  if (raddr != rsi) {
-    __ push(rsi);
-  }
-  if (raddr != rdi) {
-    __ push(rdi);
-  }
-  if (raddr != r8) {
-    __ push(r8);
-  }
-  if (raddr != r9) {
-    __ push(r9);
-  }
-  if (raddr != r10) {
-    __ push(r10);
-  }
-  if (raddr != r11) {
-    __ push(r11);
+      if (vm_reg->is_Register()) {
+        if (caller_saved.Member(opto_reg)) {
+          _gp_registers.append(vm_reg->as_Register());
+          gp_spill_size += 8;
+        }
+      } else if (vm_reg->is_XMMRegister()) {
+        // We encode in the low order 4 bits of the opto_reg, how large part of the register is live
+        const VMReg vm_reg_base = OptoReg::as_VMReg(opto_reg & ~15);
+        const int reg_size = xmm_slot_size(opto_reg);
+        const XMMRegisterData reg_data = { vm_reg_base->as_XMMRegister(), reg_size };
+        const int reg_index = _xmm_registers.find(reg_data);
+        if (reg_index == -1) {
+          // Not previously appended
+          _xmm_registers.append(reg_data);
+          xmm_spill_size += reg_size;
+        } else {
+          // Previously appended, update size
+          const int reg_size_prev = _xmm_registers.at(reg_index)._size;
+          if (reg_size > reg_size_prev) {
+            _xmm_registers.at_put(reg_index, reg_data);
+            xmm_spill_size += reg_size - reg_size_prev;
+          }
+        }
+      } else {
+        fatal("Unexpected register type");
+      }
+    }
+
+    // Sort by size, largest first
+    _xmm_registers.sort(xmm_compare_register_size);
+
+    // Stack pointer must be 16 bytes aligned for the call
+    _spill_offset = _spill_size = align_up(xmm_spill_size + gp_spill_size, 16);
   }
 
-  // Setup arguments
-  if (raddr != c_rarg1) {
-    __ movq(c_rarg1, raddr);
-  }
-  __ movq(c_rarg0, Address(raddr, 0));
+public:
+  ZSaveLiveRegisters(MacroAssembler* masm, ZLoadBarrierStubC2* stub) :
+      _masm(masm),
+      _gp_registers(),
+      _xmm_registers(),
+      _spill_size(0),
+      _spill_offset(0) {
 
-  // Call barrier function
-  __ call_VM_leaf(ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators), c_rarg0, c_rarg1);
+    //
+    // Stack layout after registers have been spilled:
+    //
+    // | ...            | original rsp, 16 bytes aligned
+    // ------------------
+    // | zmm0 high      |
+    // | ...            |
+    // | zmm0 low       | 16 bytes aligned
+    // | ...            |
+    // | ymm1 high      |
+    // | ...            |
+    // | ymm1 low       | 16 bytes aligned
+    // | ...            |
+    // | xmmN high      |
+    // | ...            |
+    // | xmmN low       | 8 bytes aligned
+    // | reg0           | 8 bytes aligned
+    // | reg1           |
+    // | ...            |
+    // | regN           | new rsp, if 16 bytes aligned
+    // | <padding>      | else new rsp, 16 bytes aligned
+    // ------------------
+    //
 
-  // Move result returned in rax to raddr, if needed
-  if (raddr != rax) {
-    __ movq(raddr, rax);
+    // Figure out what registers to save/restore
+    initialize(stub);
+
+    // Allocate stack space
+    if (_spill_size > 0) {
+      __ subptr(rsp, _spill_size);
+    }
+
+    // Save XMM/YMM/ZMM registers
+    for (int i = 0; i < _xmm_registers.length(); i++) {
+      xmm_register_save(_xmm_registers.at(i));
+    }
+
+    if (xmm_needs_vzeroupper()) {
+      __ vzeroupper();
+    }
+
+    // Save general purpose registers
+    for (int i = 0; i < _gp_registers.length(); i++) {
+      gp_register_save(_gp_registers.at(i));
+    }
   }
 
-  // Restore saved registers
-  if (raddr != r11) {
-    __ pop(r11);
-  }
-  if (raddr != r10) {
-    __ pop(r10);
-  }
-  if (raddr != r9) {
-    __ pop(r9);
-  }
-  if (raddr != r8) {
-    __ pop(r8);
+  ~ZSaveLiveRegisters() {
+    // Restore general purpose registers
+    for (int i = _gp_registers.length() - 1; i >= 0; i--) {
+      gp_register_restore(_gp_registers.at(i));
+    }
+
+    __ vzeroupper();
+
+    // Restore XMM/YMM/ZMM registers
+    for (int i = _xmm_registers.length() - 1; i >= 0; i--) {
+      xmm_register_restore(_xmm_registers.at(i));
+    }
+
+    // Free stack space
+    if (_spill_size > 0) {
+      __ addptr(rsp, _spill_size);
+    }
   }
-  if (raddr != rdi) {
-    __ pop(rdi);
-  }
-  if (raddr != rsi) {
-    __ pop(rsi);
-  }
-  if (raddr != rdx) {
-    __ pop(rdx);
-  }
-  if (raddr != rcx) {
-    __ pop(rcx);
-  }
-  if (raddr != rax) {
-    __ pop(rax);
+};
+
+class ZSetupArguments {
+private:
+  MacroAssembler* const _masm;
+  const Register        _ref;
+  const Address         _ref_addr;
+
+public:
+  ZSetupArguments(MacroAssembler* masm, ZLoadBarrierStubC2* stub) :
+      _masm(masm),
+      _ref(stub->ref()),
+      _ref_addr(stub->ref_addr()) {
+
+    // Setup arguments
+    if (_ref_addr.base() == noreg) {
+      // No self healing
+      if (_ref != c_rarg0) {
+        __ movq(c_rarg0, _ref);
+      }
+      __ xorq(c_rarg1, c_rarg1);
+    } else {
+      // Self healing
+      if (_ref == c_rarg0) {
+        __ lea(c_rarg1, _ref_addr);
+      } else if (_ref != c_rarg1) {
+        __ lea(c_rarg1, _ref_addr);
+        __ movq(c_rarg0, _ref);
+      } else if (_ref_addr.base() != c_rarg0 && _ref_addr.index() != c_rarg0) {
+        __ movq(c_rarg0, _ref);
+        __ lea(c_rarg1, _ref_addr);
+      } else {
+        __ xchgq(c_rarg0, c_rarg1);
+        if (_ref_addr.base() == c_rarg0) {
+          __ lea(c_rarg1, Address(c_rarg1, _ref_addr.index(), _ref_addr.scale(), _ref_addr.disp()));
+        } else if (_ref_addr.index() == c_rarg0) {
+          __ lea(c_rarg1, Address(_ref_addr.base(), c_rarg1, _ref_addr.scale(), _ref_addr.disp()));
+        } else {
+          ShouldNotReachHere();
+        }
+      }
+    }
   }
 
-  __ ret(0);
+  ~ZSetupArguments() {
+    // Transfer result
+    if (_ref != rax) {
+      __ movq(_ref, rax);
+    }
+  }
+};
+
+#undef __
+#define __ masm->
 
-  return start;
+void ZBarrierSetAssembler::generate_c2_load_barrier_stub(MacroAssembler* masm, ZLoadBarrierStubC2* stub) const {
+  BLOCK_COMMENT("ZLoadBarrierStubC2");
+
+  // Stub entry
+  __ bind(*stub->entry());
+
+  {
+    ZSaveLiveRegisters save_live_registers(masm, stub);
+    ZSetupArguments setup_arguments(masm, stub);
+    __ call(RuntimeAddress(stub->slow_path()));
+  }
+
+  // Stub exit
+  __ jmp(*stub->continuation());
 }
 
 #undef __
 
-static void barrier_stubs_init_inner(const char* label, const DecoratorSet decorators, address* stub) {
-  const int nregs = RegisterImpl::number_of_registers;
-  const int code_size = nregs * 128; // Rough estimate of code size
-
-  ResourceMark rm;
-
-  CodeBuffer buf(BufferBlob::create(label, code_size));
-  StubCodeGenerator cgen(&buf);
-
-  for (int i = 0; i < nregs; i++) {
-    const Register reg = as_Register(i);
-    stub[i] = generate_load_barrier_stub(&cgen, reg, decorators);
-  }
-}
-
-void ZBarrierSetAssembler::barrier_stubs_init() {
-  barrier_stubs_init_inner("zgc_load_barrier_stubs", ON_STRONG_OOP_REF, _load_barrier_slow_stub);
-  barrier_stubs_init_inner("zgc_load_barrier_weak_stubs", ON_WEAK_OOP_REF, _load_barrier_weak_slow_stub);
-}
-
-address ZBarrierSetAssembler::load_barrier_slow_stub(Register reg) {
-  return _load_barrier_slow_stub[reg->encoding()];
-}
-
-address ZBarrierSetAssembler::load_barrier_weak_slow_stub(Register reg) {
-  return _load_barrier_weak_slow_stub[reg->encoding()];
-}
+#endif // COMPILER2
--- a/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -24,6 +24,14 @@
 #ifndef CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP
 #define CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP
 
+#include "code/vmreg.hpp"
+#include "oops/accessDecorators.hpp"
+#ifdef COMPILER2
+#include "opto/optoreg.hpp"
+#endif // COMPILER2
+
+class MacroAssembler;
+
 #ifdef COMPILER1
 class LIR_Assembler;
 class LIR_OprDesc;
@@ -32,14 +40,13 @@
 class ZLoadBarrierStubC1;
 #endif // COMPILER1
 
+#ifdef COMPILER2
+class Node;
+class ZLoadBarrierStubC2;
+#endif // COMPILER2
+
 class ZBarrierSetAssembler : public ZBarrierSetAssemblerBase {
-private:
-  address _load_barrier_slow_stub[RegisterImpl::number_of_registers];
-  address _load_barrier_weak_slow_stub[RegisterImpl::number_of_registers];
-
 public:
-  ZBarrierSetAssembler();
-
   virtual void load_at(MacroAssembler* masm,
                        DecoratorSet decorators,
                        BasicType type,
@@ -82,10 +89,13 @@
                                              DecoratorSet decorators) const;
 #endif // COMPILER1
 
-  virtual void barrier_stubs_init();
+#ifdef COMPILER2
+  OptoReg::Name refine_register(const Node* node,
+                                OptoReg::Name opto_reg);
 
-  address load_barrier_slow_stub(Register reg);
-  address load_barrier_weak_slow_stub(Register reg);
+  void generate_c2_load_barrier_stub(MacroAssembler* masm,
+                                     ZLoadBarrierStubC2* stub) const;
+#endif // COMPILER2
 };
 
 #endif // CPU_X86_GC_Z_ZBARRIERSETASSEMBLER_X86_HPP
--- a/src/hotspot/cpu/x86/gc/z/zGlobals_x86.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/gc/z/zGlobals_x86.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -40,7 +40,7 @@
 //  +--------------------------------+ 0x0000014000000000 (20TB)
 //  |         Remapped View          |
 //  +--------------------------------+ 0x0000010000000000 (16TB)
-//  |     (Reserved, but unused)     |
+//  .                                .
 //  +--------------------------------+ 0x00000c0000000000 (12TB)
 //  |         Marked1 View           |
 //  +--------------------------------+ 0x0000080000000000 (8TB)
@@ -75,7 +75,7 @@
 //  +--------------------------------+ 0x0000280000000000 (40TB)
 //  |         Remapped View          |
 //  +--------------------------------+ 0x0000200000000000 (32TB)
-//  |     (Reserved, but unused)     |
+//  .                                .
 //  +--------------------------------+ 0x0000180000000000 (24TB)
 //  |         Marked1 View           |
 //  +--------------------------------+ 0x0000100000000000 (16TB)
@@ -110,7 +110,7 @@
 //  +--------------------------------+ 0x0000500000000000 (80TB)
 //  |         Remapped View          |
 //  +--------------------------------+ 0x0000400000000000 (64TB)
-//  |     (Reserved, but unused)     |
+//  .                                .
 //  +--------------------------------+ 0x0000300000000000 (48TB)
 //  |         Marked1 View           |
 //  +--------------------------------+ 0x0000200000000000 (32TB)
--- a/src/hotspot/cpu/x86/gc/z/zGlobals_x86.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/gc/z/zGlobals_x86.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -36,7 +36,6 @@
 //  ------------------------------------------------------------------
 //
 const size_t ZPlatformGranuleSizeShift      = 21; // 2MB
-const size_t ZPlatformMaxHeapSizeShift      = 46; // 16TB
 const size_t ZPlatformNMethodDisarmedOffset = 4;
 const size_t ZPlatformCacheLineSize         = 64;
 
--- a/src/hotspot/cpu/x86/gc/z/z_x86_64.ad	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/gc/z/z_x86_64.ad	Thu Oct 10 10:57:42 2019 -0400
@@ -24,190 +24,144 @@
 source_hpp %{
 
 #include "gc/z/c2/zBarrierSetC2.hpp"
+#include "gc/z/zThreadLocalData.hpp"
 
 %}
 
 source %{
 
-#include "gc/z/zBarrierSetAssembler.hpp"
+static void z_load_barrier(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) {
+  ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, weak);
+  __ testptr(ref, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
+  __ jcc(Assembler::notZero, *stub->entry());
+  __ bind(*stub->continuation());
+}
 
-static void z_load_barrier_slow_reg(MacroAssembler& _masm, Register dst, Address src, bool weak) {
-  assert(dst != rsp, "Invalid register");
-  assert(dst != r15, "Invalid register");
-
-  const address stub = weak ? ZBarrierSet::assembler()->load_barrier_weak_slow_stub(dst)
-                            : ZBarrierSet::assembler()->load_barrier_slow_stub(dst);
-  __ lea(dst, src);
-  __ call(RuntimeAddress(stub));
+static void z_load_barrier_slow_path(MacroAssembler& _masm, const MachNode* node, Address ref_addr, Register ref, Register tmp) {
+  ZLoadBarrierStubC2* const stub = ZLoadBarrierStubC2::create(node, ref_addr, ref, tmp, false /* weak */);
+  __ jmp(*stub->entry());
+  __ bind(*stub->continuation());
 }
 
 %}
 
-// For XMM and YMM enabled processors
-instruct zLoadBarrierSlowRegXmmAndYmm(rRegP dst, memory src, rFlagsReg cr,
-                                      rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
-                                      rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
-                                      rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
-                                      rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
-  match(Set dst (LoadBarrierSlowReg src dst));
-  predicate(UseAVX <= 2 && !n->as_LoadBarrierSlowReg()->is_weak());
+// Load Pointer
+instruct zLoadP(rRegP dst, memory mem, rFlagsReg cr)
+%{
+  predicate(UseZGC && n->as_Load()->barrier_data() == ZLoadBarrierStrong);
+  match(Set dst (LoadP mem));
+  effect(KILL cr, TEMP dst);
 
-  effect(KILL cr,
-         KILL x0, KILL x1, KILL x2, KILL x3,
-         KILL x4, KILL x5, KILL x6, KILL x7,
-         KILL x8, KILL x9, KILL x10, KILL x11,
-         KILL x12, KILL x13, KILL x14, KILL x15);
+  ins_cost(125);
 
-  format %{ "lea $dst, $src\n\t"
-            "call #ZLoadBarrierSlowPath" %}
+  format %{ "movq     $dst, $mem" %}
 
   ins_encode %{
-    z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, false /* weak */);
+    __ movptr($dst$$Register, $mem$$Address);
+    if (barrier_data() != ZLoadBarrierElided) {
+      z_load_barrier(_masm, this, $mem$$Address, $dst$$Register, noreg /* tmp */, false /* weak */);
+    }
   %}
-  ins_pipe(pipe_slow);
+
+  ins_pipe(ialu_reg_mem);
 %}
 
-// For ZMM enabled processors
-instruct zLoadBarrierSlowRegZmm(rRegP dst, memory src, rFlagsReg cr,
-                                rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
-                                rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
-                                rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
-                                rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
-                                rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19,
-                                rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23,
-                                rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
-                                rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
+// Load Weak Pointer
+instruct zLoadWeakP(rRegP dst, memory mem, rFlagsReg cr)
+%{
+  predicate(UseZGC && n->as_Load()->barrier_data() == ZLoadBarrierWeak);
+  match(Set dst (LoadP mem));
+  effect(KILL cr, TEMP dst);
 
-  match(Set dst (LoadBarrierSlowReg src dst));
-  predicate(UseAVX == 3 && !n->as_LoadBarrierSlowReg()->is_weak());
+  ins_cost(125);
 
-  effect(KILL cr,
-         KILL x0, KILL x1, KILL x2, KILL x3,
-         KILL x4, KILL x5, KILL x6, KILL x7,
-         KILL x8, KILL x9, KILL x10, KILL x11,
-         KILL x12, KILL x13, KILL x14, KILL x15,
-         KILL x16, KILL x17, KILL x18, KILL x19,
-         KILL x20, KILL x21, KILL x22, KILL x23,
-         KILL x24, KILL x25, KILL x26, KILL x27,
-         KILL x28, KILL x29, KILL x30, KILL x31);
-
-  format %{ "lea $dst, $src\n\t"
-            "call #ZLoadBarrierSlowPath" %}
+  format %{ "movq     $dst, $mem" %}
 
   ins_encode %{
-    z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, false /* weak */);
+    __ movptr($dst$$Register, $mem$$Address);
+    z_load_barrier(_masm, this, $mem$$Address, $dst$$Register, noreg /* tmp */, true /* weak */);
   %}
-  ins_pipe(pipe_slow);
-%}
-
-// For XMM and YMM enabled processors
-instruct zLoadBarrierWeakSlowRegXmmAndYmm(rRegP dst, memory src, rFlagsReg cr,
-                                          rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
-                                          rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
-                                          rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
-                                          rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15) %{
-  match(Set dst (LoadBarrierSlowReg src dst));
-  predicate(UseAVX <= 2 && n->as_LoadBarrierSlowReg()->is_weak());
 
-  effect(KILL cr,
-         KILL x0, KILL x1, KILL x2, KILL x3,
-         KILL x4, KILL x5, KILL x6, KILL x7,
-         KILL x8, KILL x9, KILL x10, KILL x11,
-         KILL x12, KILL x13, KILL x14, KILL x15);
-
-  format %{ "lea $dst, $src\n\t"
-            "call #ZLoadBarrierSlowPath" %}
-
-  ins_encode %{
-    z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, true /* weak */);
-  %}
-  ins_pipe(pipe_slow);
+  ins_pipe(ialu_reg_mem);
 %}
 
-// For ZMM enabled processors
-instruct zLoadBarrierWeakSlowRegZmm(rRegP dst, memory src, rFlagsReg cr,
-                                    rxmm0 x0, rxmm1 x1, rxmm2 x2, rxmm3 x3,
-                                    rxmm4 x4, rxmm5 x5, rxmm6 x6, rxmm7 x7,
-                                    rxmm8 x8, rxmm9 x9, rxmm10 x10, rxmm11 x11,
-                                    rxmm12 x12, rxmm13 x13, rxmm14 x14, rxmm15 x15,
-                                    rxmm16 x16, rxmm17 x17, rxmm18 x18, rxmm19 x19,
-                                    rxmm20 x20, rxmm21 x21, rxmm22 x22, rxmm23 x23,
-                                    rxmm24 x24, rxmm25 x25, rxmm26 x26, rxmm27 x27,
-                                    rxmm28 x28, rxmm29 x29, rxmm30 x30, rxmm31 x31) %{
+instruct zCompareAndExchangeP(memory mem, rax_RegP oldval, rRegP newval, rRegP tmp, rFlagsReg cr) %{
+  match(Set oldval (CompareAndExchangeP mem (Binary oldval newval)));
+  predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+  effect(KILL cr, TEMP tmp);
 
-  match(Set dst (LoadBarrierSlowReg src dst));
-  predicate(UseAVX == 3 && n->as_LoadBarrierSlowReg()->is_weak());
-
-  effect(KILL cr,
-         KILL x0, KILL x1, KILL x2, KILL x3,
-         KILL x4, KILL x5, KILL x6, KILL x7,
-         KILL x8, KILL x9, KILL x10, KILL x11,
-         KILL x12, KILL x13, KILL x14, KILL x15,
-         KILL x16, KILL x17, KILL x18, KILL x19,
-         KILL x20, KILL x21, KILL x22, KILL x23,
-         KILL x24, KILL x25, KILL x26, KILL x27,
-         KILL x28, KILL x29, KILL x30, KILL x31);
-
-  format %{ "lea $dst, $src\n\t"
-            "call #ZLoadBarrierSlowPath" %}
+  format %{ "lock\n\t"
+            "cmpxchgq $newval, $mem" %}
 
   ins_encode %{
-    z_load_barrier_slow_reg(_masm, $dst$$Register, $src$$Address, true /* weak */);
+    if (barrier_data() != ZLoadBarrierElided) {
+      __ movptr($tmp$$Register, $oldval$$Register);
+    }
+    __ lock();
+    __ cmpxchgptr($newval$$Register, $mem$$Address);
+    if (barrier_data() != ZLoadBarrierElided) {
+      Label good;
+      __ testptr($oldval$$Register, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
+      __ jcc(Assembler::zero, good);
+      z_load_barrier_slow_path(_masm, this, $mem$$Address, $oldval$$Register, $tmp$$Register);
+      __ movptr($oldval$$Register, $tmp$$Register);
+      __ lock();
+      __ cmpxchgptr($newval$$Register, $mem$$Address);
+      __ bind(good);
+    }
   %}
-  ins_pipe(pipe_slow);
+
+  ins_pipe(pipe_cmpxchg);
 %}
 
-// Specialized versions of compareAndExchangeP that adds a keepalive that is consumed
-// but doesn't affect output.
+instruct zCompareAndSwapP(rRegI res, memory mem, rRegP newval, rRegP tmp, rFlagsReg cr, rax_RegP oldval) %{
+  match(Set res (CompareAndSwapP mem (Binary oldval newval)));
+  match(Set res (WeakCompareAndSwapP mem (Binary oldval newval)));
+  predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+  effect(KILL cr, KILL oldval, TEMP tmp);
+
+  format %{ "lock\n\t"
+            "cmpxchgq $newval, $mem\n\t"
+            "sete     $res\n\t"
+            "movzbl   $res, $res" %}
 
-instruct z_compareAndExchangeP(
-        memory mem_ptr,
-        rax_RegP oldval, rRegP newval, rRegP keepalive,
-        rFlagsReg cr) %{
-    predicate(VM_Version::supports_cx8());
-    match(Set oldval (ZCompareAndExchangeP (Binary mem_ptr keepalive) (Binary oldval newval)));
-    effect(KILL cr);
+  ins_encode %{
+    if (barrier_data() != ZLoadBarrierElided) {
+      __ movptr($tmp$$Register, $oldval$$Register);
+    }
+    __ lock();
+    __ cmpxchgptr($newval$$Register, $mem$$Address);
+    if (barrier_data() != ZLoadBarrierElided) {
+      Label good;
+      __ testptr($oldval$$Register, Address(r15_thread, ZThreadLocalData::address_bad_mask_offset()));
+      __ jcc(Assembler::zero, good);
+      z_load_barrier_slow_path(_masm, this, $mem$$Address, $oldval$$Register, $tmp$$Register);
+      __ movptr($oldval$$Register, $tmp$$Register);
+      __ lock();
+      __ cmpxchgptr($newval$$Register, $mem$$Address);
+      __ bind(good);
+      __ cmpptr($tmp$$Register, $oldval$$Register);
+    }
+    __ setb(Assembler::equal, $res$$Register);
+    __ movzbl($res$$Register, $res$$Register);
+  %}
 
-    format %{ "cmpxchgq $mem_ptr,$newval\t# "
-              "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
-    opcode(0x0F, 0xB1);
-    ins_encode(lock_prefix,
-            REX_reg_mem_wide(newval, mem_ptr),
-            OpcP, OpcS,
-            reg_mem(newval, mem_ptr)  // lock cmpxchg
-    );
-    ins_pipe( pipe_cmpxchg );
+  ins_pipe(pipe_cmpxchg);
 %}
 
-instruct z_compareAndSwapP(rRegI res,
-                         memory mem_ptr,
-                         rax_RegP oldval, rRegP newval, rRegP keepalive,
-                         rFlagsReg cr) %{
-  predicate(VM_Version::supports_cx8());
-  match(Set res (ZCompareAndSwapP (Binary mem_ptr keepalive) (Binary oldval newval)));
-  match(Set res (ZWeakCompareAndSwapP (Binary mem_ptr keepalive) (Binary oldval newval)));
-  effect(KILL cr, KILL oldval);
+instruct zXChgP(memory mem, rRegP newval, rFlagsReg cr) %{
+  match(Set newval (GetAndSetP mem newval));
+  predicate(UseZGC && n->as_LoadStore()->barrier_data() == ZLoadBarrierStrong);
+  effect(KILL cr);
+
+  format %{ "xchgq    $newval, $mem" %}
 
-  format %{ "cmpxchgq $mem_ptr,$newval\t# "
-            "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
-            "sete    $res\n\t"
-            "movzbl  $res, $res" %}
-  opcode(0x0F, 0xB1);
-  ins_encode(lock_prefix,
-          REX_reg_mem_wide(newval, mem_ptr),
-          OpcP, OpcS,
-          reg_mem(newval, mem_ptr),
-          REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
-          REX_reg_breg(res, res), // movzbl
-          Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
-  ins_pipe( pipe_cmpxchg );
+  ins_encode %{
+    __ xchgptr($newval$$Register, $mem$$Address);
+    if (barrier_data() != ZLoadBarrierElided) {
+      z_load_barrier(_masm, this, Address(noreg, 0), $newval$$Register, noreg /* tmp */, false /* weak */);
+    }
+  %}
+
+  ins_pipe(pipe_cmpxchg);
 %}
-
-instruct z_xchgP( memory mem, rRegP newval, rRegP keepalive) %{
-  match(Set newval (ZGetAndSetP mem (Binary newval keepalive)));
-  format %{ "XCHGQ  $newval,[$mem]" %}
-  ins_encode %{
-    __ xchgq($newval$$Register, $mem$$Address);
-  %}
-  ins_pipe( pipe_cmpxchg );
-%}
--- a/src/hotspot/cpu/x86/globals_x86.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/globals_x86.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -211,5 +211,15 @@
           "Use BMI2 instructions")                                          \
                                                                             \
   diagnostic(bool, UseLibmIntrinsic, true,                                  \
-          "Use Libm Intrinsics")
+          "Use Libm Intrinsics")                                            \
+                                                                            \
+  /* Minimum array size in bytes to use AVX512 intrinsics */                \
+  /* for copy, inflate and fill which don't bail out early based on any */  \
+  /* condition. When this value is set to zero compare operations like */   \
+  /* compare, vectorizedMismatch, compress can also use AVX512 intrinsics.*/\
+  diagnostic(int, AVX3Threshold, 4096,                                      \
+             "Minimum array size in bytes to use AVX512 intrinsics"         \
+             "for copy, inflate and fill. When this value is set as zero"   \
+             "compare operations can also use AVX512 intrinsics.")          \
+          range(0, max_jint)
 #endif // CPU_X86_GLOBALS_X86_HPP
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -824,11 +824,13 @@
 }
 
 void MacroAssembler::stop(const char* msg) {
-  address rip = pc();
-  pusha(); // get regs on stack
+  if (ShowMessageBoxOnError) {
+    address rip = pc();
+    pusha(); // get regs on stack
+    lea(c_rarg1, InternalAddress(rip));
+    movq(c_rarg2, rsp); // pass pointer to regs array
+  }
   lea(c_rarg0, ExternalAddress((address) msg));
-  lea(c_rarg1, InternalAddress(rip));
-  movq(c_rarg2, rsp); // pass pointer to regs array
   andq(rsp, -16); // align stack as required by ABI
   call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug64)));
   hlt();
@@ -6593,7 +6595,7 @@
     bind(COMPARE_WIDE_VECTORS_LOOP);
 
 #ifdef _LP64
-    if (VM_Version::supports_avx512vlbw()) { // trying 64 bytes fast loop
+    if ((AVX3Threshold == 0) && VM_Version::supports_avx512vlbw()) { // trying 64 bytes fast loop
       cmpl(cnt2, stride2x2);
       jccb(Assembler::below, COMPARE_WIDE_VECTORS_LOOP_AVX2);
       testl(cnt2, stride2x2-1);   // cnt2 holds the vector count
@@ -6853,7 +6855,7 @@
   testl(len, len);
   jcc(Assembler::zero, FALSE_LABEL);
 
-  if ((UseAVX > 2) && // AVX512
+  if ((AVX3Threshold == 0) && (UseAVX > 2) && // AVX512
     VM_Version::supports_avx512vlbw() &&
     VM_Version::supports_bmi2()) {
 
@@ -6926,7 +6928,7 @@
   } else {
     movl(result, len); // copy
 
-    if (UseAVX == 2 && UseSSE >= 2) {
+    if (UseAVX >= 2 && UseSSE >= 2) {
       // With AVX2, use 32-byte vector compare
       Label COMPARE_WIDE_VECTORS, COMPARE_TAIL;
 
@@ -7099,14 +7101,12 @@
     lea(ary2, Address(ary2, limit, Address::times_1));
     negptr(limit);
 
-    bind(COMPARE_WIDE_VECTORS);
-
 #ifdef _LP64
-    if (VM_Version::supports_avx512vlbw()) { // trying 64 bytes fast loop
+    if ((AVX3Threshold == 0) && VM_Version::supports_avx512vlbw()) { // trying 64 bytes fast loop
       Label COMPARE_WIDE_VECTORS_LOOP_AVX2, COMPARE_WIDE_VECTORS_LOOP_AVX3;
 
       cmpl(limit, -64);
-      jccb(Assembler::greater, COMPARE_WIDE_VECTORS_LOOP_AVX2);
+      jcc(Assembler::greater, COMPARE_WIDE_VECTORS_LOOP_AVX2);
 
       bind(COMPARE_WIDE_VECTORS_LOOP_AVX3); // the hottest loop
 
@@ -7139,7 +7139,7 @@
 
     }//if (VM_Version::supports_avx512vlbw())
 #endif //_LP64
-
+    bind(COMPARE_WIDE_VECTORS);
     vmovdqu(vec1, Address(ary1, limit, Address::times_1));
     vmovdqu(vec2, Address(ary2, limit, Address::times_1));
     vpxor(vec1, vec2);
@@ -7365,32 +7365,33 @@
       assert( UseSSE >= 2, "supported cpu only" );
       Label L_fill_32_bytes_loop, L_check_fill_8_bytes, L_fill_8_bytes_loop, L_fill_8_bytes;
       movdl(xtmp, value);
-      if (UseAVX > 2 && UseUnalignedLoadStores) {
+      if (UseAVX >= 2 && UseUnalignedLoadStores) {
+        Label L_check_fill_32_bytes;
+        if (UseAVX > 2) {
+          // Fill 64-byte chunks
+          Label L_fill_64_bytes_loop_avx3, L_check_fill_64_bytes_avx2;
+
+          // If number of bytes to fill < AVX3Threshold, perform fill using AVX2
+          cmpl(count, AVX3Threshold);
+          jccb(Assembler::below, L_check_fill_64_bytes_avx2);
+
+          vpbroadcastd(xtmp, xtmp, Assembler::AVX_512bit);
+
+          subl(count, 16 << shift);
+          jccb(Assembler::less, L_check_fill_32_bytes);
+          align(16);
+
+          BIND(L_fill_64_bytes_loop_avx3);
+          evmovdqul(Address(to, 0), xtmp, Assembler::AVX_512bit);
+          addptr(to, 64);
+          subl(count, 16 << shift);
+          jcc(Assembler::greaterEqual, L_fill_64_bytes_loop_avx3);
+          jmpb(L_check_fill_32_bytes);
+
+          BIND(L_check_fill_64_bytes_avx2);
+        }
         // Fill 64-byte chunks
-        Label L_fill_64_bytes_loop, L_check_fill_32_bytes;
-        vpbroadcastd(xtmp, xtmp, Assembler::AVX_512bit);
-
-        subl(count, 16 << shift);
-        jcc(Assembler::less, L_check_fill_32_bytes);
-        align(16);
-
-        BIND(L_fill_64_bytes_loop);
-        evmovdqul(Address(to, 0), xtmp, Assembler::AVX_512bit);
-        addptr(to, 64);
-        subl(count, 16 << shift);
-        jcc(Assembler::greaterEqual, L_fill_64_bytes_loop);
-
-        BIND(L_check_fill_32_bytes);
-        addl(count, 8 << shift);
-        jccb(Assembler::less, L_check_fill_8_bytes);
-        vmovdqu(Address(to, 0), xtmp);
-        addptr(to, 32);
-        subl(count, 8 << shift);
-
-        BIND(L_check_fill_8_bytes);
-      } else if (UseAVX == 2 && UseUnalignedLoadStores) {
-        // Fill 64-byte chunks
-        Label L_fill_64_bytes_loop, L_check_fill_32_bytes;
+        Label L_fill_64_bytes_loop;
         vpbroadcastd(xtmp, xtmp, Assembler::AVX_256bit);
 
         subl(count, 16 << shift);
@@ -8104,12 +8105,13 @@
   shlq(length);
   xorq(result, result);
 
-  if ((UseAVX > 2) &&
+  if ((AVX3Threshold == 0) && (UseAVX > 2) &&
       VM_Version::supports_avx512vlbw()) {
     Label VECTOR64_LOOP, VECTOR64_NOT_EQUAL, VECTOR32_TAIL;
 
     cmpq(length, 64);
     jcc(Assembler::less, VECTOR32_TAIL);
+
     movq(tmp1, length);
     andq(tmp1, 0x3F);      // tail count
     andq(length, ~(0x3F)); //vector count
@@ -9566,7 +9568,7 @@
   // save length for return
   push(len);
 
-  if ((UseAVX > 2) && // AVX512
+  if ((AVX3Threshold == 0) && (UseAVX > 2) && // AVX512
     VM_Version::supports_avx512vlbw() &&
     VM_Version::supports_bmi2()) {
 
@@ -9758,7 +9760,7 @@
 //   }
 void MacroAssembler::byte_array_inflate(Register src, Register dst, Register len,
   XMMRegister tmp1, Register tmp2) {
-  Label copy_chars_loop, done, below_threshold;
+  Label copy_chars_loop, done, below_threshold, avx3_threshold;
   // rsi: src
   // rdi: dst
   // rdx: len
@@ -9768,7 +9770,7 @@
   // rdi holds start addr of destination char[]
   // rdx holds length
   assert_different_registers(src, dst, len, tmp2);
-
+  movl(tmp2, len);
   if ((UseAVX > 2) && // AVX512
     VM_Version::supports_avx512vlbw() &&
     VM_Version::supports_bmi2()) {
@@ -9780,9 +9782,11 @@
     testl(len, -16);
     jcc(Assembler::zero, below_threshold);
 
+    testl(len, -1 * AVX3Threshold);
+    jcc(Assembler::zero, avx3_threshold);
+
     // In order to use only one arithmetic operation for the main loop we use
     // this pre-calculation
-    movl(tmp2, len);
     andl(tmp2, (32 - 1)); // tail count (in chars), 32 element wide loop
     andl(len, -32);     // vector count
     jccb(Assembler::zero, copy_tail);
@@ -9813,12 +9817,11 @@
     evmovdquw(Address(dst, 0), k2, tmp1, Assembler::AVX_512bit);
 
     jmp(done);
+    bind(avx3_threshold);
   }
   if (UseSSE42Intrinsics) {
     Label copy_16_loop, copy_8_loop, copy_bytes, copy_new_tail, copy_tail;
 
-    movl(tmp2, len);
-
     if (UseAVX > 1) {
       andl(tmp2, (16 - 1));
       andl(len, -16);
@@ -9843,13 +9846,7 @@
 
       bind(below_threshold);
       bind(copy_new_tail);
-      if ((UseAVX > 2) &&
-        VM_Version::supports_avx512vlbw() &&
-        VM_Version::supports_bmi2()) {
-        movl(tmp2, len);
-      } else {
-        movl(len, tmp2);
-      }
+      movl(len, tmp2);
       andl(tmp2, 0x00000007);
       andl(len, 0xFFFFFFF8);
       jccb(Assembler::zero, copy_tail);
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1288,30 +1288,58 @@
     if (UseUnalignedLoadStores) {
       Label L_end;
       // Copy 64-bytes per iteration
-      __ BIND(L_loop);
       if (UseAVX > 2) {
+        Label L_loop_avx512, L_loop_avx2, L_32_byte_head, L_above_threshold, L_below_threshold;
+
+        __ BIND(L_copy_bytes);
+        __ cmpptr(qword_count, (-1 * AVX3Threshold / 8));
+        __ jccb(Assembler::less, L_above_threshold);
+        __ jmpb(L_below_threshold);
+
+        __ bind(L_loop_avx512);
         __ evmovdqul(xmm0, Address(end_from, qword_count, Address::times_8, -56), Assembler::AVX_512bit);
         __ evmovdqul(Address(end_to, qword_count, Address::times_8, -56), xmm0, Assembler::AVX_512bit);
-      } else if (UseAVX == 2) {
+        __ bind(L_above_threshold);
+        __ addptr(qword_count, 8);
+        __ jcc(Assembler::lessEqual, L_loop_avx512);
+        __ jmpb(L_32_byte_head);
+
+        __ bind(L_loop_avx2);
         __ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56));
         __ vmovdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0);
         __ vmovdqu(xmm1, Address(end_from, qword_count, Address::times_8, -24));
         __ vmovdqu(Address(end_to, qword_count, Address::times_8, -24), xmm1);
+        __ bind(L_below_threshold);
+        __ addptr(qword_count, 8);
+        __ jcc(Assembler::lessEqual, L_loop_avx2);
+
+        __ bind(L_32_byte_head);
+        __ subptr(qword_count, 4);  // sub(8) and add(4)
+        __ jccb(Assembler::greater, L_end);
       } else {
-        __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56));
-        __ movdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0);
-        __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, -40));
-        __ movdqu(Address(end_to, qword_count, Address::times_8, -40), xmm1);
-        __ movdqu(xmm2, Address(end_from, qword_count, Address::times_8, -24));
-        __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm2);
-        __ movdqu(xmm3, Address(end_from, qword_count, Address::times_8, - 8));
-        __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm3);
+        __ BIND(L_loop);
+        if (UseAVX == 2) {
+          __ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56));
+          __ vmovdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0);
+          __ vmovdqu(xmm1, Address(end_from, qword_count, Address::times_8, -24));
+          __ vmovdqu(Address(end_to, qword_count, Address::times_8, -24), xmm1);
+        } else {
+          __ movdqu(xmm0, Address(end_from, qword_count, Address::times_8, -56));
+          __ movdqu(Address(end_to, qword_count, Address::times_8, -56), xmm0);
+          __ movdqu(xmm1, Address(end_from, qword_count, Address::times_8, -40));
+          __ movdqu(Address(end_to, qword_count, Address::times_8, -40), xmm1);
+          __ movdqu(xmm2, Address(end_from, qword_count, Address::times_8, -24));
+          __ movdqu(Address(end_to, qword_count, Address::times_8, -24), xmm2);
+          __ movdqu(xmm3, Address(end_from, qword_count, Address::times_8, - 8));
+          __ movdqu(Address(end_to, qword_count, Address::times_8, - 8), xmm3);
+        }
+
+        __ BIND(L_copy_bytes);
+        __ addptr(qword_count, 8);
+        __ jcc(Assembler::lessEqual, L_loop);
+        __ subptr(qword_count, 4);  // sub(8) and add(4)
+        __ jccb(Assembler::greater, L_end);
       }
-      __ BIND(L_copy_bytes);
-      __ addptr(qword_count, 8);
-      __ jcc(Assembler::lessEqual, L_loop);
-      __ subptr(qword_count, 4);  // sub(8) and add(4)
-      __ jccb(Assembler::greater, L_end);
       // Copy trailing 32 bytes
       if (UseAVX >= 2) {
         __ vmovdqu(xmm0, Address(end_from, qword_count, Address::times_8, -24));
@@ -1368,31 +1396,59 @@
     if (UseUnalignedLoadStores) {
       Label L_end;
       // Copy 64-bytes per iteration
-      __ BIND(L_loop);
       if (UseAVX > 2) {
+        Label L_loop_avx512, L_loop_avx2, L_32_byte_head, L_above_threshold, L_below_threshold;
+
+        __ BIND(L_copy_bytes);
+        __ cmpptr(qword_count, (AVX3Threshold / 8));
+        __ jccb(Assembler::greater, L_above_threshold);
+        __ jmpb(L_below_threshold);
+
+        __ BIND(L_loop_avx512);
         __ evmovdqul(xmm0, Address(from, qword_count, Address::times_8, 0), Assembler::AVX_512bit);
         __ evmovdqul(Address(dest, qword_count, Address::times_8, 0), xmm0, Assembler::AVX_512bit);
-      } else if (UseAVX == 2) {
+        __ bind(L_above_threshold);
+        __ subptr(qword_count, 8);
+        __ jcc(Assembler::greaterEqual, L_loop_avx512);
+        __ jmpb(L_32_byte_head);
+
+        __ bind(L_loop_avx2);
         __ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 32));
         __ vmovdqu(Address(dest, qword_count, Address::times_8, 32), xmm0);
-        __ vmovdqu(xmm1, Address(from, qword_count, Address::times_8,  0));
-        __ vmovdqu(Address(dest, qword_count, Address::times_8,  0), xmm1);
+        __ vmovdqu(xmm1, Address(from, qword_count, Address::times_8, 0));
+        __ vmovdqu(Address(dest, qword_count, Address::times_8, 0), xmm1);
+        __ bind(L_below_threshold);
+        __ subptr(qword_count, 8);
+        __ jcc(Assembler::greaterEqual, L_loop_avx2);
+
+        __ bind(L_32_byte_head);
+        __ addptr(qword_count, 4);  // add(8) and sub(4)
+        __ jccb(Assembler::less, L_end);
       } else {
-        __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 48));
-        __ movdqu(Address(dest, qword_count, Address::times_8, 48), xmm0);
-        __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 32));
-        __ movdqu(Address(dest, qword_count, Address::times_8, 32), xmm1);
-        __ movdqu(xmm2, Address(from, qword_count, Address::times_8, 16));
-        __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm2);
-        __ movdqu(xmm3, Address(from, qword_count, Address::times_8,  0));
-        __ movdqu(Address(dest, qword_count, Address::times_8,  0), xmm3);
+        __ BIND(L_loop);
+        if (UseAVX == 2) {
+          __ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 32));
+          __ vmovdqu(Address(dest, qword_count, Address::times_8, 32), xmm0);
+          __ vmovdqu(xmm1, Address(from, qword_count, Address::times_8,  0));
+          __ vmovdqu(Address(dest, qword_count, Address::times_8,  0), xmm1);
+        } else {
+          __ movdqu(xmm0, Address(from, qword_count, Address::times_8, 48));
+          __ movdqu(Address(dest, qword_count, Address::times_8, 48), xmm0);
+          __ movdqu(xmm1, Address(from, qword_count, Address::times_8, 32));
+          __ movdqu(Address(dest, qword_count, Address::times_8, 32), xmm1);
+          __ movdqu(xmm2, Address(from, qword_count, Address::times_8, 16));
+          __ movdqu(Address(dest, qword_count, Address::times_8, 16), xmm2);
+          __ movdqu(xmm3, Address(from, qword_count, Address::times_8,  0));
+          __ movdqu(Address(dest, qword_count, Address::times_8,  0), xmm3);
+        }
+
+        __ BIND(L_copy_bytes);
+        __ subptr(qword_count, 8);
+        __ jcc(Assembler::greaterEqual, L_loop);
+
+        __ addptr(qword_count, 4);  // add(8) and sub(4)
+        __ jccb(Assembler::less, L_end);
       }
-      __ BIND(L_copy_bytes);
-      __ subptr(qword_count, 8);
-      __ jcc(Assembler::greaterEqual, L_loop);
-
-      __ addptr(qword_count, 4);  // add(8) and sub(4)
-      __ jccb(Assembler::less, L_end);
       // Copy trailing 32 bytes
       if (UseAVX >= 2) {
         __ vmovdqu(xmm0, Address(from, qword_count, Address::times_8, 0));
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -381,6 +381,10 @@
     __ cmpl(rax, 0xE0);
     __ jccb(Assembler::notEqual, legacy_setup); // jump if EVEX is not supported
 
+    __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())));
+    __ movl(rax, Address(rsi, 0));
+    __ cmpl(rax, 0x50654);              // If it is Skylake
+    __ jcc(Assembler::equal, legacy_setup);
     // If UseAVX is unitialized or is set by the user to include EVEX
     if (use_evex) {
       // EVEX setup: run in lowest evex mode
@@ -465,6 +469,11 @@
     __ cmpl(rax, 0xE0);
     __ jcc(Assembler::notEqual, legacy_save_restore);
 
+    __ lea(rsi, Address(rbp, in_bytes(VM_Version::std_cpuid1_offset())));
+    __ movl(rax, Address(rsi, 0));
+    __ cmpl(rax, 0x50654);              // If it is Skylake
+    __ jcc(Assembler::equal, legacy_save_restore);
+
     // If UseAVX is unitialized or is set by the user to include EVEX
     if (use_evex) {
       // EVEX check: run in lowest evex mode
@@ -660,6 +669,9 @@
   }
   if (FLAG_IS_DEFAULT(UseAVX)) {
     FLAG_SET_DEFAULT(UseAVX, use_avx_limit);
+    if (is_intel_family_core() && _model == CPU_MODEL_SKYLAKE && _stepping < 5) {
+      FLAG_SET_DEFAULT(UseAVX, 2);  //Set UseAVX=2 for Skylake
+    }
   } else if (UseAVX > use_avx_limit) {
     warning("UseAVX=%d is not supported on this CPU, setting it to UseAVX=%d", (int) UseAVX, use_avx_limit);
     FLAG_SET_DEFAULT(UseAVX, use_avx_limit);
@@ -1059,6 +1071,13 @@
   }
 #endif // COMPILER2 && ASSERT
 
+  if (!FLAG_IS_DEFAULT(AVX3Threshold)) {
+    if (!is_power_of_2(AVX3Threshold)) {
+      warning("AVX3Threshold must be a power of 2");
+      FLAG_SET_DEFAULT(AVX3Threshold, 4096);
+    }
+  }
+
 #ifdef _LP64
   if (FLAG_IS_DEFAULT(UseMultiplyToLenIntrinsic)) {
     UseMultiplyToLenIntrinsic = true;
--- a/src/hotspot/cpu/x86/vm_version_x86.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/vm_version_x86.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -366,7 +366,7 @@
     CPU_MODEL_HASWELL_E3     = 0x3c,
     CPU_MODEL_HASWELL_E7     = 0x3f,
     CPU_MODEL_BROADWELL      = 0x3d,
-    CPU_MODEL_SKYLAKE        = CPU_MODEL_HASWELL_E3
+    CPU_MODEL_SKYLAKE        = 0x55
   };
 
   // cpuid information block.  All info derived from executing cpuid with
--- a/src/hotspot/cpu/x86/x86.ad	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/x86.ad	Thu Oct 10 10:57:42 2019 -0400
@@ -1097,138 +1097,6 @@
 reg_class_dynamic vectorz_reg(vectorz_reg_evex, vectorz_reg_legacy, %{ VM_Version::supports_evex() %} );
 reg_class_dynamic vectorz_reg_vl(vectorz_reg_evex, vectorz_reg_legacy, %{ VM_Version::supports_evex() && VM_Version::supports_avx512vl() %} );
 
-reg_class xmm0_reg(XMM0, XMM0b, XMM0c, XMM0d);
-reg_class ymm0_reg(XMM0, XMM0b, XMM0c, XMM0d, XMM0e, XMM0f, XMM0g, XMM0h);
-reg_class zmm0_reg(XMM0, XMM0b, XMM0c, XMM0d, XMM0e, XMM0f, XMM0g, XMM0h, XMM0i, XMM0j, XMM0k, XMM0l, XMM0m, XMM0n, XMM0o, XMM0p);
-
-reg_class xmm1_reg(XMM1, XMM1b, XMM1c, XMM1d);
-reg_class ymm1_reg(XMM1, XMM1b, XMM1c, XMM1d, XMM1e, XMM1f, XMM1g, XMM1h);
-reg_class zmm1_reg(XMM1, XMM1b, XMM1c, XMM1d, XMM1e, XMM1f, XMM1g, XMM1h, XMM1i, XMM1j, XMM1k, XMM1l, XMM1m, XMM1n, XMM1o, XMM1p);
-
-reg_class xmm2_reg(XMM2, XMM2b, XMM2c, XMM2d);
-reg_class ymm2_reg(XMM2, XMM2b, XMM2c, XMM2d, XMM2e, XMM2f, XMM2g, XMM2h);
-reg_class zmm2_reg(XMM2, XMM2b, XMM2c, XMM2d, XMM2e, XMM2f, XMM2g, XMM2h, XMM2i, XMM2j, XMM2k, XMM2l, XMM2m, XMM2n, XMM2o, XMM2p);
-
-reg_class xmm3_reg(XMM3, XMM3b, XMM3c, XMM3d);
-reg_class ymm3_reg(XMM3, XMM3b, XMM3c, XMM3d, XMM3e, XMM3f, XMM3g, XMM3h);
-reg_class zmm3_reg(XMM3, XMM3b, XMM3c, XMM3d, XMM3e, XMM3f, XMM3g, XMM3h, XMM3i, XMM3j, XMM3k, XMM3l, XMM3m, XMM3n, XMM3o, XMM3p);
-
-reg_class xmm4_reg(XMM4, XMM4b, XMM4c, XMM4d);
-reg_class ymm4_reg(XMM4, XMM4b, XMM4c, XMM4d, XMM4e, XMM4f, XMM4g, XMM4h);
-reg_class zmm4_reg(XMM4, XMM4b, XMM4c, XMM4d, XMM4e, XMM4f, XMM4g, XMM4h, XMM4i, XMM4j, XMM4k, XMM4l, XMM4m, XMM4n, XMM4o, XMM4p);
-
-reg_class xmm5_reg(XMM5, XMM5b, XMM5c, XMM5d);
-reg_class ymm5_reg(XMM5, XMM5b, XMM5c, XMM5d, XMM5e, XMM5f, XMM5g, XMM5h);
-reg_class zmm5_reg(XMM5, XMM5b, XMM5c, XMM5d, XMM5e, XMM5f, XMM5g, XMM5h, XMM5i, XMM5j, XMM5k, XMM5l, XMM5m, XMM5n, XMM5o, XMM5p);
-
-reg_class xmm6_reg(XMM6, XMM6b, XMM6c, XMM6d);
-reg_class ymm6_reg(XMM6, XMM6b, XMM6c, XMM6d, XMM6e, XMM6f, XMM6g, XMM6h);
-reg_class zmm6_reg(XMM6, XMM6b, XMM6c, XMM6d, XMM6e, XMM6f, XMM6g, XMM6h, XMM6i, XMM6j, XMM6k, XMM6l, XMM6m, XMM6n, XMM6o, XMM6p);
-
-reg_class xmm7_reg(XMM7, XMM7b, XMM7c, XMM7d);
-reg_class ymm7_reg(XMM7, XMM7b, XMM7c, XMM7d, XMM7e, XMM7f, XMM7g, XMM7h);
-reg_class zmm7_reg(XMM7, XMM7b, XMM7c, XMM7d, XMM7e, XMM7f, XMM7g, XMM7h, XMM7i, XMM7j, XMM7k, XMM7l, XMM7m, XMM7n, XMM7o, XMM7p);
-
-#ifdef _LP64
-
-reg_class xmm8_reg(XMM8, XMM8b, XMM8c, XMM8d);
-reg_class ymm8_reg(XMM8, XMM8b, XMM8c, XMM8d, XMM8e, XMM8f, XMM8g, XMM8h);
-reg_class zmm8_reg(XMM8, XMM8b, XMM8c, XMM8d, XMM8e, XMM8f, XMM8g, XMM8h, XMM8i, XMM8j, XMM8k, XMM8l, XMM8m, XMM8n, XMM8o, XMM8p);
-
-reg_class xmm9_reg(XMM9, XMM9b, XMM9c, XMM9d);
-reg_class ymm9_reg(XMM9, XMM9b, XMM9c, XMM9d, XMM9e, XMM9f, XMM9g, XMM9h);
-reg_class zmm9_reg(XMM9, XMM9b, XMM9c, XMM9d, XMM9e, XMM9f, XMM9g, XMM9h, XMM9i, XMM9j, XMM9k, XMM9l, XMM9m, XMM9n, XMM9o, XMM9p);
-
-reg_class xmm10_reg(XMM10, XMM10b, XMM10c, XMM10d);
-reg_class ymm10_reg(XMM10, XMM10b, XMM10c, XMM10d, XMM10e, XMM10f, XMM10g, XMM10h);
-reg_class zmm10_reg(XMM10, XMM10b, XMM10c, XMM10d, XMM10e, XMM10f, XMM10g, XMM10h, XMM10i, XMM10j, XMM10k, XMM10l, XMM10m, XMM10n, XMM10o, XMM10p);
-
-reg_class xmm11_reg(XMM11, XMM11b, XMM11c, XMM11d);
-reg_class ymm11_reg(XMM11, XMM11b, XMM11c, XMM11d, XMM11e, XMM11f, XMM11g, XMM11h);
-reg_class zmm11_reg(XMM11, XMM11b, XMM11c, XMM11d, XMM11e, XMM11f, XMM11g, XMM11h, XMM11i, XMM11j, XMM11k, XMM11l, XMM11m, XMM11n, XMM11o, XMM11p);
-
-reg_class xmm12_reg(XMM12, XMM12b, XMM12c, XMM12d);
-reg_class ymm12_reg(XMM12, XMM12b, XMM12c, XMM12d, XMM12e, XMM12f, XMM12g, XMM12h);
-reg_class zmm12_reg(XMM12, XMM12b, XMM12c, XMM12d, XMM12e, XMM12f, XMM12g, XMM12h, XMM12i, XMM12j, XMM12k, XMM12l, XMM12m, XMM12n, XMM12o, XMM12p);
-
-reg_class xmm13_reg(XMM13, XMM13b, XMM13c, XMM13d);
-reg_class ymm13_reg(XMM13, XMM13b, XMM13c, XMM13d, XMM13e, XMM13f, XMM13g, XMM13h);
-reg_class zmm13_reg(XMM13, XMM13b, XMM13c, XMM13d, XMM13e, XMM13f, XMM13g, XMM13h, XMM13i, XMM13j, XMM13k, XMM13l, XMM13m, XMM13n, XMM13o, XMM13p);
-
-reg_class xmm14_reg(XMM14, XMM14b, XMM14c, XMM14d);
-reg_class ymm14_reg(XMM14, XMM14b, XMM14c, XMM14d, XMM14e, XMM14f, XMM14g, XMM14h);
-reg_class zmm14_reg(XMM14, XMM14b, XMM14c, XMM14d, XMM14e, XMM14f, XMM14g, XMM14h, XMM14i, XMM14j, XMM14k, XMM14l, XMM14m, XMM14n, XMM14o, XMM14p);
-
-reg_class xmm15_reg(XMM15, XMM15b, XMM15c, XMM15d);
-reg_class ymm15_reg(XMM15, XMM15b, XMM15c, XMM15d, XMM15e, XMM15f, XMM15g, XMM15h);
-reg_class zmm15_reg(XMM15, XMM15b, XMM15c, XMM15d, XMM15e, XMM15f, XMM15g, XMM15h, XMM15i, XMM15j, XMM15k, XMM15l, XMM15m, XMM15n, XMM15o, XMM15p);
-
-reg_class xmm16_reg(XMM16, XMM16b, XMM16c, XMM16d);
-reg_class ymm16_reg(XMM16, XMM16b, XMM16c, XMM16d, XMM16e, XMM16f, XMM16g, XMM16h);
-reg_class zmm16_reg(XMM16, XMM16b, XMM16c, XMM16d, XMM16e, XMM16f, XMM16g, XMM16h, XMM16i, XMM16j, XMM16k, XMM16l, XMM16m, XMM16n, XMM16o, XMM16p);
-
-reg_class xmm17_reg(XMM17, XMM17b, XMM17c, XMM17d);
-reg_class ymm17_reg(XMM17, XMM17b, XMM17c, XMM17d, XMM17e, XMM17f, XMM17g, XMM17h);
-reg_class zmm17_reg(XMM17, XMM17b, XMM17c, XMM17d, XMM17e, XMM17f, XMM17g, XMM17h, XMM17i, XMM17j, XMM17k, XMM17l, XMM17m, XMM17n, XMM17o, XMM17p);
-
-reg_class xmm18_reg(XMM18, XMM18b, XMM18c, XMM18d);
-reg_class ymm18_reg(XMM18, XMM18b, XMM18c, XMM18d, XMM18e, XMM18f, XMM18g, XMM18h);
-reg_class zmm18_reg(XMM18, XMM18b, XMM18c, XMM18d, XMM18e, XMM18f, XMM18g, XMM18h, XMM18i, XMM18j, XMM18k, XMM18l, XMM18m, XMM18n, XMM18o, XMM18p);
-
-reg_class xmm19_reg(XMM19, XMM19b, XMM19c, XMM19d);
-reg_class ymm19_reg(XMM19, XMM19b, XMM19c, XMM19d, XMM19e, XMM19f, XMM19g, XMM19h);
-reg_class zmm19_reg(XMM19, XMM19b, XMM19c, XMM19d, XMM19e, XMM19f, XMM19g, XMM19h, XMM19i, XMM19j, XMM19k, XMM19l, XMM19m, XMM19n, XMM19o, XMM19p);
-
-reg_class xmm20_reg(XMM20, XMM20b, XMM20c, XMM20d);
-reg_class ymm20_reg(XMM20, XMM20b, XMM20c, XMM20d, XMM20e, XMM20f, XMM20g, XMM20h);
-reg_class zmm20_reg(XMM20, XMM20b, XMM20c, XMM20d, XMM20e, XMM20f, XMM20g, XMM20h, XMM20i, XMM20j, XMM20k, XMM20l, XMM20m, XMM20n, XMM20o, XMM20p);
-
-reg_class xmm21_reg(XMM21, XMM21b, XMM21c, XMM21d);
-reg_class ymm21_reg(XMM21, XMM21b, XMM21c, XMM21d, XMM21e, XMM21f, XMM21g, XMM21h);
-reg_class zmm21_reg(XMM21, XMM21b, XMM21c, XMM21d, XMM21e, XMM21f, XMM21g, XMM21h, XMM21i, XMM21j, XMM21k, XMM21l, XMM21m, XMM21n, XMM21o, XMM21p);
-
-reg_class xmm22_reg(XMM22, XMM22b, XMM22c, XMM22d);
-reg_class ymm22_reg(XMM22, XMM22b, XMM22c, XMM22d, XMM22e, XMM22f, XMM22g, XMM22h);
-reg_class zmm22_reg(XMM22, XMM22b, XMM22c, XMM22d, XMM22e, XMM22f, XMM22g, XMM22h, XMM22i, XMM22j, XMM22k, XMM22l, XMM22m, XMM22n, XMM22o, XMM22p);
-
-reg_class xmm23_reg(XMM23, XMM23b, XMM23c, XMM23d);
-reg_class ymm23_reg(XMM23, XMM23b, XMM23c, XMM23d, XMM23e, XMM23f, XMM23g, XMM23h);
-reg_class zmm23_reg(XMM23, XMM23b, XMM23c, XMM23d, XMM23e, XMM23f, XMM23g, XMM23h, XMM23i, XMM23j, XMM23k, XMM23l, XMM23m, XMM23n, XMM23o, XMM23p);
-
-reg_class xmm24_reg(XMM24, XMM24b, XMM24c, XMM24d);
-reg_class ymm24_reg(XMM24, XMM24b, XMM24c, XMM24d, XMM24e, XMM24f, XMM24g, XMM24h);
-reg_class zmm24_reg(XMM24, XMM24b, XMM24c, XMM24d, XMM24e, XMM24f, XMM24g, XMM24h, XMM24i, XMM24j, XMM24k, XMM24l, XMM24m, XMM24n, XMM24o, XMM24p);
-
-reg_class xmm25_reg(XMM25, XMM25b, XMM25c, XMM25d);
-reg_class ymm25_reg(XMM25, XMM25b, XMM25c, XMM25d, XMM25e, XMM25f, XMM25g, XMM25h);
-reg_class zmm25_reg(XMM25, XMM25b, XMM25c, XMM25d, XMM25e, XMM25f, XMM25g, XMM25h, XMM25i, XMM25j, XMM25k, XMM25l, XMM25m, XMM25n, XMM25o, XMM25p);
-
-reg_class xmm26_reg(XMM26, XMM26b, XMM26c, XMM26d);
-reg_class ymm26_reg(XMM26, XMM26b, XMM26c, XMM26d, XMM26e, XMM26f, XMM26g, XMM26h);
-reg_class zmm26_reg(XMM26, XMM26b, XMM26c, XMM26d, XMM26e, XMM26f, XMM26g, XMM26h, XMM26i, XMM26j, XMM26k, XMM26l, XMM26m, XMM26n, XMM26o, XMM26p);
-
-reg_class xmm27_reg(XMM27, XMM27b, XMM27c, XMM27d);
-reg_class ymm27_reg(XMM27, XMM27b, XMM27c, XMM27d, XMM27e, XMM27f, XMM27g, XMM27h);
-reg_class zmm27_reg(XMM27, XMM27b, XMM27c, XMM27d, XMM27e, XMM27f, XMM27g, XMM27h, XMM27i, XMM27j, XMM27k, XMM27l, XMM27m, XMM27n, XMM27o, XMM27p);
-
-reg_class xmm28_reg(XMM28, XMM28b, XMM28c, XMM28d);
-reg_class ymm28_reg(XMM28, XMM28b, XMM28c, XMM28d, XMM28e, XMM28f, XMM28g, XMM28h);
-reg_class zmm28_reg(XMM28, XMM28b, XMM28c, XMM28d, XMM28e, XMM28f, XMM28g, XMM28h, XMM28i, XMM28j, XMM28k, XMM28l, XMM28m, XMM28n, XMM28o, XMM28p);
-
-reg_class xmm29_reg(XMM29, XMM29b, XMM29c, XMM29d);
-reg_class ymm29_reg(XMM29, XMM29b, XMM29c, XMM29d, XMM29e, XMM29f, XMM29g, XMM29h);
-reg_class zmm29_reg(XMM29, XMM29b, XMM29c, XMM29d, XMM29e, XMM29f, XMM29g, XMM29h, XMM29i, XMM29j, XMM29k, XMM29l, XMM29m, XMM29n, XMM29o, XMM29p);
-
-reg_class xmm30_reg(XMM30, XMM30b, XMM30c, XMM30d);
-reg_class ymm30_reg(XMM30, XMM30b, XMM30c, XMM30d, XMM30e, XMM30f, XMM30g, XMM30h);
-reg_class zmm30_reg(XMM30, XMM30b, XMM30c, XMM30d, XMM30e, XMM30f, XMM30g, XMM30h, XMM30i, XMM30j, XMM30k, XMM30l, XMM30m, XMM30n, XMM30o, XMM30p);
-
-reg_class xmm31_reg(XMM31, XMM31b, XMM31c, XMM31d);
-reg_class ymm31_reg(XMM31, XMM31b, XMM31c, XMM31d, XMM31e, XMM31f, XMM31g, XMM31h);
-reg_class zmm31_reg(XMM31, XMM31b, XMM31c, XMM31d, XMM31e, XMM31f, XMM31g, XMM31h, XMM31i, XMM31j, XMM31k, XMM31l, XMM31m, XMM31n, XMM31o, XMM31p);
-
-#endif
-
 %}
 
 
@@ -1800,8 +1668,8 @@
   return (UseAVX > 2) ? 6 : 4;
 }
 
-static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
-                            int stack_offset, int reg, uint ireg, outputStream* st) {
+int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
+                     int stack_offset, int reg, uint ireg, outputStream* st) {
   // In 64-bit VM size calculation is very complex. Emitting instructions
   // into scratch buffer is used to get size in 64-bit VM.
   LP64_ONLY( assert(!do_size, "this method calculates size only for 32-bit VM"); )
@@ -2863,6 +2731,7 @@
 %}
 
 
+#ifdef _LP64
 instruct roundD_reg(legRegD dst, legRegD src, immU8 rmode) %{
   predicate(UseSSE>=4);
   match(Set dst (RoundDoubleMode src rmode));
@@ -2963,6 +2832,7 @@
   %}
   ins_pipe( pipe_slow );
 %}
+#endif // _LP64
 
 instruct onspinwait() %{
   match(OnSpinWait);
@@ -3859,7 +3729,7 @@
 %}
 
 instruct Repl2F_zero(vecD dst, immF0 zero) %{
-  predicate(n->as_Vector()->length() == 2 && UseAVX < 3);
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (ReplicateF zero));
   format %{ "xorps   $dst,$dst\t! replicate2F zero" %}
   ins_encode %{
@@ -3869,7 +3739,7 @@
 %}
 
 instruct Repl4F_zero(vecX dst, immF0 zero) %{
-  predicate(n->as_Vector()->length() == 4 && UseAVX < 3);
+  predicate(n->as_Vector()->length() == 4);
   match(Set dst (ReplicateF zero));
   format %{ "xorps   $dst,$dst\t! replicate4F zero" %}
   ins_encode %{
@@ -3879,7 +3749,7 @@
 %}
 
 instruct Repl8F_zero(vecY dst, immF0 zero) %{
-  predicate(n->as_Vector()->length() == 8 && UseAVX < 3);
+  predicate(n->as_Vector()->length() == 8 && UseAVX > 0);
   match(Set dst (ReplicateF zero));
   format %{ "vxorps  $dst,$dst,$dst\t! replicate8F zero" %}
   ins_encode %{
@@ -3953,7 +3823,7 @@
 
 // Replicate double (8 byte) scalar zero to be vector
 instruct Repl2D_zero(vecX dst, immD0 zero) %{
-  predicate(n->as_Vector()->length() == 2 && UseAVX < 3);
+  predicate(n->as_Vector()->length() == 2);
   match(Set dst (ReplicateD zero));
   format %{ "xorpd   $dst,$dst\t! replicate2D zero" %}
   ins_encode %{
@@ -3963,7 +3833,7 @@
 %}
 
 instruct Repl4D_zero(vecY dst, immD0 zero) %{
-  predicate(n->as_Vector()->length() == 4 && UseAVX < 3);
+  predicate(n->as_Vector()->length() == 4 && UseAVX > 0);
   match(Set dst (ReplicateD zero));
   format %{ "vxorpd  $dst,$dst,$dst,vect256\t! replicate4D zero" %}
   ins_encode %{
@@ -4888,42 +4758,6 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct Repl2F_zero_evex(vecD dst, immF0 zero) %{
-  predicate(n->as_Vector()->length() == 2 && UseAVX > 2);
-  match(Set dst (ReplicateF zero));
-  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate2F zero" %}
-  ins_encode %{
-    // Use vpxor in place of vxorps since EVEX has a constriant on dq for vxorps: this is a 512-bit operation
-    int vector_len = 2;
-    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-instruct Repl4F_zero_evex(vecX dst, immF0 zero) %{
-  predicate(n->as_Vector()->length() == 4 && UseAVX > 2);
-  match(Set dst (ReplicateF zero));
-  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate4F zero" %}
-  ins_encode %{
-    // Use vpxor in place of vxorps since EVEX has a constriant on dq for vxorps: this is a 512-bit operation
-    int vector_len = 2;
-    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-instruct Repl8F_zero_evex(vecY dst, immF0 zero) %{
-  predicate(n->as_Vector()->length() == 8 && UseAVX > 2);
-  match(Set dst (ReplicateF zero));
-  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate8F zero" %}
-  ins_encode %{
-    // Use vpxor in place of vxorps since EVEX has a constriant on dq for vxorps: this is a 512-bit operation
-    int vector_len = 2;
-    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
 instruct Repl16F_zero_evex(vecZ dst, immF0 zero) %{
   predicate(n->as_Vector()->length() == 16 && UseAVX > 2);
   match(Set dst (ReplicateF zero));
@@ -4980,30 +4814,6 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct Repl2D_zero_evex(vecX dst, immD0 zero) %{
-  predicate(n->as_Vector()->length() == 2 && UseAVX > 2);
-  match(Set dst (ReplicateD zero));
-  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate2D zero" %}
-  ins_encode %{
-    // Use vpxor in place of vxorpd since EVEX has a constriant on dq for vxorpd: this is a 512-bit operation
-    int vector_len = 2;
-    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-instruct Repl4D_zero_evex(vecY dst, immD0 zero) %{
-  predicate(n->as_Vector()->length() == 4 && UseAVX > 2);
-  match(Set dst (ReplicateD zero));
-  format %{ "vpxor  $dst k0,$dst,$dst\t! replicate4D zero" %}
-  ins_encode %{
-    // Use vpxor in place of vxorpd since EVEX has a constriant on dq for vxorpd: this is a 512-bit operation
-    int vector_len = 2;
-    __ vpxor($dst$$XMMRegister,$dst$$XMMRegister, $dst$$XMMRegister, vector_len);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
 instruct Repl8D_zero_evex(vecZ dst, immD0 zero) %{
   predicate(n->as_Vector()->length() == 8 && UseAVX > 2);
   match(Set dst (ReplicateD zero));
--- a/src/hotspot/cpu/x86/x86_64.ad	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/cpu/x86/x86_64.ad	Thu Oct 10 10:57:42 2019 -0400
@@ -1058,8 +1058,8 @@
 static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
                           int src_hi, int dst_hi, uint ireg, outputStream* st);
 
-static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
-                            int stack_offset, int reg, uint ireg, outputStream* st);
+int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
+                     int stack_offset, int reg, uint ireg, outputStream* st);
 
 static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
                                       int dst_offset, uint ireg, outputStream* st) {
@@ -4260,200 +4260,6 @@
   %}
 %}
 
-// Operands for bound floating pointer register arguments
-operand rxmm0() %{
-  constraint(ALLOC_IN_RC(xmm0_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm1() %{
-  constraint(ALLOC_IN_RC(xmm1_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm2() %{
-  constraint(ALLOC_IN_RC(xmm2_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm3() %{
-  constraint(ALLOC_IN_RC(xmm3_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm4() %{
-  constraint(ALLOC_IN_RC(xmm4_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm5() %{
-  constraint(ALLOC_IN_RC(xmm5_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm6() %{
-  constraint(ALLOC_IN_RC(xmm6_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm7() %{
-  constraint(ALLOC_IN_RC(xmm7_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm8() %{
-  constraint(ALLOC_IN_RC(xmm8_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm9() %{
-  constraint(ALLOC_IN_RC(xmm9_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm10() %{
-  constraint(ALLOC_IN_RC(xmm10_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm11() %{
-  constraint(ALLOC_IN_RC(xmm11_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm12() %{
-  constraint(ALLOC_IN_RC(xmm12_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm13() %{
-  constraint(ALLOC_IN_RC(xmm13_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm14() %{
-  constraint(ALLOC_IN_RC(xmm14_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm15() %{
-  constraint(ALLOC_IN_RC(xmm15_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm16() %{
-  constraint(ALLOC_IN_RC(xmm16_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm17() %{
-  constraint(ALLOC_IN_RC(xmm17_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm18() %{
-  constraint(ALLOC_IN_RC(xmm18_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm19() %{
-  constraint(ALLOC_IN_RC(xmm19_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm20() %{
-  constraint(ALLOC_IN_RC(xmm20_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm21() %{
-  constraint(ALLOC_IN_RC(xmm21_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm22() %{
-  constraint(ALLOC_IN_RC(xmm22_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm23() %{
-  constraint(ALLOC_IN_RC(xmm23_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm24() %{
-  constraint(ALLOC_IN_RC(xmm24_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm25() %{
-  constraint(ALLOC_IN_RC(xmm25_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm26() %{
-  constraint(ALLOC_IN_RC(xmm26_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm27() %{
-  constraint(ALLOC_IN_RC(xmm27_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm28() %{
-  constraint(ALLOC_IN_RC(xmm28_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm29() %{
-  constraint(ALLOC_IN_RC(xmm29_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm30() %{
-  constraint(ALLOC_IN_RC(xmm30_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-operand rxmm31() %{
-  constraint(ALLOC_IN_RC(xmm31_reg));
-  match(VecX);
-  format%{%}
-  interface(REG_INTER);
-%}
-
 //----------OPERAND CLASSES----------------------------------------------------
 // Operand Classes are groups of operands that are used as to simplify
 // instruction definitions by not requiring the AD writer to specify separate
@@ -5346,6 +5152,7 @@
 instruct loadP(rRegP dst, memory mem)
 %{
   match(Set dst (LoadP mem));
+  predicate(n->as_Load()->barrier_data() == 0);
 
   ins_cost(125); // XXX
   format %{ "movq    $dst, $mem\t# ptr" %}
@@ -7794,6 +7601,7 @@
                            rax_RegP oldval, rRegP newval,
                            rFlagsReg cr)
 %{
+  predicate(n->as_LoadStore()->barrier_data() == 0);
   match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
 
   format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
@@ -7845,7 +7653,7 @@
                          rax_RegP oldval, rRegP newval,
                          rFlagsReg cr)
 %{
-  predicate(VM_Version::supports_cx8());
+  predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0);
   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
   match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
   effect(KILL cr, KILL oldval);
@@ -8087,7 +7895,7 @@
                          rax_RegP oldval, rRegP newval,
                          rFlagsReg cr)
 %{
-  predicate(VM_Version::supports_cx8());
+  predicate(VM_Version::supports_cx8() && n->as_LoadStore()->barrier_data() == 0);
   match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
   effect(KILL cr);
 
@@ -8232,6 +8040,7 @@
 
 instruct xchgP( memory mem, rRegP newval) %{
   match(Set newval (GetAndSetP mem newval));
+  predicate(n->as_LoadStore()->barrier_data() == 0);
   format %{ "XCHGQ  $newval,[$mem]" %}
   ins_encode %{
     __ xchgq($newval$$Register, $mem$$Address);
@@ -11974,6 +11783,7 @@
 instruct compP_rReg_mem(rFlagsRegU cr, rRegP op1, memory op2)
 %{
   match(Set cr (CmpP op1 (LoadP op2)));
+  predicate(n->in(2)->as_Load()->barrier_data() == 0);
 
   ins_cost(500); // XXX
   format %{ "cmpq    $op1, $op2\t# ptr" %}
@@ -11999,7 +11809,8 @@
 // and raw pointers have no anti-dependencies.
 instruct compP_mem_rReg(rFlagsRegU cr, rRegP op1, memory op2)
 %{
-  predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none);
+  predicate(n->in(2)->in(2)->bottom_type()->reloc() == relocInfo::none &&
+            n->in(2)->as_Load()->barrier_data() == 0);
   match(Set cr (CmpP op1 (LoadP op2)));
 
   format %{ "cmpq    $op1, $op2\t# raw ptr" %}
@@ -12024,7 +11835,8 @@
 // any compare to a zero should be eq/neq.
 instruct testP_mem(rFlagsReg cr, memory op, immP0 zero)
 %{
-  predicate(!UseCompressedOops || (CompressedOops::base() != NULL));
+  predicate((!UseCompressedOops || (CompressedOops::base() != NULL)) &&
+            n->in(1)->as_Load()->barrier_data() == 0);
   match(Set cr (CmpP (LoadP op) zero));
 
   ins_cost(500); // XXX
@@ -12037,7 +11849,9 @@
 
 instruct testP_mem_reg0(rFlagsReg cr, memory mem, immP0 zero)
 %{
-  predicate(UseCompressedOops && (CompressedOops::base() == NULL) && (CompressedKlassPointers::base() == NULL));
+  predicate(UseCompressedOops && (CompressedOops::base() == NULL) &&
+            (CompressedKlassPointers::base() == NULL) &&
+            n->in(1)->as_Load()->barrier_data() == 0);
   match(Set cr (CmpP (LoadP mem) zero));
 
   format %{ "cmpq    R12, $mem\t# ptr (R12_heapbase==0)" %}
--- a/src/hotspot/os/aix/os_aix.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/os/aix/os_aix.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -132,18 +132,6 @@
 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
 
 // excerpts from systemcfg.h that might be missing on older os levels
-#ifndef PV_5_Compat
-  #define PV_5_Compat 0x0F8000   /* Power PC 5 */
-#endif
-#ifndef PV_6
-  #define PV_6 0x100000          /* Power PC 6 */
-#endif
-#ifndef PV_6_1
-  #define PV_6_1 0x100001        /* Power PC 6 DD1.x */
-#endif
-#ifndef PV_6_Compat
-  #define PV_6_Compat 0x108000   /* Power PC 6 */
-#endif
 #ifndef PV_7
   #define PV_7 0x200000          /* Power PC 7 */
 #endif
@@ -156,6 +144,13 @@
 #ifndef PV_8_Compat
   #define PV_8_Compat 0x308000   /* Power PC 8 */
 #endif
+#ifndef PV_9
+  #define PV_9 0x400000          /* Power PC 9 */
+#endif
+#ifndef PV_9_Compat
+  #define PV_9_Compat  0x408000  /* Power PC 9 */
+#endif
+
 
 static address resolve_function_descriptor_to_code_pointer(address p);
 
@@ -1386,15 +1381,7 @@
 void os::print_os_info(outputStream* st) {
   st->print("OS:");
 
-  st->print("uname:");
-  struct utsname name;
-  uname(&name);
-  st->print(name.sysname); st->print(" ");
-  st->print(name.nodename); st->print(" ");
-  st->print(name.release); st->print(" ");
-  st->print(name.version); st->print(" ");
-  st->print(name.machine);
-  st->cr();
+  os::Posix::print_uname_info(st);
 
   uint32_t ver = os::Aix::os_version();
   st->print_cr("AIX kernel version %u.%u.%u.%u",
@@ -1402,16 +1389,12 @@
 
   os::Posix::print_rlimit_info(st);
 
+  os::Posix::print_load_average(st);
+
   // _SC_THREAD_THREADS_MAX is the maximum number of threads within a process.
   long tmax = sysconf(_SC_THREAD_THREADS_MAX);
   st->print_cr("maximum #threads within a process:%ld", tmax);
 
-  // load average
-  st->print("load average:");
-  double loadavg[3] = {-1.L, -1.L, -1.L};
-  os::loadavg(loadavg, 3);
-  st->print_cr("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
-
   // print wpar info
   libperfstat::wparinfo_t wi;
   if (libperfstat::get_wparinfo(&wi)) {
@@ -1504,6 +1487,9 @@
 void os::get_summary_cpu_info(char* buf, size_t buflen) {
   // read _system_configuration.version
   switch (_system_configuration.version) {
+  case PV_9:
+    strncpy(buf, "Power PC 9", buflen);
+    break;
   case PV_8:
     strncpy(buf, "Power PC 8", buflen);
     break;
@@ -1537,6 +1523,9 @@
   case PV_8_Compat:
     strncpy(buf, "PV_8_Compat", buflen);
     break;
+  case PV_9_Compat:
+    strncpy(buf, "PV_9_Compat", buflen);
+    break;
   default:
     strncpy(buf, "unknown", buflen);
   }
--- a/src/hotspot/os/posix/gc/z/zVirtualMemory_posix.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/os/posix/gc/z/zVirtualMemory_posix.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -43,7 +43,7 @@
 
   if ((uintptr_t)res != start) {
     // Failed to reserve memory at the requested address
-    unmap(start, size);
+    unmap((uintptr_t)res, size);
     return false;
   }
 
--- a/src/hotspot/os/posix/os_posix.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/os/posix/os_posix.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -373,8 +373,12 @@
 void os::Posix::print_load_average(outputStream* st) {
   st->print("load average:");
   double loadavg[3];
-  os::loadavg(loadavg, 3);
-  st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
+  int res = os::loadavg(loadavg, 3);
+  if (res != -1) {
+    st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
+  } else {
+    st->print(" Unavailable");
+  }
   st->cr();
 }
 
--- a/src/hotspot/os/windows/os_windows.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/os/windows/os_windows.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -4189,8 +4189,6 @@
     if (::isalpha(buf[0]) && !::IsDBCSLeadByte(buf[0]) && buf[1] == ':' && buf[2] == '\\') {
       prefix = L"\\\\?\\";
     } else if (buf[0] == '\\' && buf[1] == '\\') {
-      assert(buf[2] != '\\');
-
       if (buf[2] == '?' && buf[3] == '\\') {
         prefix = L"";
         needs_fullpath = false;
--- a/src/hotspot/share/adlc/formssel.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/adlc/formssel.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -773,11 +773,6 @@
        !strcmp(_matrule->_rChild->_opType,"CheckCastPP")  ||
        !strcmp(_matrule->_rChild->_opType,"GetAndSetP")   ||
        !strcmp(_matrule->_rChild->_opType,"GetAndSetN")   ||
-#if INCLUDE_ZGC
-       !strcmp(_matrule->_rChild->_opType,"ZGetAndSetP") ||
-       !strcmp(_matrule->_rChild->_opType,"ZCompareAndExchangeP") ||
-       !strcmp(_matrule->_rChild->_opType,"LoadBarrierSlowReg") ||
-#endif
 #if INCLUDE_SHENANDOAHGC
        !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeP") ||
        !strcmp(_matrule->_rChild->_opType,"ShenandoahCompareAndExchangeN") ||
@@ -3510,9 +3505,6 @@
     "StoreCM",
     "GetAndSetB", "GetAndSetS", "GetAndAddI", "GetAndSetI", "GetAndSetP",
     "GetAndAddB", "GetAndAddS", "GetAndAddL", "GetAndSetL", "GetAndSetN",
-#if INCLUDE_ZGC
-    "ZGetAndSetP", "ZCompareAndSwapP", "ZCompareAndExchangeP", "ZWeakCompareAndSwapP",
-#endif
     "ClearArray"
   };
   int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
--- a/src/hotspot/share/aot/aotCodeHeap.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/aot/aotCodeHeap.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -37,6 +37,7 @@
 #include "memory/allocation.inline.hpp"
 #include "memory/universe.hpp"
 #include "oops/compressedOops.hpp"
+#include "oops/klass.inline.hpp"
 #include "oops/method.inline.hpp"
 #include "runtime/deoptimization.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/aot/aotCompiledMethod.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/aot/aotCompiledMethod.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -32,6 +32,7 @@
 #include "compiler/compilerOracle.hpp"
 #include "gc/shared/cardTableBarrierSet.hpp"
 #include "gc/shared/collectedHeap.hpp"
+#include "oops/klass.inline.hpp"
 #include "oops/method.inline.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/c1/c1_LIRGenerator.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/c1/c1_LIRGenerator.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -36,6 +36,7 @@
 #include "ci/ciUtilities.hpp"
 #include "gc/shared/barrierSet.hpp"
 #include "gc/shared/c1/barrierSetC1.hpp"
+#include "oops/klass.inline.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubRoutines.hpp"
--- a/src/hotspot/share/ci/ciEnv.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/ci/ciEnv.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -238,6 +238,7 @@
   _jvmti_can_access_local_variables     = JvmtiExport::can_access_local_variables();
   _jvmti_can_post_on_exceptions         = JvmtiExport::can_post_on_exceptions();
   _jvmti_can_pop_frame                  = JvmtiExport::can_pop_frame();
+  _jvmti_can_get_owned_monitor_info     = JvmtiExport::can_get_owned_monitor_info();
 }
 
 bool ciEnv::jvmti_state_changed() const {
@@ -262,6 +263,10 @@
       JvmtiExport::can_pop_frame()) {
     return true;
   }
+  if (!_jvmti_can_get_owned_monitor_info &&
+      JvmtiExport::can_get_owned_monitor_info()) {
+    return true;
+  }
 
   return false;
 }
--- a/src/hotspot/share/ci/ciEnv.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/ci/ciEnv.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -73,6 +73,7 @@
   bool  _jvmti_can_access_local_variables;
   bool  _jvmti_can_post_on_exceptions;
   bool  _jvmti_can_pop_frame;
+  bool  _jvmti_can_get_owned_monitor_info; // includes can_get_owned_monitor_stack_depth_info
 
   // Cache DTrace flags
   bool  _dtrace_extended_probes;
@@ -347,6 +348,7 @@
   }
   bool  jvmti_can_hotswap_or_post_breakpoint() const { return _jvmti_can_hotswap_or_post_breakpoint; }
   bool  jvmti_can_post_on_exceptions()         const { return _jvmti_can_post_on_exceptions; }
+  bool  jvmti_can_get_owned_monitor_info()     const { return _jvmti_can_get_owned_monitor_info; }
 
   // Cache DTrace flags
   void  cache_dtrace_flags();
--- a/src/hotspot/share/classfile/classFileParser.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -3004,7 +3004,7 @@
   // We temporarily use the vtable_index field in the Method* to store the
   // class file index, so we can read in after calling qsort.
   // Put the method ordering in the shared archive.
-  if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) {
+  if (JvmtiExport::can_maintain_original_method_order() || Arguments::is_dumping_archive()) {
     for (int index = 0; index < length; index++) {
       Method* const m = methods->at(index);
       assert(!m->valid_vtable_index(), "vtable index should not be set");
@@ -3018,7 +3018,7 @@
   intArray* method_ordering = NULL;
   // If JVMTI original method ordering or sharing is enabled construct int
   // array remembering the original ordering
-  if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) {
+  if (JvmtiExport::can_maintain_original_method_order() || Arguments::is_dumping_archive()) {
     method_ordering = new intArray(length, length, -1);
     for (int index = 0; index < length; index++) {
       Method* const m = methods->at(index);
--- a/src/hotspot/share/classfile/classLoader.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/classLoader.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -462,7 +462,7 @@
 
 #if INCLUDE_CDS
 void ClassLoader::exit_with_path_failure(const char* error, const char* message) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "only called at dump time");
+  Arguments::assert_is_dumping_archive();
   tty->print_cr("Hint: enable -Xlog:class+path=info to diagnose the failure");
   vm_exit_during_initialization(error, message);
 }
@@ -532,7 +532,7 @@
 
 #if INCLUDE_CDS
 void ClassLoader::setup_app_search_path(const char *class_path) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity");
+  Arguments::assert_is_dumping_archive();
 
   ResourceMark rm;
   ClasspathStream cp_stream(class_path);
@@ -546,7 +546,7 @@
 void ClassLoader::add_to_module_path_entries(const char* path,
                                              ClassPathEntry* entry) {
   assert(entry != NULL, "ClassPathEntry should not be NULL");
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
+  Arguments::assert_is_dumping_archive();
 
   // The entry does not exist, add to the list
   if (_module_path_entries == NULL) {
@@ -560,7 +560,7 @@
 
 // Add a module path to the _module_path_entries list.
 void ClassLoader::update_module_path_entry_list(const char *path, TRAPS) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
+  Arguments::assert_is_dumping_archive();
   struct stat st;
   if (os::stat(path, &st) != 0) {
     tty->print_cr("os::stat error %d (%s). CDS dump aborted (path was \"%s\").",
@@ -656,7 +656,7 @@
   bool set_base_piece = true;
 
 #if INCLUDE_CDS
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+  if (Arguments::is_dumping_archive()) {
     if (!Arguments::has_jimage()) {
       vm_exit_during_initialization("CDS is not supported in exploded JDK build", NULL);
     }
@@ -1360,7 +1360,7 @@
 // Record the shared classpath index and loader type for classes loaded
 // by the builtin loaders at dump time.
 void ClassLoader::record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "sanity");
+  Arguments::assert_is_dumping_archive();
   assert(stream != NULL, "sanity");
 
   if (ik->is_unsafe_anonymous()) {
@@ -1537,13 +1537,13 @@
 
 #if INCLUDE_CDS
 void ClassLoader::initialize_shared_path() {
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+  if (Arguments::is_dumping_archive()) {
     ClassLoaderExt::setup_search_paths();
   }
 }
 
 void ClassLoader::initialize_module_path(TRAPS) {
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+  if (Arguments::is_dumping_archive()) {
     ClassLoaderExt::setup_module_paths(THREAD);
     FileMapInfo::allocate_shared_path_table();
   }
--- a/src/hotspot/share/classfile/classLoader.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/classLoader.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -26,6 +26,7 @@
 #define SHARE_CLASSFILE_CLASSLOADER_HPP
 
 #include "jimage.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/handles.hpp"
 #include "runtime/perfData.hpp"
 #include "utilities/exceptions.hpp"
@@ -236,6 +237,8 @@
   CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;})
   CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;})
 
+  static bool has_bootclasspath_append() { return _first_append_entry != NULL; }
+
  protected:
   // Initialization:
   //   - setup the boot loader's system class path
@@ -395,8 +398,7 @@
   // Helper function used by CDS code to get the number of module path
   // entries during shared classpath setup time.
   static int num_module_path_entries() {
-    assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
-           "Should only be called at CDS dump time");
+    Arguments::assert_is_dumping_archive();
     int num_entries = 0;
     ClassPathEntry* e= ClassLoader::_module_path_entries;
     while (e != NULL) {
--- a/src/hotspot/share/classfile/classLoader.inline.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/classLoader.inline.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -62,8 +62,7 @@
 // entries during shared classpath setup time.
 
 inline int ClassLoader::num_boot_classpath_entries() {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
-         "Should only be called at CDS dump time");
+  Arguments::assert_is_dumping_archive();
   assert(has_jrt_entry(), "must have a java runtime image");
   int num_entries = 1; // count the runtime image
   ClassPathEntry* e = ClassLoader::_first_append_entry;
@@ -85,8 +84,7 @@
 // Helper function used by CDS code to get the number of app classpath
 // entries during shared classpath setup time.
 inline int ClassLoader::num_app_classpath_entries() {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
-         "Should only be called at CDS dump time");
+  Arguments::assert_is_dumping_archive();
   int num_entries = 0;
   ClassPathEntry* e= ClassLoader::_app_classpath_entries;
   while (e != NULL) {
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -62,8 +62,7 @@
 }
 
 void ClassLoaderExt::setup_app_search_path() {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
-         "this function is only used at CDS dump time");
+  Arguments::assert_is_dumping_archive();
   _app_class_paths_start_index = ClassLoader::num_boot_classpath_entries();
   char* app_class_path = os::strdup(Arguments::get_appclasspath());
 
@@ -92,8 +91,7 @@
   }
 }
 void ClassLoaderExt::setup_module_paths(TRAPS) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
-         "this function is only used with CDS dump time");
+  Arguments::assert_is_dumping_archive();
   _app_module_paths_start_index = ClassLoader::num_boot_classpath_entries() +
                               ClassLoader::num_app_classpath_entries();
   Handle system_class_loader (THREAD, SystemDictionary::java_system_loader());
@@ -231,7 +229,7 @@
 void ClassLoaderExt::record_result(const s2 classpath_index,
                                    InstanceKlass* result,
                                    TRAPS) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity");
+  Arguments::assert_is_dumping_archive();
 
   // We need to remember where the class comes from during dumping.
   oop loader = result->class_loader();
--- a/src/hotspot/share/classfile/compactHashtable.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/compactHashtable.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -42,7 +42,7 @@
 //
 CompactHashtableWriter::CompactHashtableWriter(int num_entries,
                                                CompactHashtableStats* stats) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump-time only");
+  Arguments::assert_is_dumping_archive();
   assert(num_entries >= 0, "sanity");
   _num_buckets = calculate_num_buckets(num_entries);
   assert(_num_buckets > 0, "no buckets");
--- a/src/hotspot/share/classfile/dictionary.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/dictionary.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -246,7 +246,7 @@
 
 // Used to scan and relocate the classes during CDS archive dump.
 void Dictionary::classes_do(MetaspaceClosure* it) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump-time only");
+  Arguments::assert_is_dumping_archive();
   for (int index = 0; index < table_size(); index++) {
     for (DictionaryEntry* probe = bucket(index);
                           probe != NULL;
--- a/src/hotspot/share/classfile/javaClasses.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -377,7 +377,7 @@
 
   if (_to_java_string_fn == NULL) {
     void *lib_handle = os::native_java_library();
-    _to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "NewStringPlatform"));
+    _to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "JNU_NewStringPlatform"));
     if (_to_java_string_fn == NULL) {
       fatal("NewStringPlatform missing");
     }
--- a/src/hotspot/share/classfile/javaClasses.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -202,7 +202,6 @@
 
   // Conversion between '.' and '/' formats
   static Handle externalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '/', '.', THREAD); }
-  static Handle internalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '.', '/', THREAD); }
 
   // Conversion
   static Symbol* as_symbol(oop java_string);
--- a/src/hotspot/share/classfile/klassFactory.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/klassFactory.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -218,7 +218,7 @@
   JFR_ONLY(ON_KLASS_CREATION(result, parser, THREAD);)
 
 #if INCLUDE_CDS
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+  if (Arguments::is_dumping_archive()) {
     ClassLoader::record_result(result, stream, THREAD);
   }
 #endif // INCLUDE_CDS
--- a/src/hotspot/share/classfile/symbolTable.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/symbolTable.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -220,7 +220,7 @@
   assert (len <= Symbol::max_length(), "should be checked by caller");
 
   Symbol* sym;
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+  if (Arguments::is_dumping_archive()) {
     c_heap = false;
   }
   if (c_heap) {
@@ -283,7 +283,7 @@
 };
 
 void SymbolTable::metaspace_pointers_do(MetaspaceClosure* it) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "called only during dump time");
+  Arguments::assert_is_dumping_archive();
   MetaspacePointersDo mpd(it);
   _local_table->do_safepoint_scan(mpd);
 }
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1205,10 +1205,8 @@
   TempNewSymbol pkg_name = NULL;
   PackageEntry* pkg_entry = NULL;
   ModuleEntry* mod_entry = NULL;
-  const char* pkg_string = NULL;
   pkg_name = InstanceKlass::package_from_name(class_name, CHECK_false);
   if (pkg_name != NULL) {
-    pkg_string = pkg_name->as_C_string();
     if (loader_data != NULL) {
       pkg_entry = loader_data->packages()->lookup_only(pkg_name);
     }
@@ -1245,7 +1243,7 @@
     // 3. or, the class is from an unamed module
     if (!ent->is_modules_image() && ik->is_shared_boot_class()) {
       // the class is from the -Xbootclasspath/a
-      if (pkg_string == NULL ||
+      if (pkg_name == NULL ||
           pkg_entry == NULL ||
           pkg_entry->in_unnamed_module()) {
         assert(mod_entry == NULL ||
@@ -1257,8 +1255,7 @@
     return false;
   } else {
     bool res = SystemDictionaryShared::is_shared_class_visible_for_classloader(
-              ik, class_loader, pkg_string, pkg_name,
-              pkg_entry, mod_entry, CHECK_(false));
+              ik, class_loader, pkg_name, pkg_entry, mod_entry, CHECK_(false));
     return res;
   }
 }
@@ -1432,6 +1429,11 @@
         // a named package within the unnamed module.  In all cases,
         // limit visibility to search for the class only in the boot
         // loader's append path.
+        if (!ClassLoader::has_bootclasspath_append()) {
+           // If there is no bootclasspath append entry, no need to continue
+           // searching.
+           return NULL;
+        }
         search_only_bootloader_append = true;
       }
     }
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -657,7 +657,6 @@
 bool SystemDictionaryShared::is_shared_class_visible_for_classloader(
                                                      InstanceKlass* ik,
                                                      Handle class_loader,
-                                                     const char* pkg_string,
                                                      Symbol* pkg_name,
                                                      PackageEntry* pkg_entry,
                                                      ModuleEntry* mod_entry,
@@ -684,7 +683,7 @@
     }
   } else if (SystemDictionary::is_system_class_loader(class_loader())) {
     assert(ent != NULL, "shared class for system loader should have valid SharedClassPathEntry");
-    if (pkg_string == NULL) {
+    if (pkg_name == NULL) {
       // The archived class is in the unnamed package. Currently, the boot image
       // does not contain any class in the unnamed package.
       assert(!ent->is_modules_image(), "Class in the unnamed package must be from the classpath");
@@ -1029,7 +1028,7 @@
 }
 
 void SystemDictionaryShared::set_shared_class_misc_info(InstanceKlass* k, ClassFileStream* cfs) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "only when dumping");
+  Arguments::assert_is_dumping_archive();
   assert(!is_builtin(k), "must be unregistered class");
   DumpTimeSharedClassInfo* info = find_or_allocate_info_for(k);
   info->_clsfile_size  = cfs->length();
@@ -1185,7 +1184,7 @@
 
 bool SystemDictionaryShared::is_excluded_class(InstanceKlass* k) {
   assert(_no_class_loading_should_happen, "sanity");
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "only when dumping");
+  Arguments::assert_is_dumping_archive();
   return find_or_allocate_info_for(k)->is_excluded();
 }
 
@@ -1209,7 +1208,7 @@
 
 bool SystemDictionaryShared::add_verification_constraint(InstanceKlass* k, Symbol* name,
          Symbol* from_name, bool from_field_is_protected, bool from_is_array, bool from_is_object) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "called at dump time only");
+  Arguments::assert_is_dumping_archive();
   DumpTimeSharedClassInfo* info = find_or_allocate_info_for(k);
   info->add_verification_constraint(k, name, from_name, from_field_is_protected,
                                     from_is_array, from_is_object);
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -240,7 +240,6 @@
   static bool is_sharing_possible(ClassLoaderData* loader_data);
   static bool is_shared_class_visible_for_classloader(InstanceKlass* ik,
                                                       Handle class_loader,
-                                                      const char* pkg_string,
                                                       Symbol* pkg_name,
                                                       PackageEntry* pkg_entry,
                                                       ModuleEntry* mod_entry,
--- a/src/hotspot/share/classfile/verificationType.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/verificationType.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -28,6 +28,7 @@
 #include "classfile/verificationType.hpp"
 #include "classfile/verifier.hpp"
 #include "logging/log.hpp"
+#include "oops/klass.inline.hpp"
 #include "runtime/handles.inline.hpp"
 
 VerificationType VerificationType::from_tag(u1 tag) {
@@ -94,7 +95,7 @@
       return true;
     }
 
-    if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+    if (Arguments::is_dumping_archive()) {
       if (SystemDictionaryShared::add_verification_constraint(klass,
               name(), from.name(), from_field_is_protected, from.is_array(),
               from.is_object())) {
--- a/src/hotspot/share/classfile/verifier.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/classfile/verifier.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -63,29 +63,39 @@
 #define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION       52
 #define MAX_ARRAY_DIMENSIONS 255
 
-// Access to external entry for VerifyClassCodes - old byte code verifier
+// Access to external entry for VerifyClassForMajorVersion - old byte code verifier
 
 extern "C" {
-  typedef jboolean (*verify_byte_codes_fn_t)(JNIEnv *, jclass, char *, jint);
-  typedef jboolean (*verify_byte_codes_fn_new_t)(JNIEnv *, jclass, char *, jint, jint);
+  typedef jboolean (*verify_byte_codes_fn_t)(JNIEnv *, jclass, char *, jint, jint);
 }
 
-static void* volatile _verify_byte_codes_fn = NULL;
+static verify_byte_codes_fn_t volatile _verify_byte_codes_fn = NULL;
+
+static verify_byte_codes_fn_t verify_byte_codes_fn() {
 
-static volatile jint _is_new_verify_byte_codes_fn = (jint) true;
+  if (_verify_byte_codes_fn != NULL)
+    return _verify_byte_codes_fn;
+
+  MutexLocker locker(Verify_lock);
+
+  if (_verify_byte_codes_fn != NULL)
+    return _verify_byte_codes_fn;
 
-static void* verify_byte_codes_fn() {
-  if (OrderAccess::load_acquire(&_verify_byte_codes_fn) == NULL) {
-    void *lib_handle = os::native_java_library();
-    void *func = os::dll_lookup(lib_handle, "VerifyClassCodesForMajorVersion");
-    OrderAccess::release_store(&_verify_byte_codes_fn, func);
-    if (func == NULL) {
-      _is_new_verify_byte_codes_fn = false;
-      func = os::dll_lookup(lib_handle, "VerifyClassCodes");
-      OrderAccess::release_store(&_verify_byte_codes_fn, func);
-    }
-  }
-  return (void*)_verify_byte_codes_fn;
+  // Load verify dll
+  char buffer[JVM_MAXPATHLEN];
+  char ebuf[1024];
+  if (!os::dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"))
+    return NULL; // Caller will throw VerifyError
+
+  void *lib_handle = os::dll_load(buffer, ebuf, sizeof(ebuf));
+  if (lib_handle == NULL)
+    return NULL; // Caller will throw VerifyError
+
+  void *fn = os::dll_lookup(lib_handle, "VerifyClassForMajorVersion");
+  if (fn == NULL)
+    return NULL; // Caller will throw VerifyError
+
+  return _verify_byte_codes_fn = CAST_TO_FN_PTR(verify_byte_codes_fn_t, fn);
 }
 
 
@@ -282,7 +292,7 @@
   JavaThread* thread = (JavaThread*)THREAD;
   JNIEnv *env = thread->jni_environment();
 
-  void* verify_func = verify_byte_codes_fn();
+  verify_byte_codes_fn_t verify_func = verify_byte_codes_fn();
 
   if (verify_func == NULL) {
     jio_snprintf(message, message_len, "Could not link verifier");
@@ -301,16 +311,7 @@
     // ThreadToNativeFromVM takes care of changing thread_state, so safepoint
     // code knows that we have left the VM
 
-    if (_is_new_verify_byte_codes_fn) {
-      verify_byte_codes_fn_new_t func =
-        CAST_TO_FN_PTR(verify_byte_codes_fn_new_t, verify_func);
-      result = (*func)(env, cls, message, (int)message_len,
-          klass->major_version());
-    } else {
-      verify_byte_codes_fn_t func =
-        CAST_TO_FN_PTR(verify_byte_codes_fn_t, verify_func);
-      result = (*func)(env, cls, message, (int)message_len);
-    }
+    result = (*verify_func)(env, cls, message, (int)message_len, klass->major_version());
   }
 
   JNIHandles::destroy_local(cls);
--- a/src/hotspot/share/code/compiledIC.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/code/compiledIC.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -741,4 +741,22 @@
   tty->cr();
 }
 
+void CompiledDirectStaticCall::verify_mt_safe(const methodHandle& callee, address entry,
+                                              NativeMovConstReg* method_holder,
+                                              NativeJump*        jump) {
+  // A generated lambda form might be deleted from the Lambdaform
+  // cache in MethodTypeForm.  If a jit compiled lambdaform method
+  // becomes not entrant and the cache access returns null, the new
+  // resolve will lead to a new generated LambdaForm.
+  Method* old_method = reinterpret_cast<Method*>(method_holder->data());
+  assert(old_method == NULL || old_method == callee() ||
+         callee->is_compiled_lambda_form() ||
+         !old_method->method_holder()->is_loader_alive() ||
+         old_method->is_old(),  // may be race patching deoptimized nmethod due to redefinition.
+         "a) MT-unsafe modification of inline cache");
+
+  address destination = jump->jump_destination();
+  assert(destination == (address)-1 || destination == entry,
+         "b) MT-unsafe modification of inline cache");
+}
 #endif // !PRODUCT
--- a/src/hotspot/share/code/compiledIC.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/code/compiledIC.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -402,6 +402,9 @@
 
   // Also used by CompiledIC
   void set_to_interpreted(const methodHandle& callee, address entry);
+  void verify_mt_safe(const methodHandle& callee, address entry,
+                      NativeMovConstReg* method_holder,
+                      NativeJump*        jump) PRODUCT_RETURN;
 #if INCLUDE_AOT
   void set_to_far(const methodHandle& callee, address entry);
 #endif
--- a/src/hotspot/share/compiler/compilerDirectives.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/compiler/compilerDirectives.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -66,8 +66,7 @@
     cflags(VectorizeDebug,          uintx, 0, VectorizeDebug) \
     cflags(CloneMapDebug,           bool, false, CloneMapDebug) \
     cflags(IGVPrintLevel,           intx, PrintIdealGraphLevel, IGVPrintLevel) \
-    cflags(MaxNodeLimit,            intx, MaxNodeLimit, MaxNodeLimit) \
-ZGC_ONLY(cflags(ZTraceLoadBarriers, bool, false, ZTraceLoadBarriers))
+    cflags(MaxNodeLimit,            intx, MaxNodeLimit, MaxNodeLimit)
 #else
   #define compilerdirectives_c2_flags(cflags)
 #endif
--- a/src/hotspot/share/compiler/oopMap.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/compiler/oopMap.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -48,29 +48,25 @@
 
 // OopMapStream
 
-OopMapStream::OopMapStream(OopMap* oop_map, int oop_types_mask) {
+OopMapStream::OopMapStream(OopMap* oop_map) {
   _stream = new CompressedReadStream(oop_map->write_stream()->buffer());
-  _mask = oop_types_mask;
   _size = oop_map->omv_count();
   _position = 0;
   _valid_omv = false;
 }
 
-OopMapStream::OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask) {
+OopMapStream::OopMapStream(const ImmutableOopMap* oop_map) {
   _stream = new CompressedReadStream(oop_map->data_addr());
-  _mask = oop_types_mask;
   _size = oop_map->count();
   _position = 0;
   _valid_omv = false;
 }
 
 void OopMapStream::find_next() {
-  while(_position++ < _size) {
+  if (_position++ < _size) {
     _omv.read_from(_stream);
-    if(((int)_omv.type() & _mask) > 0) {
-      _valid_omv = true;
-      return;
-    }
+    _valid_omv = true;
+    return;
   }
   _valid_omv = false;
 }
@@ -140,16 +136,7 @@
   assert( _locs_used[reg->value()] == OopMapValue::unused_value, "cannot insert twice" );
   debug_only( _locs_used[reg->value()] = x; )
 
-  OopMapValue o(reg, x);
-
-  if(x == OopMapValue::callee_saved_value) {
-    // This can never be a stack location, so we don't need to transform it.
-    assert(optional->is_reg(), "Trying to callee save a stack location");
-    o.set_content_reg(optional);
-  } else if(x == OopMapValue::derived_oop_value) {
-    o.set_content_reg(optional);
-  }
-
+  OopMapValue o(reg, x, optional);
   o.write_on(write_stream());
   increment_count();
 }
@@ -160,11 +147,6 @@
 }
 
 
-void OopMap::set_value(VMReg reg) {
-  // At this time, we don't need value entries in our OopMap.
-}
-
-
 void OopMap::set_narrowoop(VMReg reg) {
   set_xxx(reg, OopMapValue::narrowoop_value, VMRegImpl::Bad());
 }
@@ -328,7 +310,7 @@
   // changed before derived pointer offset has been collected)
   OopMapValue omv;
   {
-    OopMapStream oms(map,OopMapValue::derived_oop_value);
+    OopMapStream oms(map);
     if (!oms.is_done()) {
 #ifndef TIERED
       COMPILER1_PRESENT(ShouldNotReachHere();)
@@ -340,27 +322,28 @@
 #endif // !TIERED
       do {
         omv = oms.current();
-        oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
-        guarantee(loc != NULL, "missing saved register");
-        oop *derived_loc = loc;
-        oop *base_loc    = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
-        // Ignore NULL oops and decoded NULL narrow oops which
-        // equal to CompressedOops::base() when a narrow oop
-        // implicit null check is used in compiled code.
-        // The narrow_oop_base could be NULL or be the address
-        // of the page below heap depending on compressed oops mode.
-        if (base_loc != NULL && *base_loc != NULL && !CompressedOops::is_base(*base_loc)) {
-          derived_oop_fn(base_loc, derived_loc);
+        if (omv.type() == OopMapValue::derived_oop_value) {
+          oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
+          guarantee(loc != NULL, "missing saved register");
+          oop *derived_loc = loc;
+          oop *base_loc    = fr->oopmapreg_to_location(omv.content_reg(), reg_map);
+          // Ignore NULL oops and decoded NULL narrow oops which
+          // equal to CompressedOops::base() when a narrow oop
+          // implicit null check is used in compiled code.
+          // The narrow_oop_base could be NULL or be the address
+          // of the page below heap depending on compressed oops mode.
+          if (base_loc != NULL && *base_loc != NULL && !CompressedOops::is_base(*base_loc)) {
+            derived_oop_fn(base_loc, derived_loc);
+          }
         }
         oms.next();
       }  while (!oms.is_done());
     }
   }
 
-  // We want coop and oop oop_types
-  int mask = OopMapValue::oop_value | OopMapValue::narrowoop_value;
   {
-    for (OopMapStream oms(map,mask); !oms.is_done(); oms.next()) {
+    // We want coop and oop oop_types
+    for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
       omv = oms.current();
       oop* loc = fr->oopmapreg_to_location(omv.reg(),reg_map);
       // It should be an error if no location can be found for a
@@ -436,12 +419,14 @@
   assert(map != NULL, "no ptr map found");
   DEBUG_ONLY(int nof_callee = 0;)
 
-  for (OopMapStream oms(map, OopMapValue::callee_saved_value); !oms.is_done(); oms.next()) {
+  for (OopMapStream oms(map); !oms.is_done(); oms.next()) {
     OopMapValue omv = oms.current();
-    VMReg reg = omv.content_reg();
-    oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
-    reg_map->set_location(reg, (address) loc);
-    DEBUG_ONLY(nof_callee++;)
+    if (omv.type() == OopMapValue::callee_saved_value) {
+      VMReg reg = omv.content_reg();
+      oop* loc = fr->oopmapreg_to_location(omv.reg(), reg_map);
+      reg_map->set_location(reg, (address) loc);
+      DEBUG_ONLY(nof_callee++;)
+    }
   }
 
   // Check that runtime stubs save all callee-saved registers
@@ -452,25 +437,6 @@
 #endif // COMPILER2
 }
 
-//=============================================================================
-// Non-Product code
-
-#ifndef PRODUCT
-
-bool ImmutableOopMap::has_derived_pointer() const {
-#if !defined(TIERED) && !INCLUDE_JVMCI
-  COMPILER1_PRESENT(return false);
-#endif // !TIERED
-#if COMPILER2_OR_JVMCI
-  OopMapStream oms(this,OopMapValue::derived_oop_value);
-  return oms.is_done();
-#else
-  return false;
-#endif // COMPILER2_OR_JVMCI
-}
-
-#endif //PRODUCT
-
 // Printing code is present in product build for -XX:+PrintAssembly.
 
 static
--- a/src/hotspot/share/compiler/oopMap.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/compiler/oopMap.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -53,7 +53,7 @@
 
 public:
   // Constants
-  enum { type_bits                = 4,
+  enum { type_bits                = 2,
          register_bits            = BitsPerShort - type_bits };
 
   enum { type_shift               = 0,
@@ -64,19 +64,41 @@
          register_mask            = right_n_bits(register_bits),
          register_mask_in_place   = register_mask << register_shift };
 
-  enum oop_types {              // must fit in type_bits
-         unused_value =0,       // powers of 2, for masking OopMapStream
-         oop_value = 1,
-         narrowoop_value = 2,
-         callee_saved_value = 4,
-         derived_oop_value= 8 };
+  enum oop_types {
+         oop_value,
+         narrowoop_value,
+         callee_saved_value,
+         derived_oop_value,
+         unused_value = -1          // Only used as a sentinel value
+  };
 
   // Constructors
   OopMapValue () { set_value(0); set_content_reg(VMRegImpl::Bad()); }
-  OopMapValue (VMReg reg, oop_types t) { set_reg_type(reg, t); set_content_reg(VMRegImpl::Bad()); }
-  OopMapValue (VMReg reg, oop_types t, VMReg reg2) { set_reg_type(reg, t); set_content_reg(reg2); }
-  OopMapValue (CompressedReadStream* stream) { read_from(stream); }
+  OopMapValue (VMReg reg, oop_types t, VMReg reg2) {
+    set_reg_type(reg, t);
+    set_content_reg(reg2);
+  }
+
+ private:
+    void set_reg_type(VMReg p, oop_types t) {
+    set_value((p->value() << register_shift) | t);
+    assert(reg() == p, "sanity check" );
+    assert(type() == t, "sanity check" );
+  }
 
+  void set_content_reg(VMReg r) {
+    if (is_callee_saved()) {
+      // This can never be a stack location, so we don't need to transform it.
+      assert(r->is_reg(), "Trying to callee save a stack location");
+    } else if (is_derived_oop()) {
+      assert (r->is_valid(), "must have a valid VMReg");
+    } else {
+      assert (!r->is_valid(), "valid VMReg not allowed");
+    }
+    _content_reg = r->value();
+  }
+
+ public:
   // Archiving
   void write_on(CompressedWriteStream* stream) {
     stream->write_int(value());
@@ -94,15 +116,10 @@
 
   // Querying
   bool is_oop()               { return mask_bits(value(), type_mask_in_place) == oop_value; }
-  bool is_narrowoop()           { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
+  bool is_narrowoop()         { return mask_bits(value(), type_mask_in_place) == narrowoop_value; }
   bool is_callee_saved()      { return mask_bits(value(), type_mask_in_place) == callee_saved_value; }
   bool is_derived_oop()       { return mask_bits(value(), type_mask_in_place) == derived_oop_value; }
 
-  void set_oop()              { set_value((value() & register_mask_in_place) | oop_value); }
-  void set_narrowoop()          { set_value((value() & register_mask_in_place) | narrowoop_value); }
-  void set_callee_saved()     { set_value((value() & register_mask_in_place) | callee_saved_value); }
-  void set_derived_oop()      { set_value((value() & register_mask_in_place) | derived_oop_value); }
-
   VMReg reg() const { return VMRegImpl::as_VMReg(mask_bits(value(), register_mask_in_place) >> register_shift); }
   oop_types type() const      { return (oop_types)mask_bits(value(), type_mask_in_place); }
 
@@ -110,15 +127,7 @@
     return (p->value()  == (p->value() & register_mask));
   }
 
-  void set_reg_type(VMReg p, oop_types t) {
-    set_value((p->value() << register_shift) | t);
-    assert(reg() == p, "sanity check" );
-    assert(type() == t, "sanity check" );
-  }
-
-
   VMReg content_reg() const       { return VMRegImpl::as_VMReg(_content_reg, true); }
-  void set_content_reg(VMReg r)   { _content_reg = r->value(); }
 
   // Physical location queries
   bool is_register_loc()      { return reg()->is_reg(); }
@@ -156,6 +165,8 @@
   enum DeepCopyToken { _deep_copy_token };
   OopMap(DeepCopyToken, OopMap* source);  // used only by deep_copy
 
+  void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
+
  public:
   OopMap(int frame_size, int arg_count);
 
@@ -173,19 +184,14 @@
   // frame_size units are stack-slots (4 bytes) NOT intptr_t; we can name odd
   // slots to hold 4-byte values like ints and floats in the LP64 build.
   void set_oop  ( VMReg local);
-  void set_value( VMReg local);
   void set_narrowoop(VMReg local);
-  void set_dead ( VMReg local);
   void set_callee_saved( VMReg local, VMReg caller_machine_register );
   void set_derived_oop ( VMReg local, VMReg derived_from_local_register );
-  void set_xxx(VMReg reg, OopMapValue::oop_types x, VMReg optional);
 
   int heap_size() const;
   void copy_data_to(address addr) const;
   OopMap* deep_copy();
 
-  bool has_derived_pointer() const PRODUCT_RETURN0;
-
   bool legal_vm_reg_name(VMReg local) {
      return OopMapValue::legal_vm_reg_name(local);
   }
@@ -269,7 +275,6 @@
 public:
   ImmutableOopMap(const OopMap* oopmap);
 
-  bool has_derived_pointer() const PRODUCT_RETURN0;
   int count() const { return _count; }
 #ifdef ASSERT
   int nr_of_bytes() const; // this is an expensive operation, only used in debug builds
@@ -334,7 +339,6 @@
 class OopMapStream : public StackObj {
  private:
   CompressedReadStream* _stream;
-  int _mask;
   int _size;
   int _position;
   bool _valid_omv;
@@ -342,8 +346,8 @@
   void find_next();
 
  public:
-  OopMapStream(OopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
-  OopMapStream(const ImmutableOopMap* oop_map, int oop_types_mask = OopMapValue::type_mask_in_place);
+  OopMapStream(OopMap* oop_map);
+  OopMapStream(const ImmutableOopMap* oop_map);
   bool is_done()                        { if(!_valid_omv) { find_next(); } return !_valid_omv; }
   void next()                           { find_next(); }
   OopMapValue current()                 { return _omv; }
--- a/src/hotspot/share/gc/g1/g1Analytics.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1Analytics.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -78,6 +78,8 @@
     _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
     _prev_collection_pause_end_ms(0.0),
     _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _concurrent_refine_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
+    _logged_cards_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
     _cost_per_logged_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
     _cost_scan_hcc_seq(new TruncatedSeq(TruncatedSeqLength)),
     _young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
@@ -102,6 +104,10 @@
   int index = MIN2(ParallelGCThreads - 1, 7u);
 
   _rs_length_diff_seq->add(rs_length_diff_defaults[index]);
+  // Start with inverse of maximum STW cost.
+  _concurrent_refine_rate_ms_seq->add(1/cost_per_logged_card_ms_defaults[0]);
+  // Some applications have very low rates for logging cards.
+  _logged_cards_rate_ms_seq->add(0.0);
   _cost_per_logged_card_ms_seq->add(cost_per_logged_card_ms_defaults[index]);
   _cost_scan_hcc_seq->add(0.0);
   _young_cards_per_entry_ratio_seq->add(young_cards_per_entry_ratio_defaults[index]);
@@ -159,6 +165,14 @@
     (pause_time_ms * _recent_prev_end_times_for_all_gcs_sec->num()) / interval_ms;
 }
 
+void G1Analytics::report_concurrent_refine_rate_ms(double cards_per_ms) {
+  _concurrent_refine_rate_ms_seq->add(cards_per_ms);
+}
+
+void G1Analytics::report_logged_cards_rate_ms(double cards_per_ms) {
+  _logged_cards_rate_ms_seq->add(cards_per_ms);
+}
+
 void G1Analytics::report_cost_per_logged_card_ms(double cost_per_logged_card_ms) {
   _cost_per_logged_card_ms_seq->add(cost_per_logged_card_ms);
 }
@@ -223,6 +237,14 @@
   return get_new_prediction(_alloc_rate_ms_seq);
 }
 
+double G1Analytics::predict_concurrent_refine_rate_ms() const {
+  return get_new_prediction(_concurrent_refine_rate_ms_seq);
+}
+
+double G1Analytics::predict_logged_cards_rate_ms() const {
+  return get_new_prediction(_logged_cards_rate_ms_seq);
+}
+
 double G1Analytics::predict_cost_per_logged_card_ms() const {
   return get_new_prediction(_cost_per_logged_card_ms_seq);
 }
--- a/src/hotspot/share/gc/g1/g1Analytics.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1Analytics.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -46,6 +46,8 @@
   double        _prev_collection_pause_end_ms;
 
   TruncatedSeq* _rs_length_diff_seq;
+  TruncatedSeq* _concurrent_refine_rate_ms_seq;
+  TruncatedSeq* _logged_cards_rate_ms_seq;
   TruncatedSeq* _cost_per_logged_card_ms_seq;
   TruncatedSeq* _cost_scan_hcc_seq;
   TruncatedSeq* _young_cards_per_entry_ratio_seq;
@@ -99,6 +101,8 @@
   void report_concurrent_mark_remark_times_ms(double ms);
   void report_concurrent_mark_cleanup_times_ms(double ms);
   void report_alloc_rate_ms(double alloc_rate);
+  void report_concurrent_refine_rate_ms(double cards_per_ms);
+  void report_logged_cards_rate_ms(double cards_per_ms);
   void report_cost_per_logged_card_ms(double cost_per_logged_card_ms);
   void report_cost_scan_hcc(double cost_scan_hcc);
   void report_cost_per_remset_card_ms(double cost_per_remset_card_ms, bool for_young_gc);
@@ -116,6 +120,8 @@
   double predict_alloc_rate_ms() const;
   int num_alloc_rate_ms() const;
 
+  double predict_concurrent_refine_rate_ms() const;
+  double predict_logged_cards_rate_ms() const;
   double predict_cost_per_logged_card_ms() const;
 
   double predict_scan_hcc_ms() const;
--- a/src/hotspot/share/gc/g1/g1CollectionSet.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1CollectionSet.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -409,7 +409,7 @@
   guarantee(target_pause_time_ms > 0.0,
             "target_pause_time_ms = %1.6lf should be positive", target_pause_time_ms);
 
-  size_t pending_cards = _policy->pending_cards();
+  size_t pending_cards = _policy->pending_cards_at_gc_start();
   double base_time_ms = _policy->predict_base_elapsed_time_ms(pending_cards);
   double time_remaining_ms = MAX2(target_pause_time_ms - base_time_ms, 0.0);
 
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -412,6 +412,22 @@
   dcqs.notify_if_necessary();
 }
 
+G1ConcurrentRefine::RefinementStats G1ConcurrentRefine::total_refinement_stats() const {
+  struct CollectData : public ThreadClosure {
+    Tickspan _total_time;
+    size_t _total_cards;
+    CollectData() : _total_time(), _total_cards(0) {}
+    virtual void do_thread(Thread* t) {
+      G1ConcurrentRefineThread* crt = static_cast<G1ConcurrentRefineThread*>(t);
+      _total_time += crt->total_refinement_time();
+      _total_cards += crt->total_refined_cards();
+    }
+  } collector;
+  // Cast away const so we can call non-modifying closure on threads.
+  const_cast<G1ConcurrentRefine*>(this)->threads_do(&collector);
+  return RefinementStats(collector._total_time, collector._total_cards);
+}
+
 size_t G1ConcurrentRefine::activation_threshold(uint worker_id) const {
   Thresholds thresholds = calc_thresholds(_green_zone, _yellow_zone, worker_id);
   return activation_level(thresholds);
@@ -432,7 +448,8 @@
   }
 }
 
-bool G1ConcurrentRefine::do_refinement_step(uint worker_id) {
+bool G1ConcurrentRefine::do_refinement_step(uint worker_id,
+                                            size_t* total_refined_cards) {
   G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
 
   size_t curr_cards = dcqs.num_cards();
@@ -448,5 +465,6 @@
 
   // Process the next buffer, if there are enough left.
   return dcqs.refine_completed_buffer_concurrently(worker_id + worker_id_offset(),
-                                                   deactivation_threshold(worker_id));
+                                                   deactivation_threshold(worker_id),
+                                                   total_refined_cards);
 }
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -27,6 +27,7 @@
 
 #include "memory/allocation.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/ticks.hpp"
 
 // Forward decl
 class G1ConcurrentRefine;
@@ -118,11 +119,22 @@
   // Adjust refinement thresholds based on work done during the pause and the goal time.
   void adjust(double logged_cards_scan_time, size_t processed_logged_cards, double goal_ms);
 
+  struct RefinementStats {
+    Tickspan _time;
+    size_t _cards;
+    RefinementStats(Tickspan time, size_t cards) : _time(time), _cards(cards) {}
+  };
+
+  RefinementStats total_refinement_stats() const;
+
   // Cards in the dirty card queue set.
   size_t activation_threshold(uint worker_id) const;
   size_t deactivation_threshold(uint worker_id) const;
-  // Perform a single refinement step. Called by the refinement threads when woken up.
-  bool do_refinement_step(uint worker_id);
+
+  // Perform a single refinement step; called by the refinement
+  // threads.  Returns true if there was refinement work available.
+  // Increments *total_refined_cards.
+  bool do_refinement_step(uint worker_id, size_t* total_refined_cards);
 
   // Iterate over all concurrent refinement threads applying the given closure.
   void threads_do(ThreadClosure *tc);
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -37,6 +37,8 @@
   ConcurrentGCThread(),
   _vtime_start(0.0),
   _vtime_accum(0.0),
+  _total_refinement_time(),
+  _total_refined_cards(0),
   _worker_id(worker_id),
   _active(false),
   _monitor(NULL),
@@ -101,11 +103,12 @@
       break;
     }
 
-    size_t buffers_processed = 0;
     log_debug(gc, refine)("Activated worker %d, on threshold: " SIZE_FORMAT ", current: " SIZE_FORMAT,
                           _worker_id, _cr->activation_threshold(_worker_id),
                           G1BarrierSet::dirty_card_queue_set().num_cards());
 
+    size_t start_total_refined_cards = _total_refined_cards; // For logging.
+
     {
       SuspendibleThreadSetJoiner sts_join;
 
@@ -115,20 +118,22 @@
           continue;             // Re-check for termination after yield delay.
         }
 
-        if (!_cr->do_refinement_step(_worker_id)) {
-          break;
+        Ticks start_time = Ticks::now();
+        if (!_cr->do_refinement_step(_worker_id, &_total_refined_cards)) {
+          break;                // No cards to process.
         }
-        ++buffers_processed;
+        _total_refinement_time += (Ticks::now() - start_time);
       }
     }
 
     deactivate();
     log_debug(gc, refine)("Deactivated worker %d, off threshold: " SIZE_FORMAT
-                          ", current: " SIZE_FORMAT ", buffers processed: "
-                          SIZE_FORMAT,
+                          ", current: " SIZE_FORMAT ", refined cards: "
+                          SIZE_FORMAT ", total refined cards: " SIZE_FORMAT,
                           _worker_id, _cr->deactivation_threshold(_worker_id),
                           G1BarrierSet::dirty_card_queue_set().num_cards(),
-                          buffers_processed);
+                          _total_refined_cards - start_total_refined_cards,
+                          _total_refined_cards);
 
     if (os::supports_vtime()) {
       _vtime_accum = (os::elapsedVTime() - _vtime_start);
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefineThread.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -26,6 +26,7 @@
 #define SHARE_GC_G1_G1CONCURRENTREFINETHREAD_HPP
 
 #include "gc/shared/concurrentGCThread.hpp"
+#include "utilities/ticks.hpp"
 
 // Forward Decl.
 class G1ConcurrentRefine;
@@ -38,6 +39,10 @@
 
   double _vtime_start;  // Initial virtual time.
   double _vtime_accum;  // Accumulated virtual time.
+
+  Tickspan _total_refinement_time;
+  size_t _total_refined_cards;
+
   uint _worker_id;
 
   bool _active;
@@ -61,6 +66,9 @@
   // Activate this thread.
   void activate();
 
+  Tickspan total_refinement_time() const { return _total_refinement_time; }
+  size_t total_refined_cards() const { return _total_refined_cards; }
+
   // Total virtual time so far.
   double vtime_accum() { return _vtime_accum; }
 };
--- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -37,6 +37,7 @@
 #include "runtime/atomic.hpp"
 #include "runtime/flags/flagSetting.hpp"
 #include "runtime/mutexLocker.hpp"
+#include "runtime/os.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/threadSMR.hpp"
@@ -62,6 +63,9 @@
   }
 }
 
+// Assumed to be zero by concurrent threads.
+static uint par_ids_start() { return 0; }
+
 G1DirtyCardQueueSet::G1DirtyCardQueueSet(Monitor* cbl_mon,
                                          BufferNode::Allocator* allocator) :
   PtrQueueSet(allocator),
@@ -73,15 +77,16 @@
   _process_completed_buffers(false),
   _max_cards(MaxCardsUnlimited),
   _max_cards_padding(0),
-  _free_ids(0, num_par_ids()),
-  _processed_buffers_mut(0),
-  _processed_buffers_rs_thread(0)
+  _free_ids(par_ids_start(), num_par_ids()),
+  _mutator_refined_cards_counters(NEW_C_HEAP_ARRAY(size_t, num_par_ids(), mtGC))
 {
+  ::memset(_mutator_refined_cards_counters, 0, num_par_ids() * sizeof(size_t));
   _all_active = true;
 }
 
 G1DirtyCardQueueSet::~G1DirtyCardQueueSet() {
   abandon_completed_buffers();
+  FREE_C_HEAP_ARRAY(size_t, _mutator_refined_cards_counters);
 }
 
 // Determines how many mutator threads can process the buffers in parallel.
@@ -89,6 +94,14 @@
   return (uint)os::initial_active_processor_count();
 }
 
+size_t G1DirtyCardQueueSet::total_mutator_refined_cards() const {
+  size_t sum = 0;
+  for (uint i = 0; i < num_par_ids(); ++i) {
+    sum += _mutator_refined_cards_counters[i];
+  }
+  return sum;
+}
+
 void G1DirtyCardQueueSet::handle_zero_index_for_thread(Thread* t) {
   G1ThreadLocalData::dirty_card_queue(t).handle_zero_index();
 }
@@ -213,7 +226,9 @@
   return result;
 }
 
-bool G1DirtyCardQueueSet::refine_buffer(BufferNode* node, uint worker_id) {
+bool G1DirtyCardQueueSet::refine_buffer(BufferNode* node,
+                                        uint worker_id,
+                                        size_t* total_refined_cards) {
   G1RemSet* rem_set = G1CollectedHeap::heap()->rem_set();
   size_t size = buffer_size();
   void** buffer = BufferNode::make_buffer_from_node(node);
@@ -223,6 +238,7 @@
     CardTable::CardValue* cp = static_cast<CardTable::CardValue*>(buffer[i]);
     rem_set->refine_card_concurrently(cp, worker_id);
   }
+  *total_refined_cards += (i - node->index());
   node->set_index(i);
   return i == size;
 }
@@ -260,25 +276,27 @@
 
 bool G1DirtyCardQueueSet::mut_process_buffer(BufferNode* node) {
   uint worker_id = _free_ids.claim_par_id(); // temporarily claim an id
-  bool result = refine_buffer(node, worker_id);
+  uint counter_index = worker_id - par_ids_start();
+  size_t* counter = &_mutator_refined_cards_counters[counter_index];
+  bool result = refine_buffer(node, worker_id, counter);
   _free_ids.release_par_id(worker_id); // release the id
 
   if (result) {
     assert_fully_consumed(node, buffer_size());
-    Atomic::inc(&_processed_buffers_mut);
   }
   return result;
 }
 
-bool G1DirtyCardQueueSet::refine_completed_buffer_concurrently(uint worker_id, size_t stop_at) {
+bool G1DirtyCardQueueSet::refine_completed_buffer_concurrently(uint worker_id,
+                                                               size_t stop_at,
+                                                               size_t* total_refined_cards) {
   BufferNode* node = get_completed_buffer(stop_at);
   if (node == NULL) {
     return false;
-  } else if (refine_buffer(node, worker_id)) {
+  } else if (refine_buffer(node, worker_id, total_refined_cards)) {
     assert_fully_consumed(node, buffer_size());
     // Done with fully processed buffer.
     deallocate_buffer(node);
-    Atomic::inc(&_processed_buffers_rs_thread);
     return true;
   } else {
     // Return partially processed buffer to the queue.
--- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -78,14 +78,15 @@
 
   void abandon_completed_buffers();
 
-  // Refine the cards in "node" from it's index to buffer_size.
+  // Refine the cards in "node" from its index to buffer_size.
   // Stops processing if SuspendibleThreadSet::should_yield() is true.
   // Returns true if the entire buffer was processed, false if there
   // is a pending yield request.  The node's index is updated to exclude
   // the processed elements, e.g. up to the element before processing
   // stopped, or one past the last element if the entire buffer was
-  // processed.
-  bool refine_buffer(BufferNode* node, uint worker_id);
+  // processed. Increments *total_refined_cards by the number of cards
+  // processed and removed from the buffer.
+  bool refine_buffer(BufferNode* node, uint worker_id, size_t* total_refined_cards);
 
   bool mut_process_buffer(BufferNode* node);
 
@@ -97,10 +98,9 @@
 
   G1FreeIdSet _free_ids;
 
-  // The number of completed buffers processed by mutator and rs thread,
-  // respectively.
-  jint _processed_buffers_mut;
-  jint _processed_buffers_rs_thread;
+  // Array of cumulative dirty cards refined by mutator threads.
+  // Array has an entry per id in _free_ids.
+  size_t* _mutator_refined_cards_counters;
 
 public:
   G1DirtyCardQueueSet(Monitor* cbl_mon, BufferNode::Allocator* allocator);
@@ -158,7 +158,12 @@
   // Stops processing a buffer if SuspendibleThreadSet::should_yield(),
   // returning the incompletely processed buffer to the completed buffer
   // list, for later processing of the remainder.
-  bool refine_completed_buffer_concurrently(uint worker_id, size_t stop_at);
+  //
+  // Increments *total_refined_cards by the number of cards processed and
+  // removed from the buffer.
+  bool refine_completed_buffer_concurrently(uint worker_id,
+                                            size_t stop_at,
+                                            size_t* total_refined_cards);
 
   // If a full collection is happening, reset partial logs, and release
   // completed ones: the full collection will make them all irrelevant.
@@ -181,13 +186,8 @@
     return _max_cards_padding;
   }
 
-  jint processed_buffers_mut() {
-    return _processed_buffers_mut;
-  }
-  jint processed_buffers_rs_thread() {
-    return _processed_buffers_rs_thread;
-  }
-
+  // Total dirty cards refined by mutator threads.
+  size_t total_mutator_refined_cards() const;
 };
 
 inline G1DirtyCardQueueSet* G1DirtyCardQueue::dirty_card_qset() const {
--- a/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactTask.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/src/hotspot/share/gc/g1/g1Policy.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1Policy.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -70,7 +70,11 @@
   _free_regions_at_end_of_collection(0),
   _max_rs_length(0),
   _rs_length_prediction(0),
-  _pending_cards(0),
+  _pending_cards_at_gc_start(0),
+  _pending_cards_at_prev_gc_end(0),
+  _total_mutator_refined_cards(0),
+  _total_concurrent_refined_cards(0),
+  _total_concurrent_refinement_time(),
   _bytes_allocated_in_old_since_last_gc(0),
   _initial_mark_to_mixed(),
   _collection_set(NULL),
@@ -442,6 +446,7 @@
   collector_state()->set_in_young_only_phase(false);
   collector_state()->set_in_full_gc(true);
   _collection_set->clear_candidates();
+  record_concurrent_refinement_data(true /* is_full_collection */);
 }
 
 void G1Policy::record_full_collection_end() {
@@ -472,12 +477,67 @@
   _survivor_surv_rate_group->reset();
   update_young_list_max_and_target_length();
   update_rs_length_prediction();
+  _pending_cards_at_prev_gc_end = _g1h->pending_card_num();
 
   _bytes_allocated_in_old_since_last_gc = 0;
 
   record_pause(FullGC, _full_collection_start_sec, end_sec);
 }
 
+void G1Policy::record_concurrent_refinement_data(bool is_full_collection) {
+  _pending_cards_at_gc_start = _g1h->pending_card_num();
+
+  // Record info about concurrent refinement thread processing.
+  G1ConcurrentRefine* cr = _g1h->concurrent_refine();
+  G1ConcurrentRefine::RefinementStats cr_stats = cr->total_refinement_stats();
+
+  Tickspan cr_time = cr_stats._time - _total_concurrent_refinement_time;
+  _total_concurrent_refinement_time = cr_stats._time;
+
+  size_t cr_cards = cr_stats._cards - _total_concurrent_refined_cards;
+  _total_concurrent_refined_cards = cr_stats._cards;
+
+  // Don't update rate if full collection.  We could be in an implicit full
+  // collection after a non-full collection failure, in which case there
+  // wasn't any mutator/cr-thread activity since last recording.  And if
+  // we're in an explicit full collection, the time since the last GC can
+  // be arbitrarily short, so not a very good sample.  Similarly, don't
+  // update the rate if the current sample is empty or time is zero.
+  if (!is_full_collection && (cr_cards > 0) && (cr_time > Tickspan())) {
+    double rate = cr_cards / (cr_time.seconds() * MILLIUNITS);
+    _analytics->report_concurrent_refine_rate_ms(rate);
+  }
+
+  // Record info about mutator thread processing.
+  G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
+  size_t mut_total_cards = dcqs.total_mutator_refined_cards();
+  size_t mut_cards = mut_total_cards - _total_mutator_refined_cards;
+  _total_mutator_refined_cards = mut_total_cards;
+
+  // Record mutator's card logging rate.
+  // Don't update if full collection; see above.
+  if (!is_full_collection) {
+    size_t total_cards = _pending_cards_at_gc_start + cr_cards + mut_cards;
+    assert(_pending_cards_at_prev_gc_end <= total_cards,
+           "untracked cards: last pending: " SIZE_FORMAT
+           ", pending: " SIZE_FORMAT ", conc refine: " SIZE_FORMAT
+           ", mut refine:" SIZE_FORMAT,
+           _pending_cards_at_prev_gc_end, _pending_cards_at_gc_start,
+           cr_cards, mut_cards);
+    size_t logged_cards = total_cards - _pending_cards_at_prev_gc_end;
+    double logging_start_time = _analytics->prev_collection_pause_end_ms();
+    double logging_end_time = Ticks::now().seconds() * MILLIUNITS;
+    double logging_time = logging_end_time - logging_start_time;
+    // Unlike above for conc-refine rate, here we should not require a
+    // non-empty sample, since an application could go some time with only
+    // young-gen or filtered out writes.  But we'll ignore unusually short
+    // sample periods, as they may just pollute the predictions.
+    if (logging_time > 1.0) {   // Require > 1ms sample time.
+      _analytics->report_logged_cards_rate_ms(logged_cards / logging_time);
+    }
+  }
+}
+
 void G1Policy::record_collection_pause_start(double start_time_sec) {
   // We only need to do this here as the policy will only be applied
   // to the GC we're about to start. so, no point is calculating this
@@ -490,7 +550,8 @@
   assert_used_and_recalculate_used_equal(_g1h);
 
   phase_times()->record_cur_collection_start_sec(start_time_sec);
-  _pending_cards = _g1h->pending_card_num();
+
+  record_concurrent_refinement_data(false /* is_full_collection */);
 
   _collection_set->reset_bytes_used_before();
   _bytes_copied_during_gc = 0;
@@ -744,7 +805,7 @@
     // after the mixed gc phase.
     // During mixed gc we do not use them for young gen sizing.
     if (this_pause_was_young_only) {
-      _analytics->report_pending_cards((double) _pending_cards);
+      _analytics->report_pending_cards((double) _pending_cards_at_gc_start);
       _analytics->report_rs_length((double) _max_rs_length);
     }
   }
@@ -798,6 +859,7 @@
     scan_logged_cards_time_goal_ms -= scan_hcc_time_ms;
   }
 
+  _pending_cards_at_prev_gc_end = _g1h->pending_card_num();
   double const logged_cards_time = logged_cards_processing_time();
 
   log_debug(gc, ergo, refine)("Concurrent refinement times: Logged Cards Scan time goal: %1.2fms Logged Cards Scan time: %1.2fms HCC time: %1.2fms",
--- a/src/hotspot/share/gc/g1/g1Policy.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1Policy.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -100,7 +100,11 @@
 
   size_t _rs_length_prediction;
 
-  size_t _pending_cards;
+  size_t _pending_cards_at_gc_start;
+  size_t _pending_cards_at_prev_gc_end;
+  size_t _total_mutator_refined_cards;
+  size_t _total_concurrent_refined_cards;
+  Tickspan _total_concurrent_refinement_time;
 
   // The amount of allocated bytes in old gen during the last mutator and the following
   // young GC phase.
@@ -244,7 +248,15 @@
                         uint base_free_regions, double target_pause_time_ms) const;
 
 public:
-  size_t pending_cards() const { return _pending_cards; }
+  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.
@@ -283,6 +295,9 @@
   void record_pause(PauseKind kind, double start, double end);
   // Indicate that we aborted marking before doing any mixed GCs.
   void abort_time_to_mixed_tracking();
+
+  void record_concurrent_refinement_data(bool is_full_collection);
+
 public:
 
   G1Policy(STWGCTimer* gc_timer);
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -489,7 +489,6 @@
   _scan_state(new G1RemSetScanState()),
   _prev_period_summary(),
   _g1h(g1h),
-  _num_conc_refined_cards(0),
   _ct(ct),
   _g1p(_g1h->policy()),
   _hot_card_cache(hot_card_cache) {
@@ -1377,7 +1376,6 @@
 
   G1ConcurrentRefineOopClosure conc_refine_cl(_g1h, worker_id);
   if (r->oops_on_memregion_seq_iterate_careful<false>(dirty_region, &conc_refine_cl) != NULL) {
-    _num_conc_refined_cards++; // Unsynchronized update, only used for logging.
     return;
   }
 
--- a/src/hotspot/share/gc/g1/g1RemSet.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1RemSet.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -61,7 +61,6 @@
   G1RemSetSummary _prev_period_summary;
 
   G1CollectedHeap* _g1h;
-  size_t _num_conc_refined_cards; // Number of cards refined concurrently to the mutator.
 
   G1CardTable*           _ct;
   G1Policy*              _g1p;
@@ -125,8 +124,6 @@
   // Print accumulated summary info from the last time called.
   void print_periodic_summary_info(const char* header, uint period_count);
 
-  size_t num_conc_refined_cards() const { return _num_conc_refined_cards; }
-
   // Rebuilds the remembered set by scanning from bottom to TARS for all regions
   // using the given work gang.
   void rebuild_rem_set(G1ConcurrentMark* cm, WorkGang* workers, uint worker_id_offset);
--- a/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1RemSetSummary.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -27,6 +27,7 @@
 #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"
@@ -53,18 +54,17 @@
 };
 
 void G1RemSetSummary::update() {
-  _num_conc_refined_cards = _rem_set->num_conc_refined_cards();
-  G1DirtyCardQueueSet& dcqs = G1BarrierSet::dirty_card_queue_set();
-  _num_processed_buf_mutator = dcqs.processed_buffers_mut();
-  _num_processed_buf_rs_threads = dcqs.processed_buffers_rs_thread();
+  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();
 
   _num_coarsenings = HeapRegionRemSet::n_coarsenings();
 
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  G1ConcurrentRefine* cg1r = g1h->concurrent_refine();
   if (_rs_threads_vtimes != NULL) {
     GetRSThreadVTimeClosure p(this);
-    cg1r->threads_do(&p);
+    g1h->concurrent_refine()->threads_do(&p);
   }
   set_sampling_thread_vtime(g1h->sampling_thread()->vtime_accum());
 }
@@ -83,9 +83,8 @@
 
 G1RemSetSummary::G1RemSetSummary() :
   _rem_set(NULL),
-  _num_conc_refined_cards(0),
-  _num_processed_buf_mutator(0),
-  _num_processed_buf_rs_threads(0),
+  _total_mutator_refined_cards(0),
+  _total_concurrent_refined_cards(0),
   _num_coarsenings(0),
   _num_vtimes(G1ConcurrentRefine::max_num_threads()),
   _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)),
@@ -96,9 +95,8 @@
 
 G1RemSetSummary::G1RemSetSummary(G1RemSet* rem_set) :
   _rem_set(rem_set),
-  _num_conc_refined_cards(0),
-  _num_processed_buf_mutator(0),
-  _num_processed_buf_rs_threads(0),
+  _total_mutator_refined_cards(0),
+  _total_concurrent_refined_cards(0),
   _num_coarsenings(0),
   _num_vtimes(G1ConcurrentRefine::max_num_threads()),
   _rs_threads_vtimes(NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC)),
@@ -114,12 +112,10 @@
   assert(other != NULL, "just checking");
   assert(_num_vtimes == other->_num_vtimes, "just checking");
 
-  _num_conc_refined_cards = other->num_conc_refined_cards();
+  _total_mutator_refined_cards = other->total_mutator_refined_cards();
+  _total_concurrent_refined_cards = other->total_concurrent_refined_cards();
 
-  _num_processed_buf_mutator = other->num_processed_buf_mutator();
-  _num_processed_buf_rs_threads = other->num_processed_buf_rs_threads();
-
-  _num_coarsenings = other->_num_coarsenings;
+  _num_coarsenings = other->num_coarsenings();
 
   memcpy(_rs_threads_vtimes, other->_rs_threads_vtimes, sizeof(double) * _num_vtimes);
 
@@ -130,10 +126,8 @@
   assert(other != NULL, "just checking");
   assert(_num_vtimes == other->_num_vtimes, "just checking");
 
-  _num_conc_refined_cards = other->num_conc_refined_cards() - _num_conc_refined_cards;
-
-  _num_processed_buf_mutator = other->num_processed_buf_mutator() - _num_processed_buf_mutator;
-  _num_processed_buf_rs_threads = other->num_processed_buf_rs_threads() - _num_processed_buf_rs_threads;
+  _total_mutator_refined_cards = other->total_mutator_refined_cards() - _total_mutator_refined_cards;
+  _total_concurrent_refined_cards = other->total_concurrent_refined_cards() - _total_concurrent_refined_cards;
 
   _num_coarsenings = other->num_coarsenings() - _num_coarsenings;
 
@@ -356,16 +350,15 @@
 
 void G1RemSetSummary::print_on(outputStream* out) {
   out->print_cr(" Recent concurrent refinement statistics");
-  out->print_cr("  Processed " SIZE_FORMAT " cards concurrently", num_conc_refined_cards());
-  out->print_cr("  Of " SIZE_FORMAT " completed buffers:", num_processed_buf_total());
-  out->print_cr("     " SIZE_FORMAT_W(8) " (%5.1f%%) by concurrent RS threads.",
-                num_processed_buf_total(),
-                percent_of(num_processed_buf_rs_threads(), num_processed_buf_total()));
+  out->print_cr("  Of " SIZE_FORMAT " refined cards:", total_refined_cards());
+  out->print_cr("     " SIZE_FORMAT_W(8) " (%5.1f%%) by concurrent refinement threads.",
+                total_concurrent_refined_cards(),
+                percent_of(total_concurrent_refined_cards(), total_refined_cards()));
   out->print_cr("     " SIZE_FORMAT_W(8) " (%5.1f%%) by mutator threads.",
-                num_processed_buf_mutator(),
-                percent_of(num_processed_buf_mutator(), num_processed_buf_total()));
+                total_mutator_refined_cards(),
+                percent_of(total_mutator_refined_cards(), total_refined_cards()));
   out->print_cr("  Did " SIZE_FORMAT " coarsenings.", num_coarsenings());
-  out->print_cr("  Concurrent RS threads times (s)");
+  out->print_cr("  Concurrent refinement threads times (s)");
   out->print("     ");
   for (uint i = 0; i < _num_vtimes; i++) {
     out->print("    %5.2f", rs_thread_vtime(i));
--- a/src/hotspot/share/gc/g1/g1RemSetSummary.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1RemSetSummary.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -38,9 +38,8 @@
 
   G1RemSet* _rem_set;
 
-  size_t _num_conc_refined_cards;
-  size_t _num_processed_buf_mutator;
-  size_t _num_processed_buf_rs_threads;
+  size_t _total_mutator_refined_cards;
+  size_t _total_concurrent_refined_cards;
 
   size_t _num_coarsenings;
 
@@ -76,20 +75,16 @@
     return _sampling_thread_vtime;
   }
 
-  size_t num_conc_refined_cards() const {
-    return _num_conc_refined_cards;
+  size_t total_mutator_refined_cards() const {
+    return _total_mutator_refined_cards;
   }
 
-  size_t num_processed_buf_mutator() const {
-    return _num_processed_buf_mutator;
+  size_t total_concurrent_refined_cards() const {
+    return _total_concurrent_refined_cards;
   }
 
-  size_t num_processed_buf_rs_threads() const {
-    return _num_processed_buf_rs_threads;
-  }
-
-  size_t num_processed_buf_total() const {
-    return num_processed_buf_mutator() + num_processed_buf_rs_threads();
+  size_t total_refined_cards() const {
+    return total_mutator_refined_cards() + total_concurrent_refined_cards();
   }
 
   size_t num_coarsenings() const {
--- a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -264,7 +264,7 @@
   virtual void clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const;
 
   // Support for GC barriers emitted during parsing
-  virtual bool has_load_barriers() const { return false; }
+  virtual bool has_load_barrier_nodes() const { return false; }
   virtual bool is_gc_barrier_node(Node* node) const { return false; }
   virtual Node* step_over_gc_barrier(Node* c) const { return c; }
   virtual Node* step_over_gc_barrier_ctrl(Node* c) const { return c; }
@@ -287,13 +287,9 @@
   virtual bool is_gc_specific_loop_opts_pass(LoopOptsMode mode) const { return false; }
 
   virtual bool has_special_unique_user(const Node* node) const { return false; }
-  virtual bool needs_anti_dependence_check(const Node* node) const { return true; }
-
-  virtual void barrier_insertion_phase(Compile* C, PhaseIterGVN &igvn) const { }
 
   enum CompilePhase {
     BeforeOptimize,
-    BeforeLateInsertion,
     BeforeMacroExpand,
     BeforeCodeGen
   };
@@ -320,6 +316,10 @@
   virtual Node* split_if_pre(PhaseIdealLoop* phase, Node* n) const { return NULL; }
   virtual bool build_loop_late_post(PhaseIdealLoop* phase, Node* n) const { return false; }
   virtual bool sink_node(PhaseIdealLoop* phase, Node* n, Node* x, Node* x_ctrl, Node* n_ctrl) const { return false; }
+
+  virtual void late_barrier_analysis() const { }
+  virtual int estimate_stub_size() const { return 0; }
+  virtual void emit_stubs(CodeBuffer& cb) const { }
 };
 
 #endif // SHARE_GC_SHARED_C2_BARRIERSETC2_HPP
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -103,7 +103,7 @@
   static const TypeFunc* write_ref_field_pre_entry_Type();
   static const TypeFunc* shenandoah_clone_barrier_Type();
   static const TypeFunc* shenandoah_load_reference_barrier_Type();
-  virtual bool has_load_barriers() const { return true; }
+  virtual bool has_load_barrier_nodes() const { return true; }
 
   // This is the entry-point for the backend to perform accesses through the Access API.
   virtual void clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const;
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1276,12 +1276,32 @@
         // The rethrow call may have too many projections to be
         // properly handled here. Given there's no reason for a
         // barrier to depend on the call, move it above the call
-        if (phase->get_ctrl(val) == ctrl) {
-          assert(val->Opcode() == Op_DecodeN, "unexpected node");
-          assert(phase->is_dominator(phase->get_ctrl(val->in(1)), call->in(0)), "Load is too low");
-          phase->set_ctrl(val, call->in(0));
-        }
-        phase->set_ctrl(lrb, call->in(0));
+        stack.push(lrb, 0);
+        do {
+          Node* n = stack.node();
+          uint idx = stack.index();
+          if (idx < n->req()) {
+            Node* in = n->in(idx);
+            stack.set_index(idx+1);
+            if (in != NULL) {
+              if (phase->has_ctrl(in)) {
+                if (phase->is_dominator(call, phase->get_ctrl(in))) {
+#ifdef ASSERT
+                  for (uint i = 0; i < stack.size(); i++) {
+                    assert(stack.node_at(i) != in, "node shouldn't have been seen yet");
+                  }
+#endif
+                  stack.push(in, 0);
+                }
+              } else {
+                assert(phase->is_dominator(in, call->in(0)), "no dependency on the call");
+              }
+            }
+          } else {
+            phase->set_ctrl(n, call->in(0));
+            stack.pop();
+          }
+        } while(stack.size() > 0);
         continue;
       }
       CallProjections projs;
--- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -69,7 +69,8 @@
   // enough, but we also do not want to steal too much CPU from the concurrently running
   // application. Using 1/4 of available threads for concurrent GC seems a good
   // compromise here.
-  if (FLAG_IS_DEFAULT(ConcGCThreads)) {
+  bool ergo_conc = FLAG_IS_DEFAULT(ConcGCThreads);
+  if (ergo_conc) {
     FLAG_SET_DEFAULT(ConcGCThreads, MAX2(1, os::processor_count() / 4));
   }
 
@@ -82,7 +83,8 @@
   // that will overwhelm the OS scheduler. Using 1/2 of available threads seems to be a fair
   // compromise here. Due to implementation constraints, it should not be lower than
   // the number of concurrent threads.
-  if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
+  bool ergo_parallel = FLAG_IS_DEFAULT(ParallelGCThreads);
+  if (ergo_parallel) {
     FLAG_SET_DEFAULT(ParallelGCThreads, MAX2(1, os::processor_count() / 2));
   }
 
@@ -90,9 +92,21 @@
     vm_exit_during_initialization("Shenandoah expects ParallelGCThreads > 0, check -XX:ParallelGCThreads=#");
   }
 
+  // Make sure ergonomic decisions do not break the thread count invariants.
+  // This may happen when user overrides one of the flags, but not the other.
+  // When that happens, we want to adjust the setting that was set ergonomically.
   if (ParallelGCThreads < ConcGCThreads) {
-    warning("Shenandoah expects ConcGCThreads <= ParallelGCThreads, adjusting ParallelGCThreads automatically");
-    FLAG_SET_DEFAULT(ParallelGCThreads, ConcGCThreads);
+    if (ergo_conc && !ergo_parallel) {
+      FLAG_SET_DEFAULT(ConcGCThreads, ParallelGCThreads);
+    } else if (!ergo_conc && ergo_parallel) {
+      FLAG_SET_DEFAULT(ParallelGCThreads, ConcGCThreads);
+    } else if (ergo_conc && ergo_parallel) {
+      // Should not happen, check the ergonomic computation above. Fail with relevant error.
+      vm_exit_during_initialization("Shenandoah thread count ergonomic error");
+    } else {
+      // User settings error, report and ask user to rectify.
+      vm_exit_during_initialization("Shenandoah expects ConcGCThreads <= ParallelGCThreads, check -XX:ParallelGCThreads, -XX:ConcGCThreads");
+    }
   }
 
   if (FLAG_IS_DEFAULT(ParallelRefProcEnabled)) {
--- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -314,9 +314,6 @@
   diagnostic(bool, ShenandoahTerminationTrace, false,                       \
           "Tracing task termination timings")                               \
                                                                             \
-  develop(bool, ShenandoahVerifyObjectEquals, false,                        \
-          "Verify that == and != are not used on oops. Only in fastdebug")  \
-                                                                            \
   diagnostic(bool, ShenandoahAlwaysPreTouch, false,                         \
           "Pre-touch heap memory, overrides global AlwaysPreTouch")         \
                                                                             \
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -22,451 +22,157 @@
  */
 
 #include "precompiled.hpp"
-#include "opto/castnode.hpp"
+#include "classfile/javaClasses.hpp"
+#include "gc/z/c2/zBarrierSetC2.hpp"
+#include "gc/z/zBarrierSet.hpp"
+#include "gc/z/zBarrierSetAssembler.hpp"
+#include "gc/z/zBarrierSetRuntime.hpp"
+#include "opto/block.hpp"
 #include "opto/compile.hpp"
-#include "opto/escape.hpp"
 #include "opto/graphKit.hpp"
-#include "opto/loopnode.hpp"
 #include "opto/machnode.hpp"
-#include "opto/macro.hpp"
 #include "opto/memnode.hpp"
-#include "opto/movenode.hpp"
 #include "opto/node.hpp"
-#include "opto/phase.hpp"
-#include "opto/phaseX.hpp"
+#include "opto/regalloc.hpp"
 #include "opto/rootnode.hpp"
-#include "opto/type.hpp"
-#include "utilities/copy.hpp"
 #include "utilities/growableArray.hpp"
 #include "utilities/macros.hpp"
-#include "gc/z/zBarrierSet.hpp"
-#include "gc/z/c2/zBarrierSetC2.hpp"
-#include "gc/z/zThreadLocalData.hpp"
-#include "gc/z/zBarrierSetRuntime.hpp"
 
-ZBarrierSetC2State::ZBarrierSetC2State(Arena* comp_arena) :
-    _load_barrier_nodes(new (comp_arena) GrowableArray<LoadBarrierNode*>(comp_arena, 8,  0, NULL)) {}
+class ZBarrierSetC2State : public ResourceObj {
+private:
+  GrowableArray<ZLoadBarrierStubC2*>* _stubs;
+  Node_Array                          _live;
 
-int ZBarrierSetC2State::load_barrier_count() const {
-  return _load_barrier_nodes->length();
-}
+public:
+  ZBarrierSetC2State(Arena* arena) :
+    _stubs(new (arena) GrowableArray<ZLoadBarrierStubC2*>(arena, 8,  0, NULL)),
+    _live(arena) {}
 
-void ZBarrierSetC2State::add_load_barrier_node(LoadBarrierNode * n) {
-  assert(!_load_barrier_nodes->contains(n), " duplicate entry in expand list");
-  _load_barrier_nodes->append(n);
-}
+  GrowableArray<ZLoadBarrierStubC2*>* stubs() {
+    return _stubs;
+  }
 
-void ZBarrierSetC2State::remove_load_barrier_node(LoadBarrierNode * n) {
-  // this function may be called twice for a node so check
-  // that the node is in the array before attempting to remove it
-  if (_load_barrier_nodes->contains(n)) {
-    _load_barrier_nodes->remove(n);
-  }
-}
+  RegMask* live(const Node* node) {
+    if (!node->is_Mach()) {
+      // Don't need liveness for non-MachNodes
+      return NULL;
+    }
 
-LoadBarrierNode* ZBarrierSetC2State::load_barrier_node(int idx) const {
-  return _load_barrier_nodes->at(idx);
-}
+    const MachNode* const mach = node->as_Mach();
+    if (mach->barrier_data() != ZLoadBarrierStrong &&
+        mach->barrier_data() != ZLoadBarrierWeak) {
+      // Don't need liveness data for nodes without barriers
+      return NULL;
+    }
 
-void* ZBarrierSetC2::create_barrier_state(Arena* comp_arena) const {
-  return new(comp_arena) ZBarrierSetC2State(comp_arena);
-}
+    RegMask* live = (RegMask*)_live[node->_idx];
+    if (live == NULL) {
+      live = new (Compile::current()->comp_arena()->Amalloc_D(sizeof(RegMask))) RegMask();
+      _live.map(node->_idx, (Node*)live);
+    }
 
-ZBarrierSetC2State* ZBarrierSetC2::state() const {
+    return live;
+  }
+};
+
+static ZBarrierSetC2State* barrier_set_state() {
   return reinterpret_cast<ZBarrierSetC2State*>(Compile::current()->barrier_set_state());
 }
 
-bool ZBarrierSetC2::is_gc_barrier_node(Node* node) const {
-  // 1. This step follows potential oop projections of a load barrier before expansion
-  if (node->is_Proj()) {
-    node = node->in(0);
-  }
-
-  // 2. This step checks for unexpanded load barriers
-  if (node->is_LoadBarrier()) {
-    return true;
-  }
-
-  // 3. This step checks for the phi corresponding to an optimized load barrier expansion
-  if (node->is_Phi()) {
-    PhiNode* phi = node->as_Phi();
-    Node* n = phi->in(1);
-    if (n != NULL && n->is_LoadBarrierSlowReg()) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-void ZBarrierSetC2::register_potential_barrier_node(Node* node) const {
-  if (node->is_LoadBarrier()) {
-    state()->add_load_barrier_node(node->as_LoadBarrier());
-  }
-}
-
-void ZBarrierSetC2::unregister_potential_barrier_node(Node* node) const {
-  if (node->is_LoadBarrier()) {
-    state()->remove_load_barrier_node(node->as_LoadBarrier());
-  }
-}
-
-void ZBarrierSetC2::eliminate_useless_gc_barriers(Unique_Node_List &useful, Compile* C) const {
-  // Remove useless LoadBarrier nodes
-  ZBarrierSetC2State* s = state();
-  for (int i = s->load_barrier_count()-1; i >= 0; i--) {
-    LoadBarrierNode* n = s->load_barrier_node(i);
-    if (!useful.member(n)) {
-      unregister_potential_barrier_node(n);
-    }
-  }
-}
-
-void ZBarrierSetC2::enqueue_useful_gc_barrier(PhaseIterGVN* igvn, Node* node) const {
-  if (node->is_LoadBarrier() && !node->as_LoadBarrier()->has_true_uses()) {
-    igvn->_worklist.push(node);
-  }
-}
-
-const uint NoBarrier       = 0;
-const uint RequireBarrier  = 1;
-const uint WeakBarrier     = 2;
-const uint ExpandedBarrier = 4;
-
-static bool load_require_barrier(LoadNode* load)      { return (load->barrier_data() & RequireBarrier)  == RequireBarrier; }
-static bool load_has_weak_barrier(LoadNode* load)     { return (load->barrier_data() & WeakBarrier)     == WeakBarrier; }
-static bool load_has_expanded_barrier(LoadNode* load) { return (load->barrier_data() & ExpandedBarrier) == ExpandedBarrier; }
-static void load_set_expanded_barrier(LoadNode* load) { return load->set_barrier_data(ExpandedBarrier); }
-
-static void load_set_barrier(LoadNode* load, bool weak) {
-  if (weak) {
-    load->set_barrier_data(RequireBarrier | WeakBarrier);
-  } else {
-    load->set_barrier_data(RequireBarrier);
-  }
-}
-
-// == LoadBarrierNode ==
-
-LoadBarrierNode::LoadBarrierNode(Compile* C,
-                                 Node* c,
-                                 Node* mem,
-                                 Node* val,
-                                 Node* adr,
-                                 bool weak) :
-    MultiNode(Number_of_Inputs),
-    _weak(weak) {
-  init_req(Control, c);
-  init_req(Memory, mem);
-  init_req(Oop, val);
-  init_req(Address, adr);
-  init_req(Similar, C->top());
-
-  init_class_id(Class_LoadBarrier);
-  BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
-  bs->register_potential_barrier_node(this);
-}
-
-uint LoadBarrierNode::size_of() const {
-  return sizeof(*this);
-}
-
-bool LoadBarrierNode::cmp(const Node& n) const {
-  ShouldNotReachHere();
-  return false;
-}
-
-const Type *LoadBarrierNode::bottom_type() const {
-  const Type** floadbarrier = (const Type **)(Compile::current()->type_arena()->Amalloc_4((Number_of_Outputs)*sizeof(Type*)));
-  Node* in_oop = in(Oop);
-  floadbarrier[Control] = Type::CONTROL;
-  floadbarrier[Memory] = Type::MEMORY;
-  floadbarrier[Oop] = in_oop == NULL ? Type::TOP : in_oop->bottom_type();
-  return TypeTuple::make(Number_of_Outputs, floadbarrier);
-}
-
-const TypePtr* LoadBarrierNode::adr_type() const {
-  ShouldNotReachHere();
-  return NULL;
-}
-
-const Type *LoadBarrierNode::Value(PhaseGVN *phase) const {
-  const Type** floadbarrier = (const Type **)(phase->C->type_arena()->Amalloc_4((Number_of_Outputs)*sizeof(Type*)));
-  const Type* val_t = phase->type(in(Oop));
-  floadbarrier[Control] = Type::CONTROL;
-  floadbarrier[Memory]  = Type::MEMORY;
-  floadbarrier[Oop]     = val_t;
-  return TypeTuple::make(Number_of_Outputs, floadbarrier);
-}
-
-bool LoadBarrierNode::is_dominator(PhaseIdealLoop* phase, bool linear_only, Node *d, Node *n) {
-  if (phase != NULL) {
-    return phase->is_dominator(d, n);
-  }
-
-  for (int i = 0; i < 10 && n != NULL; i++) {
-    n = IfNode::up_one_dom(n, linear_only);
-    if (n == d) {
-      return true;
-    }
-  }
-
-  return false;
-}
-
-LoadBarrierNode* LoadBarrierNode::has_dominating_barrier(PhaseIdealLoop* phase, bool linear_only, bool look_for_similar) {
-  if (is_weak()) {
-    // Weak barriers can't be eliminated
-    return NULL;
-  }
-
-  Node* val = in(LoadBarrierNode::Oop);
-  if (in(Similar)->is_Proj() && in(Similar)->in(0)->is_LoadBarrier()) {
-    LoadBarrierNode* lb = in(Similar)->in(0)->as_LoadBarrier();
-    assert(lb->in(Address) == in(Address), "");
-    // Load barrier on Similar edge dominates so if it now has the Oop field it can replace this barrier.
-    if (lb->in(Oop) == in(Oop)) {
-      return lb;
-    }
-    // Follow chain of load barrier through Similar edges
-    while (!lb->in(Similar)->is_top()) {
-      lb = lb->in(Similar)->in(0)->as_LoadBarrier();
-      assert(lb->in(Address) == in(Address), "");
-    }
-    if (lb != in(Similar)->in(0)) {
-      return lb;
-    }
-  }
-  for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) {
-    Node* u = val->fast_out(i);
-    if (u != this && u->is_LoadBarrier() && u->in(Oop) == val && u->as_LoadBarrier()->has_true_uses()) {
-      Node* this_ctrl = in(LoadBarrierNode::Control);
-      Node* other_ctrl = u->in(LoadBarrierNode::Control);
-      if (is_dominator(phase, linear_only, other_ctrl, this_ctrl)) {
-        return u->as_LoadBarrier();
-      }
-    }
-  }
-
-  if (can_be_eliminated()) {
-    return NULL;
-  }
-
-  if (!look_for_similar) {
-    return NULL;
+ZLoadBarrierStubC2* ZLoadBarrierStubC2::create(const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) {
+  ZLoadBarrierStubC2* const stub = new (Compile::current()->comp_arena()) ZLoadBarrierStubC2(node, ref_addr, ref, tmp, weak);
+  if (!Compile::current()->in_scratch_emit_size()) {
+    barrier_set_state()->stubs()->append(stub);
   }
 
-  Node* addr = in(LoadBarrierNode::Address);
-  for (DUIterator_Fast imax, i = addr->fast_outs(imax); i < imax; i++) {
-    Node* u = addr->fast_out(i);
-    if (u != this && u->is_LoadBarrier() && u->as_LoadBarrier()->has_true_uses()) {
-      Node* this_ctrl = in(LoadBarrierNode::Control);
-      Node* other_ctrl = u->in(LoadBarrierNode::Control);
-      if (is_dominator(phase, linear_only, other_ctrl, this_ctrl)) {
-        ResourceMark rm;
-        Unique_Node_List wq;
-        wq.push(in(LoadBarrierNode::Control));
-        bool ok = true;
-        bool dom_found = false;
-        for (uint next = 0; next < wq.size(); ++next) {
-          Node *n = wq.at(next);
-          if (n->is_top()) {
-            return NULL;
-          }
-          assert(n->is_CFG(), "");
-          if (n->is_SafePoint()) {
-            ok = false;
-            break;
-          }
-          if (n == u) {
-            dom_found = true;
-            continue;
-          }
-          if (n->is_Region()) {
-            for (uint i = 1; i < n->req(); i++) {
-              Node* m = n->in(i);
-              if (m != NULL) {
-                wq.push(m);
-              }
-            }
-          } else {
-            Node* m = n->in(0);
-            if (m != NULL) {
-              wq.push(m);
-            }
-          }
-        }
-        if (ok) {
-          assert(dom_found, "");
-          return u->as_LoadBarrier();
-        }
-        break;
-      }
-    }
-  }
+  return stub;
+}
+
+ZLoadBarrierStubC2::ZLoadBarrierStubC2(const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak) :
+    _node(node),
+    _ref_addr(ref_addr),
+    _ref(ref),
+    _tmp(tmp),
+    _weak(weak),
+    _entry(),
+    _continuation() {
+  assert_different_registers(ref, ref_addr.base());
+  assert_different_registers(ref, ref_addr.index());
+}
 
-  return NULL;
+Address ZLoadBarrierStubC2::ref_addr() const {
+  return _ref_addr;
+}
+
+Register ZLoadBarrierStubC2::ref() const {
+  return _ref;
+}
+
+Register ZLoadBarrierStubC2::tmp() const {
+  return _tmp;
+}
+
+address ZLoadBarrierStubC2::slow_path() const {
+  const DecoratorSet decorators = _weak ? ON_WEAK_OOP_REF : ON_STRONG_OOP_REF;
+  return ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr(decorators);
 }
 
-void LoadBarrierNode::push_dominated_barriers(PhaseIterGVN* igvn) const {
-  // Change to that barrier may affect a dominated barrier so re-push those
-  assert(!is_weak(), "sanity");
-  Node* val = in(LoadBarrierNode::Oop);
+RegMask& ZLoadBarrierStubC2::live() const {
+  return *barrier_set_state()->live(_node);
+}
+
+Label* ZLoadBarrierStubC2::entry() {
+  // The _entry will never be bound when in_scratch_emit_size() is true.
+  // However, we still need to return a label that is not bound now, but
+  // will eventually be bound. Any lable will do, as it will only act as
+  // a placeholder, so we return the _continuation label.
+  return Compile::current()->in_scratch_emit_size() ? &_continuation : &_entry;
+}
+
+Label* ZLoadBarrierStubC2::continuation() {
+  return &_continuation;
+}
 
-  for (DUIterator_Fast imax, i = val->fast_outs(imax); i < imax; i++) {
-    Node* u = val->fast_out(i);
-    if (u != this && u->is_LoadBarrier() && u->in(Oop) == val) {
-      Node* this_ctrl = in(Control);
-      Node* other_ctrl = u->in(Control);
-      if (is_dominator(NULL, false, this_ctrl, other_ctrl)) {
-        igvn->_worklist.push(u);
-      }
+void* ZBarrierSetC2::create_barrier_state(Arena* comp_arena) const {
+  return new (comp_arena) ZBarrierSetC2State(comp_arena);
+}
+
+void ZBarrierSetC2::late_barrier_analysis() const {
+  analyze_dominating_barriers();
+  compute_liveness_at_stubs();
+}
+
+void ZBarrierSetC2::emit_stubs(CodeBuffer& cb) const {
+  MacroAssembler masm(&cb);
+  GrowableArray<ZLoadBarrierStubC2*>* const stubs = barrier_set_state()->stubs();
+
+  for (int i = 0; i < stubs->length(); i++) {
+    // Make sure there is enough space in the code buffer
+    if (cb.insts()->maybe_expand_to_ensure_remaining(Compile::MAX_inst_size) && cb.blob() == NULL) {
+      ciEnv::current()->record_failure("CodeCache is full");
+      return;
     }
 
-    Node* addr = in(LoadBarrierNode::Address);
-    for (DUIterator_Fast imax, i = addr->fast_outs(imax); i < imax; i++) {
-      Node* u = addr->fast_out(i);
-      if (u != this && u->is_LoadBarrier() && u->in(Similar)->is_top()) {
-        Node* this_ctrl = in(Control);
-        Node* other_ctrl = u->in(Control);
-        if (is_dominator(NULL, false, this_ctrl, other_ctrl)) {
-          igvn->_worklist.push(u);
-        }
-      }
-    }
-  }
-}
-
-Node *LoadBarrierNode::Identity(PhaseGVN *phase) {
-  LoadBarrierNode* dominating_barrier = has_dominating_barrier(NULL, true, false);
-  if (dominating_barrier != NULL) {
-    assert(!is_weak(), "Weak barriers cant be eliminated");
-    assert(dominating_barrier->in(Oop) == in(Oop), "");
-    return dominating_barrier;
-  }
-
-  return this;
-}
-
-Node *LoadBarrierNode::Ideal(PhaseGVN *phase, bool can_reshape) {
-  if (remove_dead_region(phase, can_reshape)) {
-    return this;
+    ZBarrierSet::assembler()->generate_c2_load_barrier_stub(&masm, stubs->at(i));
   }
 
-  Node *val = in(Oop);
-  Node *mem = in(Memory);
-  Node *ctrl = in(Control);
-
-  assert(val->Opcode() != Op_LoadN, "");
-  assert(val->Opcode() != Op_DecodeN, "");
-
-  if (mem->is_MergeMem()) {
-    Node *new_mem = mem->as_MergeMem()->memory_at(Compile::AliasIdxRaw);
-    set_req(Memory, new_mem);
-    if (mem->outcnt() == 0 && can_reshape) {
-      phase->is_IterGVN()->_worklist.push(mem);
-    }
-    return this;
-  }
+  masm.flush();
+}
 
-  LoadBarrierNode *dominating_barrier = NULL;
-  if (!is_weak()) {
-    dominating_barrier = has_dominating_barrier(NULL, !can_reshape, !phase->C->major_progress());
-    if (dominating_barrier != NULL && dominating_barrier->in(Oop) != in(Oop)) {
-      assert(in(Address) == dominating_barrier->in(Address), "");
-      set_req(Similar, dominating_barrier->proj_out(Oop));
-      return this;
-    }
-  }
-
-  bool eliminate = can_reshape && (dominating_barrier != NULL || !has_true_uses());
-  if (eliminate) {
-    if (can_reshape) {
-      PhaseIterGVN* igvn = phase->is_IterGVN();
-      Node* out_ctrl = proj_out_or_null(Control);
-      Node* out_res = proj_out_or_null(Oop);
+int ZBarrierSetC2::estimate_stub_size() const {
+  Compile* const C = Compile::current();
+  BufferBlob* const blob = C->scratch_buffer_blob();
+  GrowableArray<ZLoadBarrierStubC2*>* const stubs = barrier_set_state()->stubs();
+  int size = 0;
 
-      if (out_ctrl != NULL) {
-        igvn->replace_node(out_ctrl, ctrl);
-      }
-
-      // That transformation may cause the Similar edge on the load barrier to be invalid
-      fix_similar_in_uses(igvn);
-      if (out_res != NULL) {
-        if (dominating_barrier != NULL) {
-          assert(!is_weak(), "Sanity");
-          igvn->replace_node(out_res, dominating_barrier->proj_out(Oop));
-        } else {
-          igvn->replace_node(out_res, val);
-        }
-      }
-    }
-    return new ConINode(TypeInt::ZERO);
+  for (int i = 0; i < stubs->length(); i++) {
+    CodeBuffer cb(blob->content_begin(), (address)C->scratch_locs_memory() - blob->content_begin());
+    MacroAssembler masm(&cb);
+    ZBarrierSet::assembler()->generate_c2_load_barrier_stub(&masm, stubs->at(i));
+    size += cb.insts_size();
   }
 
-  // If the Similar edge is no longer a load barrier, clear it
-  Node* similar = in(Similar);
-  if (!similar->is_top() && !(similar->is_Proj() && similar->in(0)->is_LoadBarrier())) {
-    set_req(Similar, phase->C->top());
-    return this;
-  }
-
-  if (can_reshape && !is_weak()) {
-    // If this barrier is linked through the Similar edge by a
-    // dominated barrier and both barriers have the same Oop field,
-    // the dominated barrier can go away, so push it for reprocessing.
-    // We also want to avoid a barrier to depend on another dominating
-    // barrier through its Similar edge that itself depend on another
-    // barrier through its Similar edge and rather have the first
-    // depend on the third.
-    PhaseIterGVN* igvn = phase->is_IterGVN();
-    Node* out_res = proj_out(Oop);
-    for (DUIterator_Fast imax, i = out_res->fast_outs(imax); i < imax; i++) {
-      Node* u = out_res->fast_out(i);
-      if (u->is_LoadBarrier() && u->in(Similar) == out_res &&
-          (u->in(Oop) == val || !u->in(Similar)->is_top())) {
-        assert(!u->as_LoadBarrier()->is_weak(), "Sanity");
-        igvn->_worklist.push(u);
-      }
-    }
-    push_dominated_barriers(igvn);
-  }
-
-  return NULL;
-}
-
-uint LoadBarrierNode::match_edge(uint idx) const {
-  ShouldNotReachHere();
-  return 0;
-}
-
-void LoadBarrierNode::fix_similar_in_uses(PhaseIterGVN* igvn) {
-  Node* out_res = proj_out_or_null(Oop);
-  if (out_res == NULL) {
-    return;
-  }
-
-  for (DUIterator_Fast imax, i = out_res->fast_outs(imax); i < imax; i++) {
-    Node* u = out_res->fast_out(i);
-    if (u->is_LoadBarrier() && u->in(Similar) == out_res) {
-      igvn->replace_input_of(u, Similar, igvn->C->top());
-      --i;
-      --imax;
-    }
-  }
-}
-
-bool LoadBarrierNode::has_true_uses() const {
-  Node* out_res = proj_out_or_null(Oop);
-  if (out_res != NULL) {
-    for (DUIterator_Fast imax, i = out_res->fast_outs(imax); i < imax; i++) {
-      Node *u = out_res->fast_out(i);
-      if (!u->is_LoadBarrier() || u->in(Similar) != out_res) {
-        return true;
-      }
-    }
-  }
-  return false;
+  return size;
 }
 
 static bool barrier_needed(C2Access& access) {
@@ -474,1223 +180,252 @@
 }
 
 Node* ZBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const {
-  Node* p = BarrierSetC2::load_at_resolved(access, val_type);
-  if (!barrier_needed(access)) {
-    return p;
+  Node* result = BarrierSetC2::load_at_resolved(access, val_type);
+  if (barrier_needed(access) && access.raw_access()->is_Mem()) {
+    if ((access.decorators() & ON_WEAK_OOP_REF) != 0) {
+      access.raw_access()->as_Load()->set_barrier_data(ZLoadBarrierWeak);
+    } else {
+      access.raw_access()->as_Load()->set_barrier_data(ZLoadBarrierStrong);
+    }
   }
 
-  bool weak = (access.decorators() & ON_WEAK_OOP_REF) != 0;
-  if (p->isa_Load()) {
-    load_set_barrier(p->as_Load(), weak);
-  }
-  return p;
+  return result;
 }
 
 Node* ZBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access, Node* expected_val,
                                                     Node* new_val, const Type* val_type) const {
   Node* result = BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, val_type);
-  LoadStoreNode* lsn = result->as_LoadStore();
   if (barrier_needed(access)) {
-    lsn->set_has_barrier();
+    access.raw_access()->as_LoadStore()->set_barrier_data(ZLoadBarrierStrong);
   }
-  return lsn;
+  return result;
 }
 
 Node* ZBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicParseAccess& access, Node* expected_val,
                                                      Node* new_val, const Type* value_type) const {
   Node* result = BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type);
-  LoadStoreNode* lsn = result->as_LoadStore();
   if (barrier_needed(access)) {
-    lsn->set_has_barrier();
+    access.raw_access()->as_LoadStore()->set_barrier_data(ZLoadBarrierStrong);
   }
-  return lsn;
+  return result;
 }
 
 Node* ZBarrierSetC2::atomic_xchg_at_resolved(C2AtomicParseAccess& access, Node* new_val, const Type* val_type) const {
   Node* result = BarrierSetC2::atomic_xchg_at_resolved(access, new_val, val_type);
-  LoadStoreNode* lsn = result->as_LoadStore();
   if (barrier_needed(access)) {
-    lsn->set_has_barrier();
+    access.raw_access()->as_LoadStore()->set_barrier_data(ZLoadBarrierStrong);
   }
-  return lsn;
+  return result;
 }
 
-// == Macro Expansion ==
-
-// Optimized, low spill, loadbarrier variant using stub specialized on register used
-void ZBarrierSetC2::expand_loadbarrier_node(PhaseMacroExpand* phase, LoadBarrierNode* barrier) const {
-  PhaseIterGVN &igvn = phase->igvn();
-  float unlikely  = PROB_UNLIKELY(0.999);
-
-  Node* in_ctrl = barrier->in(LoadBarrierNode::Control);
-  Node* in_mem = barrier->in(LoadBarrierNode::Memory);
-  Node* in_val = barrier->in(LoadBarrierNode::Oop);
-  Node* in_adr = barrier->in(LoadBarrierNode::Address);
-
-  Node* out_ctrl = barrier->proj_out(LoadBarrierNode::Control);
-  Node* out_res = barrier->proj_out(LoadBarrierNode::Oop);
-
-  assert(barrier->in(LoadBarrierNode::Oop) != NULL, "oop to loadbarrier node cannot be null");
-
-  Node* jthread = igvn.transform(new ThreadLocalNode());
-  Node* adr = phase->basic_plus_adr(jthread, in_bytes(ZThreadLocalData::address_bad_mask_offset()));
-  Node* bad_mask = igvn.transform(LoadNode::make(igvn, in_ctrl, in_mem, adr,
-                                                 TypeRawPtr::BOTTOM, TypeX_X, TypeX_X->basic_type(),
-                                                 MemNode::unordered));
-  Node* cast = igvn.transform(new CastP2XNode(in_ctrl, in_val));
-  Node* obj_masked = igvn.transform(new AndXNode(cast, bad_mask));
-  Node* cmp = igvn.transform(new CmpXNode(obj_masked, igvn.zerocon(TypeX_X->basic_type())));
-  Node *bol = igvn.transform(new BoolNode(cmp, BoolTest::ne))->as_Bool();
-  IfNode* iff = igvn.transform(new IfNode(in_ctrl, bol, unlikely, COUNT_UNKNOWN))->as_If();
-  Node* then = igvn.transform(new IfTrueNode(iff));
-  Node* elsen = igvn.transform(new IfFalseNode(iff));
-
-  Node* new_loadp = igvn.transform(new LoadBarrierSlowRegNode(then, in_adr, in_val,
-                                                              (const TypePtr*) in_val->bottom_type(), barrier->is_weak()));
-
-  // Create the final region/phi pair to converge cntl/data paths to downstream code
-  Node* result_region = igvn.transform(new RegionNode(3));
-  result_region->set_req(1, then);
-  result_region->set_req(2, elsen);
-
-  Node* result_phi = igvn.transform(new PhiNode(result_region, TypeInstPtr::BOTTOM));
-  result_phi->set_req(1, new_loadp);
-  result_phi->set_req(2, barrier->in(LoadBarrierNode::Oop));
-
-  igvn.replace_node(out_ctrl, result_region);
-  igvn.replace_node(out_res, result_phi);
-
-  assert(barrier->outcnt() == 0,"LoadBarrier macro node has non-null outputs after expansion!");
-
-  igvn.remove_dead_node(barrier);
-  igvn.remove_dead_node(out_ctrl);
-  igvn.remove_dead_node(out_res);
-
-  assert(is_gc_barrier_node(result_phi), "sanity");
-  assert(step_over_gc_barrier(result_phi) == in_val, "sanity");
-
-  phase->C->print_method(PHASE_BARRIER_EXPANSION, 4, barrier->_idx);
+bool ZBarrierSetC2::array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type,
+                                                    bool is_clone, ArrayCopyPhase phase) const {
+  return type == T_OBJECT || type == T_ARRAY;
 }
 
-bool ZBarrierSetC2::expand_barriers(Compile* C, PhaseIterGVN& igvn) const {
-  ZBarrierSetC2State* s = state();
-  if (s->load_barrier_count() > 0) {
-    PhaseMacroExpand macro(igvn);
+// == Dominating barrier elision ==
 
-    int skipped = 0;
-    while (s->load_barrier_count() > skipped) {
-      int load_barrier_count = s->load_barrier_count();
-      LoadBarrierNode * n = s->load_barrier_node(load_barrier_count-1-skipped);
-      if (igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())) {
-        // Node is unreachable, so don't try to expand it
-        s->remove_load_barrier_node(n);
-        continue;
-      }
-      if (!n->can_be_eliminated()) {
-        skipped++;
-        continue;
-      }
-      expand_loadbarrier_node(&macro, n);
-      assert(s->load_barrier_count() < load_barrier_count, "must have deleted a node from load barrier list");
-      if (C->failing()) {
-        return true;
-      }
-    }
-    while (s->load_barrier_count() > 0) {
-      int load_barrier_count = s->load_barrier_count();
-      LoadBarrierNode* n = s->load_barrier_node(load_barrier_count - 1);
-      assert(!(igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())), "should have been processed already");
-      assert(!n->can_be_eliminated(), "should have been processed already");
-      expand_loadbarrier_node(&macro, n);
-      assert(s->load_barrier_count() < load_barrier_count, "must have deleted a node from load barrier list");
-      if (C->failing()) {
-        return true;
-      }
-    }
-    igvn.set_delay_transform(false);
-    igvn.optimize();
-    if (C->failing()) {
+static bool block_has_safepoint(const Block* block, uint from, uint to) {
+  for (uint i = from; i < to; i++) {
+    if (block->get_node(i)->is_MachSafePoint()) {
+      // Safepoint found
       return true;
     }
   }
 
+  // Safepoint not found
   return false;
 }
 
-Node* ZBarrierSetC2::step_over_gc_barrier(Node* c) const {
-  Node* node = c;
+static bool block_has_safepoint(const Block* block) {
+  return block_has_safepoint(block, 0, block->number_of_nodes());
+}
 
-  // 1. This step follows potential oop projections of a load barrier before expansion
-  if (node->is_Proj()) {
-    node = node->in(0);
+static uint block_index(const Block* block, const Node* node) {
+  for (uint j = 0; j < block->number_of_nodes(); ++j) {
+    if (block->get_node(j) == node) {
+      return j;
+    }
   }
+  ShouldNotReachHere();
+  return 0;
+}
+
+void ZBarrierSetC2::analyze_dominating_barriers() const {
+  ResourceMark rm;
+  Compile* const C = Compile::current();
+  PhaseCFG* const cfg = C->cfg();
+  Block_List worklist;
+  Node_List mem_ops;
+  Node_List barrier_loads;
 
-  // 2. This step checks for unexpanded load barriers
-  if (node->is_LoadBarrier()) {
-    return node->in(LoadBarrierNode::Oop);
-  }
+  // Step 1 - Find accesses, and track them in lists
+  for (uint i = 0; i < cfg->number_of_blocks(); ++i) {
+    const Block* const block = cfg->get_block(i);
+    for (uint j = 0; j < block->number_of_nodes(); ++j) {
+      const Node* const node = block->get_node(j);
+      if (!node->is_Mach()) {
+        continue;
+      }
 
-  // 3. This step checks for the phi corresponding to an optimized load barrier expansion
-  if (node->is_Phi()) {
-    PhiNode* phi = node->as_Phi();
-    Node* n = phi->in(1);
-    if (n != NULL && n->is_LoadBarrierSlowReg()) {
-      assert(c == node, "projections from step 1 should only be seen before macro expansion");
-      return phi->in(2);
+      MachNode* const mach = node->as_Mach();
+      switch (mach->ideal_Opcode()) {
+      case Op_LoadP:
+      case Op_CompareAndExchangeP:
+      case Op_CompareAndSwapP:
+      case Op_GetAndSetP:
+        if (mach->barrier_data() == ZLoadBarrierStrong) {
+          barrier_loads.push(mach);
+        }
+      case Op_StoreP:
+        mem_ops.push(mach);
+        break;
+
+      default:
+        break;
+      }
     }
   }
 
-  return c;
-}
-
-Node* ZBarrierSetC2::step_over_gc_barrier_ctrl(Node* c) const {
-  Node* node = c;
-
-  // 1. This step follows potential ctrl projections of a load barrier before expansion
-  if (node->is_Proj()) {
-    node = node->in(0);
-  }
-
-  // 2. This step checks for unexpanded load barriers
-  if (node->is_LoadBarrier()) {
-    return node->in(LoadBarrierNode::Control);
-  }
-
-  return c;
-}
-
-bool ZBarrierSetC2::array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const {
-  return is_reference_type(type);
-}
-
-bool ZBarrierSetC2::final_graph_reshaping(Compile* compile, Node* n, uint opcode) const {
-  switch (opcode) {
-    case Op_LoadBarrier:
-      assert(0, "There should be no load barriers left");
-    case Op_ZGetAndSetP:
-    case Op_ZCompareAndExchangeP:
-    case Op_ZCompareAndSwapP:
-    case Op_ZWeakCompareAndSwapP:
-#ifdef ASSERT
-      if (VerifyOptoOopOffsets) {
-        MemNode *mem = n->as_Mem();
-        // Check to see if address types have grounded out somehow.
-        const TypeInstPtr *tp = mem->in(MemNode::Address)->bottom_type()->isa_instptr();
-        ciInstanceKlass *k = tp->klass()->as_instance_klass();
-        bool oop_offset_is_sane = k->contains_field_offset(tp->offset());
-        assert(!tp || oop_offset_is_sane, "");
-      }
-#endif
-      return true;
-    default:
-      return false;
-  }
-}
+  // Step 2 - Find dominating accesses for each load
+  for (uint i = 0; i < barrier_loads.size(); i++) {
+    MachNode* const load = barrier_loads.at(i)->as_Mach();
+    const TypePtr* load_adr_type = NULL;
+    intptr_t load_offset = 0;
+    const Node* const load_obj = load->get_base_and_disp(load_offset, load_adr_type);
+    Block* const load_block = cfg->get_block_for_node(load);
+    const uint load_index = block_index(load_block, load);
 
-bool ZBarrierSetC2::matcher_find_shared_visit(Matcher* matcher, Matcher::MStack& mstack, Node* n, uint opcode, bool& mem_op, int& mem_addr_idx) const {
-  switch(opcode) {
-    case Op_CallLeaf:
-      if (n->as_Call()->entry_point() == ZBarrierSetRuntime::load_barrier_on_oop_field_preloaded_addr() ||
-          n->as_Call()->entry_point() == ZBarrierSetRuntime::load_barrier_on_weak_oop_field_preloaded_addr()) {
-        mem_op = true;
-        mem_addr_idx = TypeFunc::Parms + 1;
-        return true;
-      }
-      return false;
-    default:
-      return false;
-  }
-}
-
-bool ZBarrierSetC2::matcher_find_shared_post_visit(Matcher* matcher, Node* n, uint opcode) const {
-  switch(opcode) {
-    case Op_ZCompareAndExchangeP:
-    case Op_ZCompareAndSwapP:
-    case Op_ZWeakCompareAndSwapP: {
-      Node *mem = n->in(MemNode::Address);
-      Node *keepalive = n->in(5);
-      Node *pair1 = new BinaryNode(mem, keepalive);
-
-      Node *newval = n->in(MemNode::ValueIn);
-      Node *oldval = n->in(LoadStoreConditionalNode::ExpectedIn);
-      Node *pair2 = new BinaryNode(oldval, newval);
+    for (uint j = 0; j < mem_ops.size(); j++) {
+      MachNode* mem = mem_ops.at(j)->as_Mach();
+      const TypePtr* mem_adr_type = NULL;
+      intptr_t mem_offset = 0;
+      const Node* mem_obj = mem_obj = mem->get_base_and_disp(mem_offset, mem_adr_type);
+      Block* mem_block = cfg->get_block_for_node(mem);
+      uint mem_index = block_index(mem_block, mem);
 
-      n->set_req(MemNode::Address, pair1);
-      n->set_req(MemNode::ValueIn, pair2);
-      n->del_req(5);
-      n->del_req(LoadStoreConditionalNode::ExpectedIn);
-      return true;
-    }
-    case Op_ZGetAndSetP: {
-      Node *keepalive = n->in(4);
-      Node *newval = n->in(MemNode::ValueIn);
-      Node *pair = new BinaryNode(newval, keepalive);
-      n->set_req(MemNode::ValueIn, pair);
-      n->del_req(4);
-      return true;
-    }
+      if (load_obj == NodeSentinel || mem_obj == NodeSentinel ||
+          load_obj == NULL || mem_obj == NULL ||
+          load_offset < 0 || mem_offset < 0) {
+        continue;
+      }
 
-    default:
-      return false;
-  }
-}
-
-// == Verification ==
-
-#ifdef ASSERT
-
-static void verify_slippery_safepoints_internal(Node* ctrl) {
-  // Given a CFG node, make sure it does not contain both safepoints and loads
-  // that have expanded barriers.
-  bool found_safepoint = false;
-  bool found_load = false;
+      if (mem_obj != load_obj || mem_offset != load_offset) {
+        // Not the same addresses, not a candidate
+        continue;
+      }
 
-  for (DUIterator_Fast imax, i = ctrl->fast_outs(imax); i < imax; i++) {
-    Node* node = ctrl->fast_out(i);
-    if (node->in(0) != ctrl) {
-      // Skip outgoing precedence edges from ctrl.
-      continue;
-    }
-    if (node->is_SafePoint()) {
-      found_safepoint = true;
-    }
-    if (node->is_Load() && load_require_barrier(node->as_Load()) &&
-        load_has_expanded_barrier(node->as_Load())) {
-      found_load = true;
-    }
-  }
-  assert(!found_safepoint || !found_load, "found load and safepoint in same block");
-}
-
-static void verify_slippery_safepoints(Compile* C) {
-  ResourceArea *area = Thread::current()->resource_area();
-  Unique_Node_List visited(area);
-  Unique_Node_List checked(area);
-
-  // Recursively walk the graph.
-  visited.push(C->root());
-  while (visited.size() > 0) {
-    Node* node = visited.pop();
-
-    Node* ctrl = node;
-    if (!node->is_CFG()) {
-      ctrl = node->in(0);
-    }
-
-    if (ctrl != NULL && !checked.member(ctrl)) {
-      // For each block found in the graph, verify that it does not
-      // contain both a safepoint and a load requiring barriers.
-      verify_slippery_safepoints_internal(ctrl);
-
-      checked.push(ctrl);
-    }
-
-    checked.push(node);
-
-    for (DUIterator_Fast imax, i = node->fast_outs(imax); i < imax; i++) {
-      Node* use = node->fast_out(i);
-      if (checked.member(use))  continue;
-      if (visited.member(use))  continue;
-      visited.push(use);
-    }
-  }
-}
+      if (load_block == mem_block) {
+        // Earlier accesses in the same block
+        if (mem_index < load_index && !block_has_safepoint(mem_block, mem_index + 1, load_index)) {
+          load->set_barrier_data(ZLoadBarrierElided);
+        }
+      } else if (mem_block->dominates(load_block)) {
+        // Dominating block? Look around for safepoints
+        ResourceMark rm;
+        Block_List stack;
+        VectorSet visited(Thread::current()->resource_area());
+        stack.push(load_block);
+        bool safepoint_found = block_has_safepoint(load_block);
+        while (!safepoint_found && stack.size() > 0) {
+          Block* block = stack.pop();
+          if (visited.test_set(block->_pre_order)) {
+            continue;
+          }
+          if (block_has_safepoint(block)) {
+            safepoint_found = true;
+            break;
+          }
+          if (block == mem_block) {
+            continue;
+          }
 
-void ZBarrierSetC2::verify_gc_barriers(Compile* compile, CompilePhase phase) const {
-  switch(phase) {
-    case BarrierSetC2::BeforeOptimize:
-    case BarrierSetC2::BeforeLateInsertion:
-      assert(state()->load_barrier_count() == 0, "No barriers inserted yet");
-      break;
-    case BarrierSetC2::BeforeMacroExpand:
-      // Barrier placement should be set by now.
-      verify_gc_barriers(false /*post_parse*/);
-      break;
-    case BarrierSetC2::BeforeCodeGen:
-      // Barriers has been fully expanded.
-      assert(state()->load_barrier_count() == 0, "No more macro barriers");
-      verify_slippery_safepoints(compile);
-      break;
-    default:
-      assert(0, "Phase without verification");
-  }
-}
-
-// post_parse implies that there might be load barriers without uses after parsing
-// That only applies when adding barriers at parse time.
-void ZBarrierSetC2::verify_gc_barriers(bool post_parse) const {
-  ZBarrierSetC2State* s = state();
-  Compile* C = Compile::current();
-  ResourceMark rm;
-  VectorSet visited(Thread::current()->resource_area());
-
-  for (int i = 0; i < s->load_barrier_count(); i++) {
-    LoadBarrierNode* n = s->load_barrier_node(i);
-
-    // The dominating barrier on the same address if it exists and
-    // this barrier must not be applied on the value from the same
-    // load otherwise the value is not reloaded before it's used the
-    // second time.
-    assert(n->in(LoadBarrierNode::Similar)->is_top() ||
-           (n->in(LoadBarrierNode::Similar)->in(0)->is_LoadBarrier() &&
-            n->in(LoadBarrierNode::Similar)->in(0)->in(LoadBarrierNode::Address) == n->in(LoadBarrierNode::Address) &&
-            n->in(LoadBarrierNode::Similar)->in(0)->in(LoadBarrierNode::Oop) != n->in(LoadBarrierNode::Oop)),
-           "broken similar edge");
-
-    assert(n->as_LoadBarrier()->has_true_uses(),
-           "found unneeded load barrier");
-
-    // Several load barrier nodes chained through their Similar edge
-    // break the code that remove the barriers in final graph reshape.
-    assert(n->in(LoadBarrierNode::Similar)->is_top() ||
-           (n->in(LoadBarrierNode::Similar)->in(0)->is_LoadBarrier() &&
-            n->in(LoadBarrierNode::Similar)->in(0)->in(LoadBarrierNode::Similar)->is_top()),
-           "chain of Similar load barriers");
-
-    if (!n->in(LoadBarrierNode::Similar)->is_top()) {
-      ResourceMark rm;
-      Unique_Node_List wq;
-      Node* other = n->in(LoadBarrierNode::Similar)->in(0);
-      wq.push(n);
-      for (uint next = 0; next < wq.size(); ++next) {
-        Node *nn = wq.at(next);
-        assert(nn->is_CFG(), "");
-        assert(!nn->is_SafePoint(), "");
-
-        if (nn == other) {
-          continue;
+          // Push predecessor blocks
+          for (uint p = 1; p < block->num_preds(); ++p) {
+            Block* pred = cfg->get_block_for_node(block->pred(p));
+            stack.push(pred);
+          }
         }
 
-        if (nn->is_Region()) {
-          for (uint i = 1; i < nn->req(); i++) {
-            Node* m = nn->in(i);
-            if (m != NULL) {
-              wq.push(m);
-            }
-          }
-        } else {
-          Node* m = nn->in(0);
-          if (m != NULL) {
-            wq.push(m);
-          }
+        if (!safepoint_found) {
+          load->set_barrier_data(ZLoadBarrierElided);
         }
       }
     }
   }
 }
 
-#endif // end verification code
-
-// If a call is the control, we actually want its control projection
-static Node* normalize_ctrl(Node* node) {
- if (node->is_Call()) {
-   node = node->as_Call()->proj_out(TypeFunc::Control);
- }
- return node;
-}
-
-static Node* get_ctrl_normalized(PhaseIdealLoop *phase, Node* node) {
-  return normalize_ctrl(phase->get_ctrl(node));
-}
-
-static void call_catch_cleanup_one(PhaseIdealLoop* phase, LoadNode* load, Node* ctrl);
-
-// This code is cloning all uses of a load that is between a call and the catch blocks,
-// to each use.
-
-static bool fixup_uses_in_catch(PhaseIdealLoop *phase, Node *start_ctrl, Node *node) {
-
-  if (!phase->has_ctrl(node)) {
-    // This node is floating - doesn't need to be cloned.
-    assert(node != start_ctrl, "check");
-    return false;
-  }
-
-  Node* ctrl = get_ctrl_normalized(phase, node);
-  if (ctrl != start_ctrl) {
-    // We are in a successor block - the node is ok.
-    return false; // Unwind
-  }
-
-  // Process successor nodes
-  int outcnt = node->outcnt();
-  for (int i = 0; i < outcnt; i++) {
-    Node* n = node->raw_out(0);
-    assert(!n->is_LoadBarrier(), "Sanity");
-    // Calling recursively, visiting leafs first
-    fixup_uses_in_catch(phase, start_ctrl, n);
-  }
-
-  // Now all successors are outside
-  // - Clone this node to both successors
-  assert(!node->is_Store(), "Stores not expected here");
-
-  // In some very rare cases a load that doesn't need a barrier will end up here
-  // Treat it as a LoadP and the insertion of phis will be done correctly.
-  if (node->is_Load()) {
-    call_catch_cleanup_one(phase, node->as_Load(), phase->get_ctrl(node));
-  } else {
-    for (DUIterator_Fast jmax, i = node->fast_outs(jmax); i < jmax; i++) {
-      Node* use = node->fast_out(i);
-      Node* clone = node->clone();
-      assert(clone->outcnt() == 0, "");
+// == Reduced spilling optimization ==
 
-      assert(use->find_edge(node) != -1, "check");
-      phase->igvn().rehash_node_delayed(use);
-      use->replace_edge(node, clone);
-
-      Node* new_ctrl;
-      if (use->is_block_start()) {
-        new_ctrl = use;
-      } else if (use->is_CFG()) {
-        new_ctrl = use->in(0);
-        assert (new_ctrl != NULL, "");
-      } else {
-        new_ctrl = get_ctrl_normalized(phase, use);
-      }
-
-      phase->set_ctrl(clone, new_ctrl);
-
-      if (phase->C->directive()->ZTraceLoadBarriersOption) tty->print_cr("  Clone op %i as %i to control %i", node->_idx, clone->_idx, new_ctrl->_idx);
-      phase->igvn().register_new_node_with_optimizer(clone);
-      --i, --jmax;
-    }
-    assert(node->outcnt() == 0, "must be empty now");
-
-    // Node node is dead.
-    phase->igvn().remove_dead_node(node);
-  }
-  return true; // unwind - return if a use was processed
-}
+void ZBarrierSetC2::compute_liveness_at_stubs() const {
+  ResourceMark rm;
+  Compile* const C = Compile::current();
+  Arena* const A = Thread::current()->resource_area();
+  PhaseCFG* const cfg = C->cfg();
+  PhaseRegAlloc* const regalloc = C->regalloc();
+  RegMask* const live = NEW_ARENA_ARRAY(A, RegMask, cfg->number_of_blocks() * sizeof(RegMask));
+  ZBarrierSetAssembler* const bs = ZBarrierSet::assembler();
+  Block_List worklist;
 
-// Clone a load to a specific catch_proj
-static Node* clone_load_to_catchproj(PhaseIdealLoop* phase, Node* load, Node* catch_proj) {
-  Node* cloned_load = load->clone();
-  cloned_load->set_req(0, catch_proj);      // set explicit control
-  phase->set_ctrl(cloned_load, catch_proj); // update
-  if (phase->C->directive()->ZTraceLoadBarriersOption) tty->print_cr("  Clone LOAD %i as %i to control %i", load->_idx, cloned_load->_idx, catch_proj->_idx);
-  phase->igvn().register_new_node_with_optimizer(cloned_load);
-  return cloned_load;
-}
-
-static Node* get_dominating_region(PhaseIdealLoop* phase, Node* node, Node* stop) {
-  Node* region = node;
-  while (!region->isa_Region()) {
-    Node *up = phase->idom(region);
-    assert(up != region, "Must not loop");
-    assert(up != stop,   "Must not find original control");
-    region = up;
-  }
-  return region;
-}
-
-// Clone this load to each catch block
-static void call_catch_cleanup_one(PhaseIdealLoop* phase, LoadNode* load, Node* ctrl) {
-  bool trace = phase->C->directive()->ZTraceLoadBarriersOption;
-  phase->igvn().set_delay_transform(true);
-
-  // Verify pre conditions
-  assert(ctrl->isa_Proj() && ctrl->in(0)->isa_Call(), "Must be a call proj");
-  assert(ctrl->raw_out(0)->isa_Catch(), "Must be a catch");
-
-  if (ctrl->raw_out(0)->isa_Catch()->outcnt() == 1) {
-    if (trace) tty->print_cr("Cleaning up catch: Skipping load %i, call with single catch", load->_idx);
-    return;
+  for (uint i = 0; i < cfg->number_of_blocks(); ++i) {
+    new ((void*)(live + i)) RegMask();
+    worklist.push(cfg->get_block(i));
   }
 
-  // Process the loads successor nodes - if any is between
-  // the call and the catch blocks, they need to be cloned to.
-  // This is done recursively
-  for (uint i = 0; i < load->outcnt();) {
-    Node *n = load->raw_out(i);
-    assert(!n->is_LoadBarrier(), "Sanity");
-    if (!fixup_uses_in_catch(phase, ctrl, n)) {
-      // if no successor was cloned, progress to next out.
-      i++;
-    }
-  }
-
-  // Now all the loads uses has been cloned down
-  // Only thing left is to clone the loads, but they must end up
-  // first in the catch blocks.
-
-  // We clone the loads oo the catch blocks only when needed.
-  // An array is used to map the catch blocks to each lazily cloned load.
-  // In that way no extra unnecessary loads are cloned.
-
-  // Any use dominated by original block must have an phi and a region added
-
-  Node* catch_node = ctrl->raw_out(0);
-  int number_of_catch_projs = catch_node->outcnt();
-  Node** proj_to_load_mapping = NEW_RESOURCE_ARRAY(Node*, number_of_catch_projs);
-  Copy::zero_to_bytes(proj_to_load_mapping, sizeof(Node*) * number_of_catch_projs);
-
-  // The phi_map is used to keep track of where phis have already been inserted
-  int phi_map_len = phase->C->unique();
-  Node** phi_map = NEW_RESOURCE_ARRAY(Node*, phi_map_len);
-  Copy::zero_to_bytes(phi_map, sizeof(Node*) * phi_map_len);
+  while (worklist.size() > 0) {
+    const Block* const block = worklist.pop();
+    RegMask& old_live = live[block->_pre_order];
+    RegMask new_live;
 
-  for (unsigned int i = 0; i  < load->outcnt(); i++) {
-    Node* load_use_control = NULL;
-    Node* load_use = load->raw_out(i);
-
-    if (phase->has_ctrl(load_use)) {
-      load_use_control = get_ctrl_normalized(phase, load_use);
-      assert(load_use_control != ctrl, "sanity");
-    } else {
-      load_use_control = load_use->in(0);
-    }
-    assert(load_use_control != NULL, "sanity");
-    if (trace) tty->print_cr("  Handling use: %i, with control: %i", load_use->_idx, load_use_control->_idx);
-
-    // Some times the loads use is a phi. For them we need to determine from which catch block
-    // the use is defined.
-    bool load_use_is_phi = false;
-    unsigned int load_use_phi_index = 0;
-    Node* phi_ctrl = NULL;
-    if (load_use->is_Phi()) {
-      // Find phi input that matches load
-      for (unsigned int u = 1; u < load_use->req(); u++) {
-        if (load_use->in(u) == load) {
-          load_use_is_phi = true;
-          load_use_phi_index = u;
-          assert(load_use->in(0)->is_Region(), "Region or broken");
-          phi_ctrl = load_use->in(0)->in(u);
-          assert(phi_ctrl->is_CFG(), "check");
-          assert(phi_ctrl != load,   "check");
-          break;
-        }
-      }
-      assert(load_use_is_phi,        "must find");
-      assert(load_use_phi_index > 0, "sanity");
+    // Initialize to union of successors
+    for (uint i = 0; i < block->_num_succs; i++) {
+      const uint succ_id = block->_succs[i]->_pre_order;
+      new_live.OR(live[succ_id]);
     }
 
-    // For each load use, see which catch projs dominates, create load clone lazily and reconnect
-    bool found_dominating_catchproj = false;
-    for (int c = 0; c < number_of_catch_projs; c++) {
-      Node* catchproj = catch_node->raw_out(c);
-      assert(catchproj != NULL && catchproj->isa_CatchProj(), "Sanity");
-
-      if (!phase->is_dominator(catchproj, load_use_control)) {
-        if (load_use_is_phi && phase->is_dominator(catchproj, phi_ctrl)) {
-          // The loads use is local to the catchproj.
-          // fall out and replace load with catch-local load clone.
-        } else {
-          continue;
-        }
-      }
-      assert(!found_dominating_catchproj, "Max one should match");
-
-      // Clone loads to catch projs
-      Node* load_clone = proj_to_load_mapping[c];
-      if (load_clone == NULL) {
-        load_clone = clone_load_to_catchproj(phase, load, catchproj);
-        proj_to_load_mapping[c] = load_clone;
-      }
-      phase->igvn().rehash_node_delayed(load_use);
+    // Walk block backwards, computing liveness
+    for (int i = block->number_of_nodes() - 1; i >= 0; --i) {
+      const Node* const node = block->get_node(i);
 
-      if (load_use_is_phi) {
-        // phis are special - the load is defined from a specific control flow
-        load_use->set_req(load_use_phi_index, load_clone);
-      } else {
-        // Multipe edges can be replaced at once - on calls for example
-        load_use->replace_edge(load, load_clone);
+      // Remove def bits
+      const OptoReg::Name first = bs->refine_register(node, regalloc->get_reg_first(node));
+      const OptoReg::Name second = bs->refine_register(node, regalloc->get_reg_second(node));
+      if (first != OptoReg::Bad) {
+        new_live.Remove(first);
       }
-      --i; // more than one edge can have been removed, but the next is in later iterations
-
-      // We could break the for-loop after finding a dominating match.
-      // But keep iterating to catch any bad idom early.
-      found_dominating_catchproj = true;
-    }
+      if (second != OptoReg::Bad) {
+        new_live.Remove(second);
+      }
 
-    // We found no single catchproj that dominated the use - The use is at a point after
-    // where control flow from multiple catch projs have merged. We will have to create
-    // phi nodes before the use and tie the output from the cloned loads together. It
-    // can be a single phi or a number of chained phis, depending on control flow
-    if (!found_dominating_catchproj) {
-
-      // Use phi-control if use is a phi
-      if (load_use_is_phi) {
-        load_use_control = phi_ctrl;
-      }
-      assert(phase->is_dominator(ctrl, load_use_control), "Common use but no dominator");
-
-      // Clone a load on all paths
-      for (int c = 0; c < number_of_catch_projs; c++) {
-        Node* catchproj = catch_node->raw_out(c);
-        Node* load_clone = proj_to_load_mapping[c];
-        if (load_clone == NULL) {
-          load_clone = clone_load_to_catchproj(phase, load, catchproj);
-          proj_to_load_mapping[c] = load_clone;
+      // Add use bits
+      for (uint j = 1; j < node->req(); ++j) {
+        const Node* const use = node->in(j);
+        const OptoReg::Name first = bs->refine_register(use, regalloc->get_reg_first(use));
+        const OptoReg::Name second = bs->refine_register(use, regalloc->get_reg_second(use));
+        if (first != OptoReg::Bad) {
+          new_live.Insert(first);
+        }
+        if (second != OptoReg::Bad) {
+          new_live.Insert(second);
         }
       }
 
-      // Move up dominator tree from use until dom front is reached
-      Node* next_region = get_dominating_region(phase, load_use_control, ctrl);
-      while (phase->idom(next_region) != catch_node) {
-        next_region = phase->idom(next_region);
-        if (trace) tty->print_cr("Moving up idom to region ctrl %i", next_region->_idx);
-      }
-      assert(phase->is_dominator(catch_node, next_region), "Sanity");
-
-      // Create or reuse phi node that collect all cloned loads and feed it to the use.
-      Node* test_phi = phi_map[next_region->_idx];
-      if ((test_phi != NULL) && test_phi->is_Phi()) {
-        // Reuse an already created phi
-        if (trace) tty->print_cr("    Using cached Phi %i on load_use %i", test_phi->_idx, load_use->_idx);
-        phase->igvn().rehash_node_delayed(load_use);
-        load_use->replace_edge(load, test_phi);
-        // Now this use is done
-      } else {
-        // Otherwise we need to create one or more phis
-        PhiNode* next_phi = new PhiNode(next_region, load->type());
-        phi_map[next_region->_idx] = next_phi; // cache new phi
-        phase->igvn().rehash_node_delayed(load_use);
-        load_use->replace_edge(load, next_phi);
-
-        int dominators_of_region = 0;
-        do {
-          // New phi, connect to region and add all loads as in.
-          Node* region = next_region;
-          assert(region->isa_Region() && region->req() > 2, "Catch dead region nodes");
-          PhiNode* new_phi = next_phi;
-
-          if (trace) tty->print_cr("Created Phi %i on load %i with control %i", new_phi->_idx, load->_idx, region->_idx);
-
-          // Need to add all cloned loads to the phi, taking care that the right path is matched
-          dominators_of_region = 0; // reset for new region
-          for (unsigned int reg_i = 1; reg_i < region->req(); reg_i++) {
-            Node* region_pred = region->in(reg_i);
-            assert(region_pred->is_CFG(), "check");
-            bool pred_has_dominator = false;
-            for (int c = 0; c < number_of_catch_projs; c++) {
-              Node* catchproj = catch_node->raw_out(c);
-              if (phase->is_dominator(catchproj, region_pred)) {
-                new_phi->set_req(reg_i, proj_to_load_mapping[c]);
-                if (trace) tty->print_cr(" - Phi in(%i) set to load %i", reg_i, proj_to_load_mapping[c]->_idx);
-                pred_has_dominator = true;
-                dominators_of_region++;
-                break;
-              }
-            }
-
-            // Sometimes we need to chain several phis.
-            if (!pred_has_dominator) {
-              assert(dominators_of_region <= 1, "More than one region can't require extra phi");
-              if (trace) tty->print_cr(" - Region %i pred %i not dominated by catch proj", region->_idx, region_pred->_idx);
-              // Continue search on on this region_pred
-              // - walk up to next region
-              // - create a new phi and connect to first new_phi
-              next_region = get_dominating_region(phase, region_pred, ctrl);
-
-              // Lookup if there already is a phi, create a new otherwise
-              Node* test_phi = phi_map[next_region->_idx];
-              if ((test_phi != NULL) && test_phi->is_Phi()) {
-                next_phi = test_phi->isa_Phi();
-                dominators_of_region++; // record that a match was found and that we are done
-                if (trace) tty->print_cr("    Using cached phi Phi %i on control %i", next_phi->_idx, next_region->_idx);
-              } else {
-                next_phi = new PhiNode(next_region, load->type());
-                phi_map[next_region->_idx] = next_phi;
-              }
-              new_phi->set_req(reg_i, next_phi);
-            }
-          }
-
-          new_phi->set_req(0, region);
-          phase->igvn().register_new_node_with_optimizer(new_phi);
-          phase->set_ctrl(new_phi, region);
-
-          assert(dominators_of_region != 0, "Must have found one this iteration");
-        } while (dominators_of_region == 1);
-      }
-      --i;
-    }
-  } // end of loop over uses
-
-  assert(load->outcnt() == 0, "All uses should be handled");
-  phase->igvn().remove_dead_node(load);
-  phase->C->print_method(PHASE_CALL_CATCH_CLEANUP, 4, load->_idx);
-
-  // Now we should be home
-  phase->igvn().set_delay_transform(false);
-}
-
-// Sort out the loads that are between a call ant its catch blocks
-static void process_catch_cleanup_candidate(PhaseIdealLoop* phase, LoadNode* load, bool verify) {
-  bool trace = phase->C->directive()->ZTraceLoadBarriersOption;
-
-  Node* ctrl = get_ctrl_normalized(phase, load);
-  if (!ctrl->is_Proj() || (ctrl->in(0) == NULL) || !ctrl->in(0)->isa_Call()) {
-    return;
-  }
-
-  Node* catch_node = ctrl->isa_Proj()->raw_out(0);
-  if (catch_node->is_Catch()) {
-    if (catch_node->outcnt() > 1) {
-      assert(!verify, "All loads should already have been moved");
-      call_catch_cleanup_one(phase, load, ctrl);
-    } else {
-      if (trace) tty->print_cr("Call catch cleanup with only one catch: load %i ", load->_idx);
-    }
-  }
-}
-
-void ZBarrierSetC2::barrier_insertion_phase(Compile* C, PhaseIterGVN& igvn) const {
-  PhaseIdealLoop::optimize(igvn, LoopOptsZBarrierInsertion);
-  if (C->failing())  return;
-}
-
-bool ZBarrierSetC2::optimize_loops(PhaseIdealLoop* phase, LoopOptsMode mode, VectorSet& visited, Node_Stack& nstack, Node_List& worklist) const {
-
-  if (mode == LoopOptsZBarrierInsertion) {
-    // First make sure all loads between call and catch are moved to the catch block
-    clean_catch_blocks(phase);
-    DEBUG_ONLY(clean_catch_blocks(phase, true /* verify */);)
-
-    // Then expand barriers on all loads
-    insert_load_barriers(phase);
-
-    // Handle all Unsafe that need barriers.
-    insert_barriers_on_unsafe(phase);
-
-    phase->C->clear_major_progress();
-    return true;
-  } else {
-    return false;
-  }
-}
-
-static bool can_simplify_cas(LoadStoreNode* node) {
-  if (node->isa_LoadStoreConditional()) {
-    Node *expected_in = node->as_LoadStoreConditional()->in(LoadStoreConditionalNode::ExpectedIn);
-    return (expected_in->get_ptr_type() == TypePtr::NULL_PTR);
-  } else {
-    return false;
-  }
-}
-
-static void insert_barrier_before_unsafe(PhaseIdealLoop* phase, LoadStoreNode* old_node) {
-
-  Compile *C = phase->C;
-  PhaseIterGVN &igvn = phase->igvn();
-  LoadStoreNode* zclone = NULL;
-
-  Node *in_ctrl = old_node->in(MemNode::Control);
-  Node *in_mem  = old_node->in(MemNode::Memory);
-  Node *in_adr  = old_node->in(MemNode::Address);
-  Node *in_val  = old_node->in(MemNode::ValueIn);
-  const TypePtr *adr_type = old_node->adr_type();
-  const TypePtr* load_type = TypeOopPtr::BOTTOM; // The type for the load we are adding
-
-  switch (old_node->Opcode()) {
-    case Op_CompareAndExchangeP: {
-      zclone = new ZCompareAndExchangePNode(in_ctrl, in_mem, in_adr, in_val, old_node->in(LoadStoreConditionalNode::ExpectedIn),
-              adr_type, old_node->get_ptr_type(), ((CompareAndExchangeNode*)old_node)->order());
-      load_type = old_node->bottom_type()->is_ptr();
-      break;
-    }
-    case Op_WeakCompareAndSwapP: {
-      if (can_simplify_cas(old_node)) {
-        break;
-      }
-      zclone = new ZWeakCompareAndSwapPNode(in_ctrl, in_mem, in_adr, in_val, old_node->in(LoadStoreConditionalNode::ExpectedIn),
-              ((CompareAndSwapNode*)old_node)->order());
-      adr_type = TypePtr::BOTTOM;
-      break;
-    }
-    case Op_CompareAndSwapP: {
-      if (can_simplify_cas(old_node)) {
-        break;
-      }
-      zclone = new ZCompareAndSwapPNode(in_ctrl, in_mem, in_adr, in_val, old_node->in(LoadStoreConditionalNode::ExpectedIn),
-              ((CompareAndSwapNode*)old_node)->order());
-      adr_type = TypePtr::BOTTOM;
-      break;
-    }
-    case Op_GetAndSetP: {
-      zclone = new ZGetAndSetPNode(in_ctrl, in_mem, in_adr, in_val, old_node->adr_type(), old_node->get_ptr_type());
-      load_type = old_node->bottom_type()->is_ptr();
-      break;
-    }
-  }
-  if (zclone != NULL) {
-    igvn.register_new_node_with_optimizer(zclone, old_node);
-
-    // Make load
-    LoadPNode *load = new LoadPNode(NULL, in_mem, in_adr, adr_type, load_type, MemNode::unordered,
-                                    LoadNode::DependsOnlyOnTest);
-    load_set_expanded_barrier(load);
-    igvn.register_new_node_with_optimizer(load);
-    igvn.replace_node(old_node, zclone);
-
-    Node *barrier = new LoadBarrierNode(C, NULL, in_mem, load, in_adr, false /* weak */);
-    Node *barrier_val = new ProjNode(barrier, LoadBarrierNode::Oop);
-    Node *barrier_ctrl = new ProjNode(barrier, LoadBarrierNode::Control);
-
-    igvn.register_new_node_with_optimizer(barrier);
-    igvn.register_new_node_with_optimizer(barrier_val);
-    igvn.register_new_node_with_optimizer(barrier_ctrl);
-
-    // loop over all of in_ctrl usages and move to barrier_ctrl
-    for (DUIterator_Last imin, i = in_ctrl->last_outs(imin); i >= imin; --i) {
-      Node *use = in_ctrl->last_out(i);
-      uint l;
-      for (l = 0; use->in(l) != in_ctrl; l++) {}
-      igvn.replace_input_of(use, l, barrier_ctrl);
-    }
-
-    load->set_req(MemNode::Control, in_ctrl);
-    barrier->set_req(LoadBarrierNode::Control, in_ctrl);
-    zclone->add_req(barrier_val); // add req as keep alive.
-
-    C->print_method(PHASE_ADD_UNSAFE_BARRIER, 4, zclone->_idx);
-  }
-}
-
-void ZBarrierSetC2::insert_barriers_on_unsafe(PhaseIdealLoop* phase) const {
-  Compile *C = phase->C;
-  PhaseIterGVN &igvn = phase->igvn();
-  uint new_ids = C->unique();
-  VectorSet visited(Thread::current()->resource_area());
-  GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, NULL);
-  nodeStack.push(C->root());
-  visited.test_set(C->root()->_idx);
-
-  // Traverse all nodes, visit all unsafe ops that require a barrier
-  while (nodeStack.length() > 0) {
-    Node *n = nodeStack.pop();
-
-    bool is_old_node = (n->_idx < new_ids); // don't process nodes that were created during cleanup
-    if (is_old_node) {
-      if (n->is_LoadStore()) {
-        LoadStoreNode* lsn = n->as_LoadStore();
-        if (lsn->has_barrier()) {
-          BasicType bt = lsn->in(MemNode::Address)->bottom_type()->basic_type();
-          assert (is_reference_type(bt), "Sanity test");
-          insert_barrier_before_unsafe(phase, lsn);
-        }
-      }
-    }
-    for (uint i = 0; i < n->len(); i++) {
-      if (n->in(i)) {
-        if (!visited.test_set(n->in(i)->_idx)) {
-          nodeStack.push(n->in(i));
-        }
-      }
-    }
-  }
-
-  igvn.optimize();
-  C->print_method(PHASE_ADD_UNSAFE_BARRIER, 2);
-}
-
-// The purpose of ZBarrierSetC2::clean_catch_blocks is to prepare the IR for
-// splicing in load barrier nodes.
-//
-// The problem is that we might have instructions between a call and its catch nodes.
-// (This is usually handled in PhaseCFG:call_catch_cleanup, which clones mach nodes in
-// already scheduled blocks.) We can't have loads that require barriers there,
-// because we need to splice in new control flow, and that would violate the IR.
-//
-// clean_catch_blocks find all Loads that require a barrier and clone them and any
-// dependent instructions to each use. The loads must be in the beginning of the catch block
-// before any store.
-//
-// Sometimes the loads use will be at a place dominated by all catch blocks, then we need
-// a load in each catch block, and a Phi at the dominated use.
-
-void ZBarrierSetC2::clean_catch_blocks(PhaseIdealLoop* phase, bool verify) const {
-
-  Compile *C = phase->C;
-  uint new_ids = C->unique();
-  PhaseIterGVN &igvn = phase->igvn();
-  VectorSet visited(Thread::current()->resource_area());
-  GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, NULL);
-  nodeStack.push(C->root());
-  visited.test_set(C->root()->_idx);
-
-  // Traverse all nodes, visit all loads that require a barrier
-  while(nodeStack.length() > 0) {
-    Node *n = nodeStack.pop();
-
-    for (uint i = 0; i < n->len(); i++) {
-      if (n->in(i)) {
-        if (!visited.test_set(n->in(i)->_idx)) {
-          nodeStack.push(n->in(i));
-        }
+      // If this node tracks liveness, update it
+      RegMask* const regs = barrier_set_state()->live(node);
+      if (regs != NULL) {
+        regs->OR(new_live);
       }
     }
 
-    bool is_old_node = (n->_idx < new_ids); // don't process nodes that were created during cleanup
-    if (n->is_Load() && is_old_node) {
-      LoadNode* load = n->isa_Load();
-      // only care about loads that will have a barrier
-      if (load_require_barrier(load)) {
-        process_catch_cleanup_candidate(phase, load, verify);
-      }
-    }
-  }
-
-  C->print_method(PHASE_CALL_CATCH_CLEANUP, 2);
-}
-
-class DomDepthCompareClosure : public CompareClosure<LoadNode*> {
-  PhaseIdealLoop* _phase;
-
-public:
-  DomDepthCompareClosure(PhaseIdealLoop* phase) : _phase(phase) { }
-
-  int do_compare(LoadNode* const &n1, LoadNode* const &n2) {
-    int d1 = _phase->dom_depth(_phase->get_ctrl(n1));
-    int d2 = _phase->dom_depth(_phase->get_ctrl(n2));
-    if (d1 == d2) {
-      // Compare index if the depth is the same, ensures all entries are unique.
-      return n1->_idx - n2->_idx;
-    } else {
-      return d2 - d1;
-    }
-  }
-};
-
-// Traverse graph and add all loadPs to list, sorted by dom depth
-void gather_loadnodes_sorted(PhaseIdealLoop* phase, GrowableArray<LoadNode*>* loadList) {
-
-  VectorSet visited(Thread::current()->resource_area());
-  GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, NULL);
-  DomDepthCompareClosure ddcc(phase);
-
-  nodeStack.push(phase->C->root());
-  while(nodeStack.length() > 0) {
-    Node *n = nodeStack.pop();
-    if (visited.test(n->_idx)) {
-      continue;
-    }
-
-    if (n->isa_Load()) {
-      LoadNode *load = n->as_Load();
-      if (load_require_barrier(load)) {
-        assert(phase->get_ctrl(load) != NULL, "sanity");
-        assert(phase->dom_depth(phase->get_ctrl(load)) != 0, "sanity");
-        loadList->insert_sorted(&ddcc, load);
-      }
-    }
-
-    visited.set(n->_idx);
-    for (uint i = 0; i < n->req(); i++) {
-      if (n->in(i)) {
-        if (!visited.test(n->in(i)->_idx)) {
-          nodeStack.push(n->in(i));
-        }
+    // Now at block top, see if we have any changes
+    new_live.SUBTRACT(old_live);
+    if (new_live.is_NotEmpty()) {
+      // Liveness has refined, update and propagate to prior blocks
+      old_live.OR(new_live);
+      for (uint i = 1; i < block->num_preds(); ++i) {
+        Block* const pred = cfg->get_block_for_node(block->pred(i));
+        worklist.push(pred);
       }
     }
   }
 }
-
-// Add LoadBarriers to all LoadPs
-void ZBarrierSetC2::insert_load_barriers(PhaseIdealLoop* phase) const {
-
-  bool trace = phase->C->directive()->ZTraceLoadBarriersOption;
-  GrowableArray<LoadNode *> loadList(Thread::current()->resource_area(), 0, 0, NULL);
-  gather_loadnodes_sorted(phase, &loadList);
-
-  PhaseIterGVN &igvn = phase->igvn();
-  int count = 0;
-
-  for (GrowableArrayIterator<LoadNode *> loadIter = loadList.begin(); loadIter != loadList.end(); ++loadIter) {
-    LoadNode *load = *loadIter;
-
-    if (load_has_expanded_barrier(load)) {
-      continue;
-    }
-
-    do {
-      // Insert a barrier on a loadP
-      // if another load is found that needs to be expanded first, retry on that one
-      LoadNode* result = insert_one_loadbarrier(phase, load, phase->get_ctrl(load));
-      while (result != NULL) {
-        result = insert_one_loadbarrier(phase, result, phase->get_ctrl(result));
-      }
-    } while (!load_has_expanded_barrier(load));
-  }
-
-  phase->C->print_method(PHASE_INSERT_BARRIER, 2);
-}
-
-void push_antidependent_stores(PhaseIdealLoop* phase, Node_Stack& nodestack, LoadNode* start_load) {
-  // push all stores on the same mem, that can_alias
-  // Any load found must be handled first
-  PhaseIterGVN &igvn = phase->igvn();
-  int load_alias_idx = igvn.C->get_alias_index(start_load->adr_type());
-
-  Node *mem = start_load->in(1);
-  for (DUIterator_Fast imax, u = mem->fast_outs(imax); u < imax; u++) {
-    Node *mem_use = mem->fast_out(u);
-
-    if (mem_use == start_load) continue;
-    if (!mem_use->is_Store()) continue;
-    if (!phase->has_ctrl(mem_use)) continue;
-    if (phase->get_ctrl(mem_use) != phase->get_ctrl(start_load)) continue;
-
-    // add any aliasing store in this block
-    StoreNode *store = mem_use->isa_Store();
-    const TypePtr *adr_type = store->adr_type();
-    if (igvn.C->can_alias(adr_type, load_alias_idx)) {
-      nodestack.push(store, 0);
-    }
-  }
-}
-
-LoadNode* ZBarrierSetC2::insert_one_loadbarrier(PhaseIdealLoop* phase, LoadNode* start_load, Node* ctrl) const {
-  bool trace = phase->C->directive()->ZTraceLoadBarriersOption;
-  PhaseIterGVN &igvn = phase->igvn();
-
-  // Check for other loadPs at the same loop depth that is reachable by a DFS
-  // - if found - return it. It needs to be inserted first
-  // - otherwise proceed and insert barrier
-
-  VectorSet visited(Thread::current()->resource_area());
-  Node_Stack nodestack(100);
-
-  nodestack.push(start_load, 0);
-  push_antidependent_stores(phase, nodestack, start_load);
-
-  while(!nodestack.is_empty()) {
-    Node* n = nodestack.node(); // peek
-    nodestack.pop();
-    if (visited.test(n->_idx)) {
-      continue;
-    }
-
-    if (n->is_Load() && n != start_load && load_require_barrier(n->as_Load()) && !load_has_expanded_barrier(n->as_Load())) {
-      // Found another load that needs a barrier in the same block. Must expand later loads first.
-      if (trace) tty->print_cr(" * Found LoadP %i on DFS", n->_idx);
-      return n->as_Load(); // return node that should be expanded first
-    }
-
-    if (!phase->has_ctrl(n)) continue;
-    if (phase->get_ctrl(n) != phase->get_ctrl(start_load)) continue;
-    if (n->is_Phi()) continue;
-
-    visited.set(n->_idx);
-    // push all children
-    for (DUIterator_Fast imax, ii = n->fast_outs(imax); ii < imax; ii++) {
-      Node* c = n->fast_out(ii);
-      if (c != NULL) {
-        nodestack.push(c, 0);
-      }
-    }
-  }
-
-  insert_one_loadbarrier_inner(phase, start_load, ctrl, visited);
-  return NULL;
-}
-
-void ZBarrierSetC2::insert_one_loadbarrier_inner(PhaseIdealLoop* phase, LoadNode* load, Node* ctrl, VectorSet visited2) const {
-  PhaseIterGVN &igvn = phase->igvn();
-  Compile* C = igvn.C;
-  bool trace = C->directive()->ZTraceLoadBarriersOption;
-
-  // create barrier
-  Node* barrier = new LoadBarrierNode(C, NULL, load->in(LoadNode::Memory), NULL, load->in(LoadNode::Address), load_has_weak_barrier(load));
-  Node* barrier_val = new ProjNode(barrier, LoadBarrierNode::Oop);
-  Node* barrier_ctrl = new ProjNode(barrier, LoadBarrierNode::Control);
-  ctrl = normalize_ctrl(ctrl);
-
-  if (trace) tty->print_cr("Insert load %i with barrier: %i and ctrl : %i", load->_idx, barrier->_idx, ctrl->_idx);
-
-  // Splice control
-  // - insert barrier control diamond between loads ctrl and ctrl successor on path to block end.
-  // - If control successor is a catch, step over to next.
-  Node* ctrl_succ = NULL;
-  for (DUIterator_Fast imax, j = ctrl->fast_outs(imax); j < imax; j++) {
-    Node* tmp = ctrl->fast_out(j);
-
-    // - CFG nodes is the ones we are going to splice (1 only!)
-    // - Phi nodes will continue to hang from the region node!
-    // - self loops should be skipped
-    if (tmp->is_Phi() || tmp == ctrl) {
-      continue;
-    }
-
-    if (tmp->is_CFG()) {
-      assert(ctrl_succ == NULL, "There can be only one");
-      ctrl_succ = tmp;
-      continue;
-    }
-  }
-
-  // Now splice control
-  assert(ctrl_succ != load, "sanity");
-  assert(ctrl_succ != NULL, "Broken IR");
-  bool found = false;
-  for(uint k = 0; k < ctrl_succ->req(); k++) {
-    if (ctrl_succ->in(k) == ctrl) {
-      assert(!found, "sanity");
-      if (trace) tty->print_cr(" Move CFG ctrl_succ %i to barrier_ctrl", ctrl_succ->_idx);
-      igvn.replace_input_of(ctrl_succ, k, barrier_ctrl);
-      found = true;
-      k--;
-    }
-  }
-
-  // For all successors of ctrl - move all visited to become successors of barrier_ctrl instead
-  for (DUIterator_Fast imax, r = ctrl->fast_outs(imax); r < imax; r++) {
-    Node* tmp = ctrl->fast_out(r);
-    if (tmp->is_SafePoint() || (visited2.test(tmp->_idx) && (tmp != load))) {
-      if (trace) tty->print_cr(" Move ctrl_succ %i to barrier_ctrl", tmp->_idx);
-      igvn.replace_input_of(tmp, 0, barrier_ctrl);
-      --r; --imax;
-    }
-  }
-
-  // Move the loads user to the barrier
-  for (DUIterator_Fast imax, i = load->fast_outs(imax); i < imax; i++) {
-    Node* u = load->fast_out(i);
-    if (u->isa_LoadBarrier()) {
-      continue;
-    }
-
-    // find correct input  - replace with iterator?
-    for(uint j = 0; j < u->req(); j++) {
-      if (u->in(j) == load) {
-        igvn.replace_input_of(u, j, barrier_val);
-        --i; --imax; // Adjust the iterator of the *outer* loop
-        break; // some nodes (calls) might have several uses from the same node
-      }
-    }
-  }
-
-  // Connect barrier to load and control
-  barrier->set_req(LoadBarrierNode::Oop, load);
-  barrier->set_req(LoadBarrierNode::Control, ctrl);
-
-  igvn.replace_input_of(load, MemNode::Control, ctrl);
-  load->pin();
-
-  igvn.rehash_node_delayed(load);
-  igvn.register_new_node_with_optimizer(barrier);
-  igvn.register_new_node_with_optimizer(barrier_val);
-  igvn.register_new_node_with_optimizer(barrier_ctrl);
-  load_set_expanded_barrier(load);
-
-  C->print_method(PHASE_INSERT_BARRIER, 3, load->_idx);
-}
-
-// The bad_mask in the ThreadLocalData shouldn't have an anti-dep-check.
-// The bad_mask address if of type TypeRawPtr, but that will alias
-// InitializeNodes until the type system is expanded.
-bool ZBarrierSetC2::needs_anti_dependence_check(const Node* node) const {
-  MachNode* mnode = node->as_Mach();
-  if (mnode != NULL) {
-    intptr_t offset = 0;
-    const TypePtr *adr_type2 = NULL;
-    const Node* base = mnode->get_base_and_disp(offset, adr_type2);
-    if ((base != NULL) &&
-        (base->is_Mach() && base->as_Mach()->ideal_Opcode() == Op_ThreadLocal) &&
-        (offset == in_bytes(ZThreadLocalData::address_bad_mask_offset()))) {
-      return false;
-    }
-  }
-  return true;
-}
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -29,134 +29,38 @@
 #include "opto/node.hpp"
 #include "utilities/growableArray.hpp"
 
-class ZCompareAndSwapPNode : public CompareAndSwapPNode {
-public:
-    ZCompareAndSwapPNode(Node* c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : CompareAndSwapPNode(c, mem, adr, val, ex, mem_ord) { }
-    virtual int Opcode() const;
-};
-
-class ZWeakCompareAndSwapPNode : public WeakCompareAndSwapPNode {
-public:
-    ZWeakCompareAndSwapPNode(Node* c, Node *mem, Node *adr, Node *val, Node *ex, MemNode::MemOrd mem_ord) : WeakCompareAndSwapPNode(c, mem, adr, val, ex, mem_ord) { }
-    virtual int Opcode() const;
-};
+const uint8_t ZLoadBarrierStrong = 1;
+const uint8_t ZLoadBarrierWeak   = 2;
+const uint8_t ZLoadBarrierElided = 3;
 
-class ZCompareAndExchangePNode : public CompareAndExchangePNode {
-public:
-    ZCompareAndExchangePNode(Node* c, Node *mem, Node *adr, Node *val, Node *ex, const TypePtr* at, const Type* t, MemNode::MemOrd mem_ord) : CompareAndExchangePNode(c, mem, adr, val, ex, at, t, mem_ord) { }
-    virtual int Opcode() const;
-};
+class ZLoadBarrierStubC2 : public ResourceObj {
+private:
+  const MachNode* _node;
+  const Address   _ref_addr;
+  const Register  _ref;
+  const Register  _tmp;
+  const bool      _weak;
+  Label           _entry;
+  Label           _continuation;
 
-class ZGetAndSetPNode : public GetAndSetPNode {
-public:
-    ZGetAndSetPNode(Node* c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* t) : GetAndSetPNode(c, mem, adr, val, at, t) { }
-    virtual int Opcode() const;
-};
-
-class LoadBarrierNode : public MultiNode {
-private:
-  bool _weak;               // On strong or weak oop reference
-  static bool is_dominator(PhaseIdealLoop* phase, bool linear_only, Node *d, Node *n);
-  void push_dominated_barriers(PhaseIterGVN* igvn) const;
+  ZLoadBarrierStubC2(const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak);
 
 public:
-  enum {
-    Control,
-    Memory,
-    Oop,
-    Address,
-    Number_of_Outputs = Address,
-    Similar,
-    Number_of_Inputs
-  };
-
-  LoadBarrierNode(Compile* C,
-                  Node* c,
-                  Node* mem,
-                  Node* val,
-                  Node* adr,
-                  bool weak);
-
-  virtual int Opcode() const;
-  virtual uint size_of() const;
-  virtual bool cmp(const Node& n) const;
-  virtual const Type *bottom_type() const;
-  virtual const TypePtr* adr_type() const;
-  virtual const Type *Value(PhaseGVN *phase) const;
-  virtual Node *Identity(PhaseGVN *phase);
-  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
-  virtual uint match_edge(uint idx) const;
-
-  LoadBarrierNode* has_dominating_barrier(PhaseIdealLoop* phase,
-                                          bool linear_only,
-                                          bool look_for_similar);
-
-  void fix_similar_in_uses(PhaseIterGVN* igvn);
-
-  bool has_true_uses() const;
-
-  bool can_be_eliminated() const {
-    return !in(Similar)->is_top();
-  }
-
-  bool is_weak() const {
-    return _weak;
-  }
-};
+  static ZLoadBarrierStubC2* create(const MachNode* node, Address ref_addr, Register ref, Register tmp, bool weak);
 
-class LoadBarrierSlowRegNode : public TypeNode {
-private:
-  bool _is_weak;
-public:
-  LoadBarrierSlowRegNode(Node *c,
-                         Node *adr,
-                         Node *src,
-                         const TypePtr* t,
-                         bool weak) :
-      TypeNode(t, 3), _is_weak(weak) {
-    init_req(1, adr);
-    init_req(2, src);
-    init_class_id(Class_LoadBarrierSlowReg);
-  }
-
-  virtual uint size_of() const {
-    return sizeof(*this);
-  }
-
-  virtual const char * name() {
-    return "LoadBarrierSlowRegNode";
-  }
-
-  virtual Node *Ideal(PhaseGVN *phase, bool can_reshape) {
-    return NULL;
-  }
-
-  virtual int Opcode() const;
-
-  bool is_weak() { return _is_weak; }
-};
-
-class ZBarrierSetC2State : public ResourceObj {
-private:
-  // List of load barrier nodes which need to be expanded before matching
-  GrowableArray<LoadBarrierNode*>* _load_barrier_nodes;
-
-public:
-  ZBarrierSetC2State(Arena* comp_arena);
-  int load_barrier_count() const;
-  void add_load_barrier_node(LoadBarrierNode* n);
-  void remove_load_barrier_node(LoadBarrierNode* n);
-  LoadBarrierNode* load_barrier_node(int idx) const;
+  Address ref_addr() const;
+  Register ref() const;
+  Register tmp() const;
+  address slow_path() const;
+  RegMask& live() const;
+  Label* entry();
+  Label* continuation();
 };
 
 class ZBarrierSetC2 : public BarrierSetC2 {
 private:
-  ZBarrierSetC2State* state() const;
-  void expand_loadbarrier_node(PhaseMacroExpand* phase, LoadBarrierNode* barrier) const;
-
-#ifdef ASSERT
-  void verify_gc_barriers(bool post_parse) const;
-#endif
+  void compute_liveness_at_stubs() const;
+  void analyze_dominating_barriers() const;
 
 protected:
   virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const;
@@ -174,43 +78,14 @@
 
 public:
   virtual void* create_barrier_state(Arena* comp_arena) const;
-
-  virtual bool has_load_barriers() const { return true; }
-  virtual bool is_gc_barrier_node(Node* node) const;
-  virtual Node* step_over_gc_barrier(Node* c) const;
-  virtual Node* step_over_gc_barrier_ctrl(Node* c) const;
-
-  virtual void register_potential_barrier_node(Node* node) const;
-  virtual void unregister_potential_barrier_node(Node* node) const;
-  virtual void eliminate_gc_barrier(PhaseMacroExpand* macro, Node* node) const { }
-  virtual void enqueue_useful_gc_barrier(PhaseIterGVN* igvn, Node* node) const;
-  virtual void eliminate_useless_gc_barriers(Unique_Node_List &useful, Compile* C) const;
-
-  virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc, BasicType type, bool is_clone, ArrayCopyPhase phase) const;
+  virtual bool array_copy_requires_gc_barriers(bool tightly_coupled_alloc,
+                                               BasicType type,
+                                               bool is_clone,
+                                               ArrayCopyPhase phase) const;
 
-  virtual bool expand_barriers(Compile* C, PhaseIterGVN& igvn) const;
-  virtual bool final_graph_reshaping(Compile* compile, Node* n, uint opcode) const;
-  virtual bool matcher_find_shared_visit(Matcher* matcher, Matcher::MStack& mstack, Node* n, uint opcode, bool& mem_op, int& mem_addr_idx) const;
-  virtual bool matcher_find_shared_post_visit(Matcher* matcher, Node* n, uint opcode) const;
-  virtual bool needs_anti_dependence_check(const Node* node) const;
-
-#ifdef ASSERT
-  virtual void verify_gc_barriers(Compile* compile, CompilePhase phase) const;
-#endif
-
-  // Load barrier insertion and expansion external
-  virtual void barrier_insertion_phase(Compile* C, PhaseIterGVN &igvn) const;
-  virtual bool optimize_loops(PhaseIdealLoop* phase, LoopOptsMode mode, VectorSet& visited, Node_Stack& nstack, Node_List& worklist) const;
-  virtual bool is_gc_specific_loop_opts_pass(LoopOptsMode mode) const { return (mode == LoopOptsZBarrierInsertion); }
-  virtual bool strip_mined_loops_expanded(LoopOptsMode mode) const { return mode == LoopOptsZBarrierInsertion; }
-
-private:
-  // Load barrier insertion and expansion internal
-  void insert_barriers_on_unsafe(PhaseIdealLoop* phase) const;
-  void clean_catch_blocks(PhaseIdealLoop* phase, bool verify = false) const;
-  void insert_load_barriers(PhaseIdealLoop* phase) const;
-  LoadNode* insert_one_loadbarrier(PhaseIdealLoop* phase, LoadNode* load, Node* ctrl) const;
-  void insert_one_loadbarrier_inner(PhaseIdealLoop* phase, LoadNode* load, Node* ctrl, VectorSet visited) const;
+  virtual void late_barrier_analysis() const;
+  virtual int estimate_stub_size() const;
+  virtual void emit_stubs(CodeBuffer& cb) const;
 };
 
 #endif // SHARE_GC_Z_C2_ZBARRIERSETC2_HPP
--- a/src/hotspot/share/gc/z/zArguments.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zArguments.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -37,11 +37,6 @@
 void ZArguments::initialize() {
   GCArguments::initialize();
 
-  // Check max heap size
-  if (MaxHeapSize > ZMaxHeapSize) {
-    vm_exit_during_initialization("Java heap too large");
-  }
-
   // Enable NUMA by default
   if (FLAG_IS_DEFAULT(UseNUMA)) {
     FLAG_SET_DEFAULT(UseNUMA, true);
--- a/src/hotspot/share/gc/z/zBarrierSetAssembler.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zBarrierSetAssembler.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -24,10 +24,7 @@
 #ifndef SHARE_GC_Z_ZBARRIERSETASSEMBLER_HPP
 #define SHARE_GC_Z_ZBARRIERSETASSEMBLER_HPP
 
-#include "asm/macroAssembler.hpp"
 #include "gc/shared/barrierSetAssembler.hpp"
-#include "oops/accessDecorators.hpp"
-#include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
 
 class ZBarrierSetAssemblerBase : public BarrierSetAssembler {
--- a/src/hotspot/share/gc/z/zGlobals.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zGlobals.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -44,10 +44,6 @@
 const size_t      ZGranuleSizeShift             = ZPlatformGranuleSizeShift;
 const size_t      ZGranuleSize                  = (size_t)1 << ZGranuleSizeShift;
 
-// Max heap size shift/size
-const size_t      ZMaxHeapSizeShift             = ZPlatformMaxHeapSizeShift;
-const size_t      ZMaxHeapSize                  = (size_t)1 << ZMaxHeapSizeShift;
-
 // Page types
 const uint8_t     ZPageTypeSmall                = 0;
 const uint8_t     ZPageTypeMedium               = 1;
--- a/src/hotspot/share/gc/z/zVirtualMemory.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zVirtualMemory.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -31,6 +31,13 @@
     _manager(),
     _initialized(false) {
 
+  // Check max supported heap size
+  if (max_capacity > ZAddressOffsetMax) {
+    log_error(gc)("Java heap too large (max supported heap size is " SIZE_FORMAT "G)",
+                  ZAddressOffsetMax / G);
+    return;
+  }
+
   log_info(gc, init)("Address Space: " SIZE_FORMAT "T", ZAddressOffsetMax / K / G);
 
   // Reserve address space
--- a/src/hotspot/share/include/jvm.h	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/include/jvm.h	Thu Oct 10 10:57:42 2019 -0400
@@ -1044,19 +1044,6 @@
 #include "classfile_constants.h"
 
 /*
- * A function defined by the byte-code verifier and called by the VM.
- * This is not a function implemented in the VM.
- *
- * Returns JNI_FALSE if verification fails. A detailed error message
- * will be places in msg_buf, whose length is specified by buf_len.
- */
-typedef jboolean (*verifier_fn_t)(JNIEnv *env,
-                                  jclass cb,
-                                  char * msg_buf,
-                                  jint buf_len);
-
-
-/*
  * Support for a VM-independent class format checker.
  */
 typedef struct {
@@ -1086,28 +1073,6 @@
 
 typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str);
 
-typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b);
-
-/* This is the function defined in libjava.so that performs class
- * format checks. This functions fills in size information about
- * the class file and returns:
- *
- *   0: good
- *  -1: out of memory
- *  -2: bad format
- *  -3: unsupported version
- *  -4: bad class name
- */
-
-typedef jint (*check_format_fn_t)(char *class_name,
-                                  unsigned char *data,
-                                  unsigned int data_size,
-                                  class_size_info *class_size,
-                                  char *message_buffer,
-                                  jint buffer_length,
-                                  jboolean measure_only,
-                                  jboolean check_relaxed);
-
 #define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \
                                         JVM_ACC_FINAL | \
                                         JVM_ACC_SUPER | \
--- a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -168,7 +168,7 @@
 
 static bool is_cds_dump_requested() {
   // we will not be able to launch recordings if a cds dump is being requested
-  if ((DumpSharedSpaces || DynamicDumpSharedSpaces) && (JfrOptionSet::startup_recording_options() != NULL)) {
+  if (Arguments::is_dumping_archive() && (JfrOptionSet::startup_recording_options() != NULL)) {
     warning("JFR will be disabled during CDS dumping");
     teardown_startup_support();
     return true;
--- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -393,6 +393,10 @@
     Service_lock->unlock();
   }
 
+  if (UseNotificationThread && Notification_lock->owned_by_self()) {
+    Notification_lock->unlock();
+  }
+
   if (CodeCache_lock->owned_by_self()) {
     CodeCache_lock->unlock();
   }
--- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -31,6 +31,7 @@
 #include "jvmci/vmStructs_jvmci.hpp"
 #include "memory/universe.hpp"
 #include "oops/compressedOops.hpp"
+#include "oops/klass.inline.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "utilities/resourceHash.hpp"
 
--- a/src/hotspot/share/logging/logSelectionList.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/logging/logSelectionList.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/src/hotspot/share/memory/filemap.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/memory/filemap.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -263,7 +263,7 @@
 
 void SharedClassPathEntry::init(bool is_modules_image,
                                 ClassPathEntry* cpe, TRAPS) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
+  Arguments::assert_is_dumping_archive();
   _timestamp = 0;
   _filesize  = 0;
   _from_class_path_attr = false;
@@ -397,7 +397,7 @@
 }
 
 void FileMapInfo::allocate_shared_path_table() {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity");
+  Arguments::assert_is_dumping_archive();
 
   EXCEPTION_MARK; // The following calls should never throw, but would exit VM on error.
   ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
@@ -444,7 +444,7 @@
 }
 
 void FileMapInfo::check_nonempty_dir_in_shared_path_table() {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
+  Arguments::assert_is_dumping_archive();
 
   bool has_nonempty_dir = false;
 
@@ -471,7 +471,7 @@
 }
 
 void FileMapInfo::record_non_existent_class_path_entry(const char* path) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
+  Arguments::assert_is_dumping_archive();
   log_info(class, path)("non-existent Class-Path entry %s", path);
   if (_non_existent_class_paths == NULL) {
     _non_existent_class_paths = new (ResourceObj::C_HEAP, mtInternal)GrowableArray<const char*>(10, true);
@@ -480,7 +480,7 @@
 }
 
 int FileMapInfo::num_non_existent_class_paths() {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
+  Arguments::assert_is_dumping_archive();
   if (_non_existent_class_paths != NULL) {
     return _non_existent_class_paths->length();
   } else {
@@ -1150,7 +1150,7 @@
 
 void FileMapInfo::write_region(int region, char* base, size_t size,
                                bool read_only, bool allow_exec) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Dump time only");
+  Arguments::assert_is_dumping_archive();
 
   FileMapRegion* si = space_at(region);
   char* target_base = base;
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -425,7 +425,7 @@
 }
 
 void MetaspaceShared::commit_shared_space_to(char* newtop) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump-time only");
+  Arguments::assert_is_dumping_archive();
   char* base = _shared_rs.base();
   size_t need_committed_size = newtop - base;
   size_t has_committed_size = _shared_vs.committed_size();
@@ -509,8 +509,7 @@
 }
 
 uintx MetaspaceShared::object_delta_uintx(void* obj) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
-         "supported only for dumping");
+  Arguments::assert_is_dumping_archive();
   if (DumpSharedSpaces) {
     assert(shared_rs()->contains(obj), "must be");
   } else {
--- a/src/hotspot/share/memory/universe.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/memory/universe.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -710,7 +710,7 @@
   }
 
 #if INCLUDE_CDS
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+  if (Arguments::is_dumping_archive()) {
     MetaspaceShared::prepare_for_dumping();
   }
 #endif
--- a/src/hotspot/share/oops/constMethod.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/oops/constMethod.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -26,6 +26,7 @@
 #define SHARE_OOPS_CONSTMETHOD_HPP
 
 #include "oops/oop.hpp"
+#include "runtime/arguments.hpp"
 #include "utilities/align.hpp"
 
 // An ConstMethod represents portions of a Java method which are not written to after
@@ -293,7 +294,7 @@
     _adapter = adapter;
   }
   void set_adapter_trampoline(AdapterHandlerEntry** trampoline) {
-    assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "must be");
+    Arguments::assert_is_dumping_archive();
     if (DumpSharedSpaces) {
       assert(*trampoline == NULL,
              "must be NULL during dump time, to be initialized at run time");
--- a/src/hotspot/share/oops/cpCache.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/oops/cpCache.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -708,7 +708,7 @@
 }
 
 void ConstantPoolCache::walk_entries_for_initialization(bool check_only) {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "sanity");
+  Arguments::assert_is_dumping_archive();
   // When dumping the archive, we want to clean up the ConstantPoolCache
   // to remove any effect of linking due to the execution of Java code --
   // each ConstantPoolCacheEntry will have the same contents as if
--- a/src/hotspot/share/oops/instanceKlass.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -453,7 +453,7 @@
   assert(is_instance_klass(), "is layout incorrect?");
   assert(size_helper() == parser.layout_size(), "incorrect size_helper?");
 
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+  if (Arguments::is_dumping_archive()) {
     SystemDictionaryShared::init_dumptime_info(this);
   }
 }
@@ -603,7 +603,7 @@
   }
   set_annotations(NULL);
 
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+  if (Arguments::is_dumping_archive()) {
     SystemDictionaryShared::remove_dumptime_info(this);
   }
 }
@@ -2229,7 +2229,7 @@
     // (1) We are running AOT to generate a shared library.
     return true;
   }
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+  if (Arguments::is_dumping_archive()) {
     // (2) We are running -Xshare:dump or -XX:ArchiveClassesAtExit to create a shared archive
     return true;
   }
@@ -2477,7 +2477,7 @@
   // notify ClassLoadingService of class unload
   ClassLoadingService::notify_class_unloaded(ik);
 
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+  if (Arguments::is_dumping_archive()) {
     SystemDictionaryShared::remove_dumptime_info(ik);
   }
 
--- a/src/hotspot/share/oops/instanceKlass.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/oops/instanceKlass.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -992,7 +992,6 @@
   void process_interfaces(Thread *thread);
 
   // virtual operations from Klass
-  bool is_leaf_class() const               { return _subklass == NULL; }
   GrowableArray<Klass*>* compute_secondary_supers(int num_extra_slots,
                                                   Array<InstanceKlass*>* transitive_interfaces);
   bool can_be_primary_super_slow() const;
--- a/src/hotspot/share/oops/klass.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/oops/klass.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -57,10 +57,6 @@
   _java_mirror = class_loader_data()->add_handle(m);
 }
 
-oop Klass::java_mirror() const {
-  return _java_mirror.resolve();
-}
-
 oop Klass::java_mirror_no_keepalive() const {
   return _java_mirror.peek();
 }
@@ -525,7 +521,7 @@
 }
 
 void Klass::remove_unshareable_info() {
-  assert (DumpSharedSpaces || DynamicDumpSharedSpaces,
+  assert (Arguments::is_dumping_archive(),
           "only called during CDS dump time");
   JFR_ONLY(REMOVE_ID(this);)
   if (log_is_enabled(Trace, cds, unshareable)) {
@@ -543,7 +539,7 @@
 }
 
 void Klass::remove_java_mirror() {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "only called during CDS dump time");
+  Arguments::assert_is_dumping_archive();
   if (log_is_enabled(Trace, cds, unshareable)) {
     ResourceMark rm;
     log_trace(cds, unshareable)("remove java_mirror: %s", external_name());
@@ -681,8 +677,6 @@
   }
 }
 
-oop Klass::class_loader() const { return class_loader_data()->class_loader(); }
-
 // In product mode, this function doesn't have virtual function calls so
 // there might be some performance advantage to handling InstanceKlass here.
 const char* Klass::external_name() const {
@@ -826,14 +820,6 @@
   return ClassLoaderDataGraph::is_valid(k->class_loader_data());
 }
 
-klassVtable Klass::vtable() const {
-  return klassVtable(const_cast<Klass*>(this), start_of_vtable(), vtable_length() / vtableEntry::size());
-}
-
-vtableEntry* Klass::start_of_vtable() const {
-  return (vtableEntry*) ((address)this + in_bytes(vtable_start_offset()));
-}
-
 Method* Klass::method_at_vtable(int index)  {
 #ifndef PRODUCT
   assert(index >= 0, "valid vtable index");
@@ -844,9 +830,6 @@
   return start_of_vtable()[index].method();
 }
 
-ByteSize Klass::vtable_start_offset() {
-  return in_ByteSize(InstanceKlass::header_size() * wordSize);
-}
 
 #ifndef PRODUCT
 
--- a/src/hotspot/share/oops/klass.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/oops/klass.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -469,8 +469,6 @@
   virtual bool should_be_initialized() const    { return false; }
   // initializes the klass
   virtual void initialize(TRAPS);
-  // lookup operation for MethodLookupCache
-  friend class MethodLookupCache;
   virtual Klass* find_field(Symbol* name, Symbol* signature, fieldDescriptor* fd) const;
   virtual Method* uncached_lookup_method(const Symbol* name, const Symbol* signature,
                                          OverpassLookupMode overpass_mode,
@@ -537,9 +535,6 @@
   }
 
  public:
-  // subclass accessor (here for convenience; undefined for non-klass objects)
-  virtual bool is_leaf_class() const { fatal("not a class"); return false; }
- public:
   // ALL FUNCTIONS BELOW THIS POINT ARE DISPATCHED FROM AN OOP
   // These functions describe behavior for the oop not the KLASS.
 
--- a/src/hotspot/share/oops/klass.inline.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/oops/klass.inline.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -25,13 +25,35 @@
 #ifndef SHARE_OOPS_KLASS_INLINE_HPP
 #define SHARE_OOPS_KLASS_INLINE_HPP
 
+#include "classfile/classLoaderData.inline.hpp"
 #include "oops/compressedOops.hpp"
 #include "oops/klass.hpp"
 #include "oops/markWord.hpp"
+#include "oops/oopHandle.inline.hpp"
 
 inline void Klass::set_prototype_header(markWord header) {
   assert(!header.has_bias_pattern() || is_instance_klass(), "biased locking currently only supported for Java instances");
   _prototype_header = header;
 }
 
+inline oop Klass::java_mirror() const {
+  return _java_mirror.resolve();
+}
+
+inline klassVtable Klass::vtable() const {
+  return klassVtable(const_cast<Klass*>(this), start_of_vtable(), vtable_length() / vtableEntry::size());
+}
+
+inline oop Klass::class_loader() const {
+  return class_loader_data()->class_loader();
+}
+
+inline vtableEntry* Klass::start_of_vtable() const {
+  return (vtableEntry*) ((address)this + in_bytes(vtable_start_offset()));
+}
+
+inline ByteSize Klass::vtable_start_offset() {
+  return in_ByteSize(InstanceKlass::header_size() * wordSize);
+}
+
 #endif // SHARE_OOPS_KLASS_INLINE_HPP
--- a/src/hotspot/share/oops/klassVtable.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/oops/klassVtable.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -128,11 +128,6 @@
   *vtable_length_ret = vtable_length;
 }
 
-int klassVtable::index_of(Method* m, int len) const {
-  assert(m->has_vtable_index(), "do not ask this of non-vtable methods");
-  return m->vtable_index();
-}
-
 // Copy super class's vtable to the first part (prefix) of this class's vtable,
 // and return the number of entries copied.  Expects that 'super' is the Java
 // super class (arrays can have "array" super classes that must be skipped).
@@ -169,7 +164,6 @@
 
   // Note:  Arrays can have intermediate array supers.  Use java_super to skip them.
   InstanceKlass* super = _klass->java_super();
-  int nofNewEntries = 0;
 
   bool is_shared = _klass->is_shared();
 
@@ -1029,15 +1023,6 @@
 }
 #endif // INCLUDE_JVMTI
 
-// CDS/RedefineClasses support - clear vtables so they can be reinitialized
-void klassVtable::clear_vtable() {
-  for (int i = 0; i < _length; i++) table()[i].clear();
-}
-
-bool klassVtable::is_initialized() {
-  return _length == 0 || table()[0].method() != NULL;
-}
-
 //-----------------------------------------------------------------------------------------
 // Itable code
 
@@ -1468,31 +1453,6 @@
 #endif
 }
 
-
-// inverse to itable_index
-Method* klassItable::method_for_itable_index(InstanceKlass* intf, int itable_index) {
-  assert(intf->is_interface(), "sanity check");
-  assert(intf->verify_itable_index(itable_index), "");
-  Array<Method*>* methods = InstanceKlass::cast(intf)->methods();
-
-  if (itable_index < 0 || itable_index >= method_count_for_interface(intf))
-    return NULL;                // help caller defend against bad indices
-
-  int index = itable_index;
-  Method* m = methods->at(index);
-  int index2 = -1;
-  while (!m->has_itable_index() ||
-         (index2 = m->itable_index()) != itable_index) {
-    assert(index2 < itable_index, "monotonic");
-    if (++index == methods->length())
-      return NULL;
-    m = methods->at(index);
-  }
-  assert(m->itable_index() == itable_index, "correct inverse");
-
-  return m;
-}
-
 void klassVtable::verify(outputStream* st, bool forced) {
   // make sure table is initialized
   if (!Universe::is_fully_initialized()) return;
--- a/src/hotspot/share/oops/klassVtable.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/oops/klassVtable.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -48,13 +48,6 @@
   int          _verify_count;     // to make verify faster
 #endif
 
-  // Ordering important, so greater_than (>) can be used as an merge operator.
-  enum AccessType {
-    acc_private         = 0,
-    acc_package_private = 1,
-    acc_publicprotected = 2
-  };
-
  public:
   klassVtable(Klass* klass, void* base, int length) : _klass(klass) {
     _tableOffset = (address)base - (address)klass; _length = length;
@@ -66,22 +59,12 @@
   int length() const              { return _length; }
   inline Method* method_at(int i) const;
   inline Method* unchecked_method_at(int i) const;
-  inline Method** adr_method_at(int i) const;
 
   // searching; all methods return -1 if not found
-  int index_of(Method* m) const                         { return index_of(m, _length); }
   int index_of_miranda(Symbol* name, Symbol* signature);
 
   void initialize_vtable(bool checkconstraints, TRAPS);   // initialize vtable of a new klass
 
-  // CDS/RedefineClasses support - clear vtables so they can be reinitialized
-  // at dump time.  Clearing gives us an easy way to tell if the vtable has
-  // already been reinitialized at dump time (see dump.cpp).  Vtables can
-  // be initialized at run time by RedefineClasses so dumping the right order
-  // is necessary.
-  void clear_vtable();
-  bool is_initialized();
-
   // computes vtable length (in words) and the number of miranda methods
   static void compute_vtable_size_and_num_mirandas(int* vtable_length,
                                                    int* num_new_mirandas,
@@ -125,7 +108,6 @@
  private:
   void copy_vtable_to(vtableEntry* start);
   int  initialize_from_super(Klass* super);
-  int  index_of(Method* m, int len) const; // same as index_of, but search only up to len
   void put_method_at(Method* m, int index);
   static bool needs_new_vtable_entry(const methodHandle& m,
                                      const Klass* super,
@@ -223,12 +205,6 @@
   return table()[i].method();
 }
 
-inline Method** klassVtable::adr_method_at(int i) const {
-  // Allow one past the last entry to be referenced; useful for loop bounds.
-  assert(i >= 0 && i <= _length, "index out of bounds");
-  return (Method**)(address(table() + i) + vtableEntry::method_offset_in_bytes());
-}
-
 // --------------------------------------------------------------------------------
 class klassItable;
 class itableMethodEntry;
@@ -333,9 +309,6 @@
   static int compute_itable_size(Array<InstanceKlass*>* transitive_interfaces);
   static void setup_itable_offset_table(InstanceKlass* klass);
 
-  // Resolving of method to index
-  static Method* method_for_itable_index(InstanceKlass* klass, int itable_index);
-
   // Debugging/Statistics
   static void print_statistics() PRODUCT_RETURN;
  private:
--- a/src/hotspot/share/oops/method.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/oops/method.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -979,7 +979,7 @@
 void Method::unlink_method() {
   _code = NULL;
 
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
+  Arguments::assert_is_dumping_archive();
   // Set the values to what they should be at run time. Note that
   // this Method can no longer be executed during dump time.
   _i2i_entry = Interpreter::entry_for_cds_method(this);
--- a/src/hotspot/share/opto/buildOopMap.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/buildOopMap.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -352,7 +352,6 @@
 
     } else {
       // Other - some reaching non-oop value
-      omap->set_value( r);
 #ifdef ASSERT
       if( t->isa_rawptr() && C->cfg()->_raw_oops.member(def) ) {
         def->dump();
@@ -377,11 +376,18 @@
 #endif
 
 #ifdef ASSERT
-  for( OopMapStream oms1(omap, OopMapValue::derived_oop_value); !oms1.is_done(); oms1.next()) {
+  for( OopMapStream oms1(omap); !oms1.is_done(); oms1.next()) {
     OopMapValue omv1 = oms1.current();
+    if (omv1.type() != OopMapValue::derived_oop_value) {
+      continue;
+    }
     bool found = false;
-    for( OopMapStream oms2(omap,OopMapValue::oop_value); !oms2.is_done(); oms2.next()) {
-      if( omv1.content_reg() == oms2.current().reg() ) {
+    for( OopMapStream oms2(omap); !oms2.is_done(); oms2.next()) {
+      OopMapValue omv2 = oms2.current();
+      if (omv2.type() != OopMapValue::oop_value) {
+        continue;
+      }
+      if( omv1.content_reg() == omv2.reg() ) {
         found = true;
         break;
       }
--- a/src/hotspot/share/opto/c2compiler.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/c2compiler.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -102,7 +102,8 @@
   assert(is_initialized(), "Compiler thread must be initialized");
 
   bool subsume_loads = SubsumeLoads;
-  bool do_escape_analysis = DoEscapeAnalysis && !env->should_retain_local_variables();
+  bool do_escape_analysis = DoEscapeAnalysis && !env->should_retain_local_variables()
+                                             && !env->jvmti_can_get_owned_monitor_info();
   bool eliminate_boxing = EliminateAutoBox;
 
   while (!env->failing()) {
--- a/src/hotspot/share/opto/classes.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/classes.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -48,9 +48,6 @@
 #include "opto/subnode.hpp"
 #include "opto/vectornode.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ZGC
-#include "gc/z/c2/zBarrierSetC2.hpp"
-#endif
 #if INCLUDE_SHENANDOAHGC
 #include "gc/shenandoah/c2/shenandoahBarrierSetC2.hpp"
 #endif
--- a/src/hotspot/share/opto/classes.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/classes.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -193,17 +193,6 @@
 macro(LoadN)
 macro(LoadRange)
 macro(LoadS)
-#if INCLUDE_ZGC
-#define zgcmacro(x) macro(x)
-#else
-#define zgcmacro(x) optionalmacro(x)
-#endif
-zgcmacro(LoadBarrier)
-zgcmacro(LoadBarrierSlowReg)
-zgcmacro(ZCompareAndSwapP)
-zgcmacro(ZWeakCompareAndSwapP)
-zgcmacro(ZCompareAndExchangeP)
-zgcmacro(ZGetAndSetP)
 macro(Lock)
 macro(Loop)
 macro(LoopLimit)
--- a/src/hotspot/share/opto/compile.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/compile.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -76,9 +76,6 @@
 #include "utilities/align.hpp"
 #include "utilities/copy.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ZGC
-#include "gc/z/c2/zBarrierSetC2.hpp"
-#endif
 
 
 // -------------------- Compile::mach_constant_base_node -----------------------
@@ -990,6 +987,7 @@
     _has_method_handle_invokes(false),
     _clinit_barrier_on_entry(false),
     _comp_arena(mtCompiler),
+    _barrier_set_state(BarrierSet::barrier_set()->barrier_set_c2()->create_barrier_state(comp_arena())),
     _env(ci_env),
     _directive(directive),
     _log(ci_env->log()),
@@ -2412,13 +2410,6 @@
     print_method(PHASE_MACRO_EXPANSION, 2);
   }
 
-#ifdef ASSERT
-  bs->verify_gc_barriers(this, BarrierSetC2::BeforeLateInsertion);
-#endif
-
-  bs->barrier_insertion_phase(C, igvn);
-  if (failing())  return;
-
   {
     TracePhase tp("barrierExpand", &timers[_t_barrierExpand]);
     if (bs->expand_barriers(this, igvn)) {
--- a/src/hotspot/share/opto/compile.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/compile.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -55,7 +55,6 @@
 class IdealGraphPrinter;
 class InlineTree;
 class Int_Array;
-class LoadBarrierNode;
 class Matcher;
 class MachConstantNode;
 class MachConstantBaseNode;
@@ -96,7 +95,6 @@
   LoopOptsNone,
   LoopOptsShenandoahExpand,
   LoopOptsShenandoahPostExpand,
-  LoopOptsZBarrierInsertion,
   LoopOptsSkipSplitIf,
   LoopOptsVerify
 };
@@ -1186,11 +1184,7 @@
   bool           in_scratch_emit_size() const   { return _in_scratch_emit_size;     }
 
   enum ScratchBufferBlob {
-#if defined(PPC64)
     MAX_inst_size       = 2048,
-#else
-    MAX_inst_size       = 1024,
-#endif
     MAX_locs_size       = 128, // number of relocInfo elements
     MAX_const_size      = 128,
     MAX_stubs_size      = 128
@@ -1265,14 +1259,30 @@
   // Process an OopMap Element while emitting nodes
   void Process_OopMap_Node(MachNode *mach, int code_offset);
 
+  class BufferSizingData {
+  public:
+    int _stub;
+    int _code;
+    int _const;
+    int _reloc;
+
+      BufferSizingData() :
+      _stub(0),
+      _code(0),
+      _const(0),
+      _reloc(0)
+      { };
+  };
+
   // Initialize code buffer
-  CodeBuffer* init_buffer(uint* blk_starts);
+  void        estimate_buffer_size(int& const_req);
+  CodeBuffer* init_buffer(BufferSizingData& buf_sizes);
 
   // Write out basic block data to code buffer
   void fill_buffer(CodeBuffer* cb, uint* blk_starts);
 
   // Determine which variable sized branches can be shortened
-  void shorten_branches(uint* blk_starts, int& code_size, int& reloc_size, int& stub_size);
+  void shorten_branches(uint* blk_starts, BufferSizingData& buf_sizes);
 
   // Compute the size of first NumberOfLoopInstrToAlign instructions
   // at the head of a loop.
--- a/src/hotspot/share/opto/loopnode.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/loopnode.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -993,18 +993,6 @@
       }
     }
 
-    if (UseZGC && !inner_out->in(0)->is_CountedLoopEnd()) {
-      // In some very special cases there can be a load that has no other uses than the
-      // counted loop safepoint. Then its loadbarrier will be placed between the inner
-      // loop exit and the safepoint. This is very rare
-
-      Node* ifnode = inner_out->in(1)->in(0);
-      // Region->IfTrue->If == Region->Iffalse->If
-      if (ifnode == inner_out->in(2)->in(0)) {
-        inner_out = ifnode->in(0);
-      }
-    }
-
     CountedLoopEndNode* cle = inner_out->in(0)->as_CountedLoopEnd();
     assert(cle == inner->loopexit_or_null(), "mismatch");
     bool has_skeleton = outer_le->in(1)->bottom_type()->singleton() && outer_le->in(1)->bottom_type()->is_int()->get_con() == 0;
@@ -4049,28 +4037,32 @@
   // dominated by early is considered a potentially interfering store.
   // This can produce false positives.
   if (n->is_Load() && LCA != early) {
-    Node_List worklist;
-
-    Node *mem = n->in(MemNode::Memory);
-    for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
-      Node* s = mem->fast_out(i);
-      worklist.push(s);
-    }
-    while(worklist.size() != 0 && LCA != early) {
-      Node* s = worklist.pop();
-      if (s->is_Load() || s->Opcode() == Op_SafePoint ||
-          (s->is_CallStaticJava() && s->as_CallStaticJava()->uncommon_trap_request() != 0)) {
-        continue;
-      } else if (s->is_MergeMem()) {
-        for (DUIterator_Fast imax, i = s->fast_outs(imax); i < imax; i++) {
-          Node* s1 = s->fast_out(i);
-          worklist.push(s1);
-        }
-      } else {
-        Node *sctrl = has_ctrl(s) ? get_ctrl(s) : s->in(0);
-        assert(sctrl != NULL || s->outcnt() == 0, "must have control");
-        if (sctrl != NULL && !sctrl->is_top() && is_dominator(early, sctrl)) {
-          LCA = dom_lca_for_get_late_ctrl(LCA, sctrl, n);
+    int load_alias_idx = C->get_alias_index(n->adr_type());
+    if (C->alias_type(load_alias_idx)->is_rewritable()) {
+
+      Node_List worklist;
+
+      Node *mem = n->in(MemNode::Memory);
+      for (DUIterator_Fast imax, i = mem->fast_outs(imax); i < imax; i++) {
+        Node* s = mem->fast_out(i);
+        worklist.push(s);
+      }
+      while(worklist.size() != 0 && LCA != early) {
+        Node* s = worklist.pop();
+        if (s->is_Load() || s->Opcode() == Op_SafePoint ||
+            (s->is_CallStaticJava() && s->as_CallStaticJava()->uncommon_trap_request() != 0)) {
+          continue;
+        } else if (s->is_MergeMem()) {
+          for (DUIterator_Fast imax, i = s->fast_outs(imax); i < imax; i++) {
+            Node* s1 = s->fast_out(i);
+            worklist.push(s1);
+          }
+        } else {
+          Node *sctrl = has_ctrl(s) ? get_ctrl(s) : s->in(0);
+          assert(sctrl != NULL || s->outcnt() == 0, "must have control");
+          if (sctrl != NULL && !sctrl->is_top() && C->can_alias(s->adr_type(), load_alias_idx) && is_dominator(early, sctrl)) {
+            LCA = dom_lca_for_get_late_ctrl(LCA, sctrl, n);
+          }
         }
       }
     }
--- a/src/hotspot/share/opto/loopopts.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/loopopts.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -41,9 +41,6 @@
 #include "opto/rootnode.hpp"
 #include "opto/subnode.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_ZGC
-#include "gc/z/c2/zBarrierSetC2.hpp"
-#endif
 
 //=============================================================================
 //------------------------------split_thru_phi---------------------------------
@@ -1075,26 +1072,21 @@
   // uses.
   // A better fix for this problem can be found in the BugTraq entry, but
   // expediency for Mantis demands this hack.
-  // 6855164: If the merge point has a FastLockNode with a PhiNode input, we stop
-  // split_if_with_blocks from splitting a block because we could not move around
-  // the FastLockNode.
+#ifdef _LP64
   for (DUIterator_Fast imax, i = region->fast_outs(imax); i < imax; i++) {
     Node* n = region->fast_out(i);
     if (n->is_Phi()) {
       for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
         Node* m = n->fast_out(j);
-        if (m->is_FastLock())
-          return false;
-#ifdef _LP64
         if (m->Opcode() == Op_ConvI2L)
           return false;
         if (m->is_CastII() && m->isa_CastII()->has_range_check()) {
           return false;
         }
-#endif
       }
     }
   }
+#endif
   return true;
 }
 
--- a/src/hotspot/share/opto/machnode.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/machnode.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -197,7 +197,7 @@
 // ADLC inherit from this class.
 class MachNode : public Node {
 public:
-  MachNode() : Node((uint)0), _num_opnds(0), _opnds(NULL) {
+  MachNode() : Node((uint)0), _barrier(0), _num_opnds(0), _opnds(NULL) {
     init_class_id(Class_Mach);
   }
   // Required boilerplate
@@ -211,6 +211,9 @@
   // no constant base node input.
   virtual uint mach_constant_base_node_input() const { return (uint)-1; }
 
+  uint8_t barrier_data() const { return _barrier; }
+  void set_barrier_data(uint data) { _barrier = data; }
+
   // Copy inputs and operands to new node of instruction.
   // Called from cisc_version() and short_branch_version().
   // !!!! The method's body is defined in ad_<arch>.cpp file.
@@ -255,6 +258,9 @@
   // output have choices - but they must use the same choice.
   virtual uint two_adr( ) const { return 0; }
 
+  // The GC might require some barrier metadata for machine code emission.
+  uint8_t _barrier;
+
   // Array of complex operand pointers.  Each corresponds to zero or
   // more leafs.  Must be set by MachNode constructor to point to an
   // internal array of MachOpers.  The MachOper array is sized by
--- a/src/hotspot/share/opto/matcher.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/matcher.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1751,6 +1751,13 @@
     _shared_nodes.map(leaf->_idx, ex);
   }
 
+  // Have mach nodes inherit GC barrier data
+  if (leaf->is_LoadStore()) {
+    mach->set_barrier_data(leaf->as_LoadStore()->barrier_data());
+  } else if (leaf->is_Mem()) {
+    mach->set_barrier_data(leaf->as_Mem()->barrier_data());
+  }
+
   return ex;
 }
 
--- a/src/hotspot/share/opto/memnode.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/memnode.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -49,9 +49,6 @@
 #include "utilities/copy.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/vmError.hpp"
-#if INCLUDE_ZGC
-#include "gc/z/c2/zBarrierSetC2.hpp"
-#endif
 
 // Portions of code courtesy of Clifford Click
 
@@ -2851,7 +2848,7 @@
   : Node(required),
     _type(rt),
     _adr_type(at),
-    _has_barrier(false)
+    _barrier(0)
 {
   init_req(MemNode::Control, c  );
   init_req(MemNode::Memory , mem);
--- a/src/hotspot/share/opto/memnode.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/memnode.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -43,6 +43,8 @@
   bool _unaligned_access; // Unaligned access from unsafe
   bool _mismatched_access; // Mismatched access from unsafe: byte read in integer array for instance
   bool _unsafe_access;     // Access of unsafe origin.
+  uint8_t _barrier; // Bit field with barrier information
+
 protected:
 #ifdef ASSERT
   const TypePtr* _adr_type;     // What kind of memory is being addressed?
@@ -62,18 +64,30 @@
                  unset          // The memory ordering is not set (used for testing)
   } MemOrd;
 protected:
-  MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at )
-    : Node(c0,c1,c2   ), _unaligned_access(false), _mismatched_access(false), _unsafe_access(false) {
+  MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at ) :
+      Node(c0,c1,c2),
+      _unaligned_access(false),
+      _mismatched_access(false),
+      _unsafe_access(false),
+      _barrier(0) {
     init_class_id(Class_Mem);
     debug_only(_adr_type=at; adr_type();)
   }
-  MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3 )
-    : Node(c0,c1,c2,c3), _unaligned_access(false), _mismatched_access(false), _unsafe_access(false) {
+  MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3 ) :
+      Node(c0,c1,c2,c3),
+      _unaligned_access(false),
+      _mismatched_access(false),
+      _unsafe_access(false),
+      _barrier(0) {
     init_class_id(Class_Mem);
     debug_only(_adr_type=at; adr_type();)
   }
-  MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3, Node *c4)
-    : Node(c0,c1,c2,c3,c4), _unaligned_access(false), _mismatched_access(false), _unsafe_access(false) {
+  MemNode( Node *c0, Node *c1, Node *c2, const TypePtr* at, Node *c3, Node *c4) :
+      Node(c0,c1,c2,c3,c4),
+      _unaligned_access(false),
+      _mismatched_access(false),
+      _unsafe_access(false),
+      _barrier(0) {
     init_class_id(Class_Mem);
     debug_only(_adr_type=at; adr_type();)
   }
@@ -125,6 +139,9 @@
 #endif
   }
 
+  uint8_t barrier_data() { return _barrier; }
+  void set_barrier_data(uint8_t barrier_data) { _barrier = barrier_data; }
+
   // Search through memory states which precede this node (load or store).
   // Look for an exact match for the address, with no intervening
   // aliased stores.
@@ -181,8 +198,6 @@
   // this field.
   const MemOrd _mo;
 
-  uint _barrier; // Bit field with barrier information
-
   AllocateNode* is_new_object_mark_load(PhaseGVN *phase) const;
 
 protected:
@@ -196,7 +211,7 @@
 public:
 
   LoadNode(Node *c, Node *mem, Node *adr, const TypePtr* at, const Type *rt, MemOrd mo, ControlDependency control_dependency)
-    : MemNode(c,mem,adr,at), _control_dependency(control_dependency), _mo(mo), _barrier(0), _type(rt) {
+    : MemNode(c,mem,adr,at), _control_dependency(control_dependency), _mo(mo), _type(rt) {
     init_class_id(Class_Load);
   }
   inline bool is_unordered() const { return !is_acquire(); }
@@ -265,10 +280,6 @@
   Node* convert_to_unsigned_load(PhaseGVN& gvn);
   Node* convert_to_signed_load(PhaseGVN& gvn);
 
-  void copy_barrier_info(const Node* src) { _barrier = src->as_Load()->_barrier; }
-  uint barrier_data() { return _barrier; }
-  void set_barrier_data(uint barrier_data) { _barrier |= barrier_data; }
-
   void pin() { _control_dependency = Pinned; }
   bool has_unknown_control_dependency() const { return _control_dependency == UnknownControl; }
 
@@ -820,7 +831,7 @@
 private:
   const Type* const _type;      // What kind of value is loaded?
   const TypePtr* _adr_type;     // What kind of memory is being addressed?
-  bool _has_barrier;
+  uint8_t _barrier; // Bit field with barrier information
   virtual uint size_of() const; // Size is bigger
 public:
   LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* rt, uint required );
@@ -833,8 +844,9 @@
 
   bool result_not_used() const;
   MemBarNode* trailing_membar() const;
-  void set_has_barrier() { _has_barrier = true; };
-  bool has_barrier() const { return _has_barrier; };
+
+  uint8_t barrier_data() { return _barrier; }
+  void set_barrier_data(uint8_t barrier_data) { _barrier = barrier_data; }
 };
 
 class LoadStoreConditionalNode : public LoadStoreNode {
@@ -886,6 +898,7 @@
   MemNode::MemOrd order() const {
     return _mem_ord;
   }
+  virtual uint size_of() const { return sizeof(*this); }
 };
 
 class CompareAndExchangeNode : public LoadStoreNode {
@@ -903,6 +916,7 @@
   MemNode::MemOrd order() const {
     return _mem_ord;
   }
+  virtual uint size_of() const { return sizeof(*this); }
 };
 
 //------------------------------CompareAndSwapBNode---------------------------
--- a/src/hotspot/share/opto/node.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/node.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -546,9 +546,6 @@
   if (n->is_SafePoint()) {
     n->as_SafePoint()->clone_replaced_nodes();
   }
-  if (n->is_Load()) {
-    n->as_Load()->copy_barrier_info(this);
-  }
   return n;                     // Return the clone
 }
 
@@ -1473,10 +1470,6 @@
   if (req() < 2 || (_flags & Flag_needs_anti_dependence_check) == 0) {
     return false;
   }
-  BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
-  if (!bs->needs_anti_dependence_check(this)) {
-    return false;
-  }
   return in(1)->bottom_type()->has_memory();
 }
 
--- a/src/hotspot/share/opto/node.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/node.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -83,8 +83,6 @@
 class JumpNode;
 class JumpProjNode;
 class LoadNode;
-class LoadBarrierNode;
-class LoadBarrierSlowRegNode;
 class LoadStoreNode;
 class LoadStoreConditionalNode;
 class LockNode;
@@ -642,7 +640,6 @@
       DEFINE_CLASS_ID(MemBar,      Multi, 3)
         DEFINE_CLASS_ID(Initialize,       MemBar, 0)
         DEFINE_CLASS_ID(MemBarStoreStore, MemBar, 1)
-      DEFINE_CLASS_ID(LoadBarrier, Multi, 4)
 
     DEFINE_CLASS_ID(Mach,  Node, 1)
       DEFINE_CLASS_ID(MachReturn, Mach, 0)
@@ -679,7 +676,6 @@
       DEFINE_CLASS_ID(EncodeNarrowPtr, Type, 6)
         DEFINE_CLASS_ID(EncodeP, EncodeNarrowPtr, 0)
         DEFINE_CLASS_ID(EncodePKlass, EncodeNarrowPtr, 1)
-      DEFINE_CLASS_ID(LoadBarrierSlowReg, Type, 7)
 
     DEFINE_CLASS_ID(Proj,  Node, 3)
       DEFINE_CLASS_ID(CatchProj, Proj, 0)
@@ -836,8 +832,6 @@
   DEFINE_CLASS_QUERY(Load)
   DEFINE_CLASS_QUERY(LoadStore)
   DEFINE_CLASS_QUERY(LoadStoreConditional)
-  DEFINE_CLASS_QUERY(LoadBarrier)
-  DEFINE_CLASS_QUERY(LoadBarrierSlowReg)
   DEFINE_CLASS_QUERY(Lock)
   DEFINE_CLASS_QUERY(Loop)
   DEFINE_CLASS_QUERY(Mach)
--- a/src/hotspot/share/opto/output.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/output.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -31,6 +31,8 @@
 #include "compiler/compileBroker.hpp"
 #include "compiler/compilerDirectives.hpp"
 #include "compiler/oopMap.hpp"
+#include "gc/shared/barrierSet.hpp"
+#include "gc/shared/c2/barrierSetC2.hpp"
 #include "memory/allocation.inline.hpp"
 #include "opto/ad.hpp"
 #include "opto/callnode.hpp"
@@ -114,35 +116,33 @@
     }
   }
 
+  // Keeper of sizing aspects
+  BufferSizingData buf_sizes = BufferSizingData();
+
+  // Initialize code buffer
+  estimate_buffer_size(buf_sizes._const);
+  if (failing()) return;
+
+  // Pre-compute the length of blocks and replace
+  // long branches with short if machine supports it.
+  // Must be done before ScheduleAndBundle due to SPARC delay slots
   uint* blk_starts = NEW_RESOURCE_ARRAY(uint, _cfg->number_of_blocks() + 1);
   blk_starts[0] = 0;
-
-  // Initialize code buffer and process short branches.
-  CodeBuffer* cb = init_buffer(blk_starts);
-
-  if (cb == NULL || failing()) {
-    return;
-  }
+  shorten_branches(blk_starts, buf_sizes);
 
   ScheduleAndBundle();
-
-#ifndef PRODUCT
-  if (trace_opto_output()) {
-    tty->print("\n---- After ScheduleAndBundle ----\n");
-    for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
-      tty->print("\nBB#%03d:\n", i);
-      Block* block = _cfg->get_block(i);
-      for (uint j = 0; j < block->number_of_nodes(); j++) {
-        Node* n = block->get_node(j);
-        OptoReg::Name reg = _regalloc->get_reg_first(n);
-        tty->print(" %-6s ", reg >= 0 && reg < REG_COUNT ? Matcher::regName[reg] : "");
-        n->dump();
-      }
-    }
+  if (failing()) {
+    return;
   }
-#endif
-
-  if (failing()) {
+
+  // Late barrier analysis must be done after schedule and bundle
+  // Otherwise liveness based spilling will fail
+  BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
+  bs->late_barrier_analysis();
+
+  // Complete sizing of codebuffer
+  CodeBuffer* cb = init_buffer(buf_sizes);
+  if (cb == NULL || failing()) {
     return;
   }
 
@@ -223,7 +223,7 @@
 
 // The architecture description provides short branch variants for some long
 // branch instructions. Replace eligible long branches with short branches.
-void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size, int& stub_size) {
+void Compile::shorten_branches(uint* blk_starts, BufferSizingData& buf_sizes) {
   // Compute size of each block, method size, and relocation information size
   uint nblocks  = _cfg->number_of_blocks();
 
@@ -241,11 +241,11 @@
   bool has_short_branch_candidate = false;
 
   // Initialize the sizes to 0
-  code_size  = 0;          // Size in bytes of generated code
-  stub_size  = 0;          // Size in bytes of all stub entries
+  int code_size  = 0;          // Size in bytes of generated code
+  int stub_size  = 0;          // Size in bytes of all stub entries
   // Size in bytes of all relocation entries, including those in local stubs.
   // Start with 2-bytes of reloc info for the unvalidated entry point
-  reloc_size = 1;          // Number of relocation entries
+  int reloc_size = 1;          // Number of relocation entries
 
   // Make three passes.  The first computes pessimistic blk_starts,
   // relative jmp_offset and reloc_size information.  The second performs
@@ -479,6 +479,10 @@
   // a relocation index.
   // The CodeBuffer will expand the locs array if this estimate is too low.
   reloc_size *= 10 / sizeof(relocInfo);
+
+  buf_sizes._reloc = reloc_size;
+  buf_sizes._code  = code_size;
+  buf_sizes._stub  = stub_size;
 }
 
 //------------------------------FillLocArray-----------------------------------
@@ -490,8 +494,8 @@
   // This should never have accepted Bad before
   assert(OptoReg::is_valid(regnum), "location must be valid");
   return (OptoReg::is_reg(regnum))
-    ? new LocationValue(Location::new_reg_loc(l_type, OptoReg::as_VMReg(regnum)) )
-    : new LocationValue(Location::new_stk_loc(l_type,  ra->reg2offset(regnum)));
+         ? new LocationValue(Location::new_reg_loc(l_type, OptoReg::as_VMReg(regnum)) )
+         : new LocationValue(Location::new_stk_loc(l_type,  ra->reg2offset(regnum)));
 }
 
 
@@ -610,12 +614,12 @@
     }
 #endif //_LP64
     else if( (t->base() == Type::FloatBot || t->base() == Type::FloatCon) &&
-               OptoReg::is_reg(regnum) ) {
+             OptoReg::is_reg(regnum) ) {
       array->append(new_loc_value( _regalloc, regnum, Matcher::float_in_double()
-                                   ? Location::float_in_dbl : Location::normal ));
+                                                      ? Location::float_in_dbl : Location::normal ));
     } else if( t->base() == Type::Int && OptoReg::is_reg(regnum) ) {
       array->append(new_loc_value( _regalloc, regnum, Matcher::int_in_long
-                                   ? Location::int_in_long : Location::normal ));
+                                                      ? Location::int_in_long : Location::normal ));
     } else if( t->base() == Type::NarrowOop ) {
       array->append(new_loc_value( _regalloc, regnum, Location::narrowoop ));
     } else {
@@ -626,48 +630,48 @@
 
   // No register.  It must be constant data.
   switch (t->base()) {
-  case Type::Half:              // Second half of a double
-    ShouldNotReachHere();       // Caller should skip 2nd halves
-    break;
-  case Type::AnyPtr:
-    array->append(new ConstantOopWriteValue(NULL));
-    break;
-  case Type::AryPtr:
-  case Type::InstPtr:          // fall through
-    array->append(new ConstantOopWriteValue(t->isa_oopptr()->const_oop()->constant_encoding()));
-    break;
-  case Type::NarrowOop:
-    if (t == TypeNarrowOop::NULL_PTR) {
+    case Type::Half:              // Second half of a double
+      ShouldNotReachHere();       // Caller should skip 2nd halves
+      break;
+    case Type::AnyPtr:
       array->append(new ConstantOopWriteValue(NULL));
-    } else {
-      array->append(new ConstantOopWriteValue(t->make_ptr()->isa_oopptr()->const_oop()->constant_encoding()));
+      break;
+    case Type::AryPtr:
+    case Type::InstPtr:          // fall through
+      array->append(new ConstantOopWriteValue(t->isa_oopptr()->const_oop()->constant_encoding()));
+      break;
+    case Type::NarrowOop:
+      if (t == TypeNarrowOop::NULL_PTR) {
+        array->append(new ConstantOopWriteValue(NULL));
+      } else {
+        array->append(new ConstantOopWriteValue(t->make_ptr()->isa_oopptr()->const_oop()->constant_encoding()));
+      }
+      break;
+    case Type::Int:
+      array->append(new ConstantIntValue(t->is_int()->get_con()));
+      break;
+    case Type::RawPtr:
+      // A return address (T_ADDRESS).
+      assert((intptr_t)t->is_ptr()->get_con() < (intptr_t)0x10000, "must be a valid BCI");
+#ifdef _LP64
+      // Must be restored to the full-width 64-bit stack slot.
+      array->append(new ConstantLongValue(t->is_ptr()->get_con()));
+#else
+      array->append(new ConstantIntValue(t->is_ptr()->get_con()));
+#endif
+      break;
+    case Type::FloatCon: {
+      float f = t->is_float_constant()->getf();
+      array->append(new ConstantIntValue(jint_cast(f)));
+      break;
     }
-    break;
-  case Type::Int:
-    array->append(new ConstantIntValue(t->is_int()->get_con()));
-    break;
-  case Type::RawPtr:
-    // A return address (T_ADDRESS).
-    assert((intptr_t)t->is_ptr()->get_con() < (intptr_t)0x10000, "must be a valid BCI");
+    case Type::DoubleCon: {
+      jdouble d = t->is_double_constant()->getd();
 #ifdef _LP64
-    // Must be restored to the full-width 64-bit stack slot.
-    array->append(new ConstantLongValue(t->is_ptr()->get_con()));
+      array->append(new ConstantIntValue((jint)0));
+      array->append(new ConstantDoubleValue(d));
 #else
-    array->append(new ConstantIntValue(t->is_ptr()->get_con()));
-#endif
-    break;
-  case Type::FloatCon: {
-    float f = t->is_float_constant()->getf();
-    array->append(new ConstantIntValue(jint_cast(f)));
-    break;
-  }
-  case Type::DoubleCon: {
-    jdouble d = t->is_double_constant()->getd();
-#ifdef _LP64
-    array->append(new ConstantIntValue((jint)0));
-    array->append(new ConstantDoubleValue(d));
-#else
-    // Repack the double as two jints.
+      // Repack the double as two jints.
     // The convention the interpreter uses is that the second local
     // holds the first raw word of the native double representation.
     // This is actually reasonable, since locals and stack arrays
@@ -679,15 +683,15 @@
     array->append(new ConstantIntValue(acc.words[1]));
     array->append(new ConstantIntValue(acc.words[0]));
 #endif
-    break;
-  }
-  case Type::Long: {
-    jlong d = t->is_long()->get_con();
+      break;
+    }
+    case Type::Long: {
+      jlong d = t->is_long()->get_con();
 #ifdef _LP64
-    array->append(new ConstantIntValue((jint)0));
-    array->append(new ConstantLongValue(d));
+      array->append(new ConstantIntValue((jint)0));
+      array->append(new ConstantLongValue(d));
 #else
-    // Repack the long as two jints.
+      // Repack the long as two jints.
     // The convention the interpreter uses is that the second local
     // holds the first raw word of the native double representation.
     // This is actually reasonable, since locals and stack arrays
@@ -699,14 +703,14 @@
     array->append(new ConstantIntValue(acc.words[1]));
     array->append(new ConstantIntValue(acc.words[0]));
 #endif
-    break;
-  }
-  case Type::Top:               // Add an illegal value here
-    array->append(new LocationValue(Location()));
-    break;
-  default:
-    ShouldNotReachHere();
-    break;
+      break;
+    }
+    case Type::Top:               // Add an illegal value here
+      array->append(new LocationValue(Location()));
+      break;
+    default:
+      ShouldNotReachHere();
+      break;
   }
 }
 
@@ -871,58 +875,58 @@
 
 // A simplified version of Process_OopMap_Node, to handle non-safepoints.
 class NonSafepointEmitter {
-  Compile*  C;
-  JVMState* _pending_jvms;
-  int       _pending_offset;
-
-  void emit_non_safepoint();
+    Compile*  C;
+    JVMState* _pending_jvms;
+    int       _pending_offset;
+
+    void emit_non_safepoint();
 
  public:
-  NonSafepointEmitter(Compile* compile) {
-    this->C = compile;
-    _pending_jvms = NULL;
-    _pending_offset = 0;
-  }
-
-  void observe_instruction(Node* n, int pc_offset) {
-    if (!C->debug_info()->recording_non_safepoints())  return;
-
-    Node_Notes* nn = C->node_notes_at(n->_idx);
-    if (nn == NULL || nn->jvms() == NULL)  return;
-    if (_pending_jvms != NULL &&
-        _pending_jvms->same_calls_as(nn->jvms())) {
-      // Repeated JVMS?  Stretch it up here.
-      _pending_offset = pc_offset;
-    } else {
+    NonSafepointEmitter(Compile* compile) {
+      this->C = compile;
+      _pending_jvms = NULL;
+      _pending_offset = 0;
+    }
+
+    void observe_instruction(Node* n, int pc_offset) {
+      if (!C->debug_info()->recording_non_safepoints())  return;
+
+      Node_Notes* nn = C->node_notes_at(n->_idx);
+      if (nn == NULL || nn->jvms() == NULL)  return;
       if (_pending_jvms != NULL &&
+          _pending_jvms->same_calls_as(nn->jvms())) {
+        // Repeated JVMS?  Stretch it up here.
+        _pending_offset = pc_offset;
+      } else {
+        if (_pending_jvms != NULL &&
+            _pending_offset < pc_offset) {
+          emit_non_safepoint();
+        }
+        _pending_jvms = NULL;
+        if (pc_offset > C->debug_info()->last_pc_offset()) {
+          // This is the only way _pending_jvms can become non-NULL:
+          _pending_jvms = nn->jvms();
+          _pending_offset = pc_offset;
+        }
+      }
+    }
+
+    // Stay out of the way of real safepoints:
+    void observe_safepoint(JVMState* jvms, int pc_offset) {
+      if (_pending_jvms != NULL &&
+          !_pending_jvms->same_calls_as(jvms) &&
           _pending_offset < pc_offset) {
         emit_non_safepoint();
       }
       _pending_jvms = NULL;
-      if (pc_offset > C->debug_info()->last_pc_offset()) {
-        // This is the only way _pending_jvms can become non-NULL:
-        _pending_jvms = nn->jvms();
-        _pending_offset = pc_offset;
-      }
     }
-  }
-
-  // Stay out of the way of real safepoints:
-  void observe_safepoint(JVMState* jvms, int pc_offset) {
-    if (_pending_jvms != NULL &&
-        !_pending_jvms->same_calls_as(jvms) &&
-        _pending_offset < pc_offset) {
-      emit_non_safepoint();
+
+    void flush_at_end() {
+      if (_pending_jvms != NULL) {
+        emit_non_safepoint();
+      }
+      _pending_jvms = NULL;
     }
-    _pending_jvms = NULL;
-  }
-
-  void flush_at_end() {
-    if (_pending_jvms != NULL) {
-      emit_non_safepoint();
-    }
-    _pending_jvms = NULL;
-  }
 };
 
 void NonSafepointEmitter::emit_non_safepoint() {
@@ -952,15 +956,11 @@
 }
 
 //------------------------------init_buffer------------------------------------
-CodeBuffer* Compile::init_buffer(uint* blk_starts) {
+void Compile::estimate_buffer_size(int& const_req) {
 
   // Set the initially allocated size
-  int  code_req   = initial_code_capacity;
-  int  locs_req   = initial_locs_capacity;
-  int  stub_req   = initial_stub_capacity;
-  int  const_req  = initial_const_capacity;
-
-  int  pad_req    = NativeCall::instruction_size;
+  const_req = initial_const_capacity;
+
   // The extra spacing after the code is necessary on some platforms.
   // Sometimes we need to patch in a jump after the last instruction,
   // if the nmethod has been deoptimized.  (See 4932387, 4894843.)
@@ -972,7 +972,7 @@
 
   // Compute prolog code size
   _method_size = 0;
-  _frame_slots = OptoReg::reg2stack(_matcher->_old_SP)+_regalloc->_framesize;
+  _frame_slots = OptoReg::reg2stack(_matcher->_old_SP) + _regalloc->_framesize;
 #if defined(IA64) && !defined(AIX)
   if (save_argument_registers()) {
     // 4815101: this is a stub with implicit and unknown precision fp args.
@@ -1021,11 +1021,18 @@
   // Initialize the space for the BufferBlob used to find and verify
   // instruction size in MachNode::emit_size()
   init_scratch_buffer_blob(const_req);
-  if (failing())  return NULL; // Out of memory
-
-  // Pre-compute the length of blocks and replace
-  // long branches with short if machine supports it.
-  shorten_branches(blk_starts, code_req, locs_req, stub_req);
+}
+
+CodeBuffer* Compile::init_buffer(BufferSizingData& buf_sizes) {
+
+  int stub_req  = buf_sizes._stub;
+  int code_req  = buf_sizes._code;
+  int const_req = buf_sizes._const;
+
+  int pad_req   = NativeCall::instruction_size;
+
+  BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
+  stub_req += bs->estimate_stub_size();
 
   // nmethod and CodeBuffer count stubs & constants as part of method's code.
   // class HandlerImpl is platform-specific and defined in the *.ad files.
@@ -1038,18 +1045,18 @@
     code_req = const_req = stub_req = exception_handler_req = deopt_handler_req = 0x10;  // force expansion
 
   int total_req =
-    const_req +
-    code_req +
-    pad_req +
-    stub_req +
-    exception_handler_req +
-    deopt_handler_req;               // deopt handler
+          const_req +
+          code_req +
+          pad_req +
+          stub_req +
+          exception_handler_req +
+          deopt_handler_req;               // deopt handler
 
   if (has_method_handle_invokes())
     total_req += deopt_handler_req;  // deopt MH handler
 
   CodeBuffer* cb = code_buffer();
-  cb->initialize(total_req, locs_req);
+  cb->initialize(total_req, buf_sizes._reloc);
 
   // Have we run out of code space?
   if ((cb->blob() == NULL) || (!CompileBroker::should_compile_new_jobs())) {
@@ -1268,12 +1275,12 @@
           Process_OopMap_Node(mach, current_offset);
         } // End if safepoint
 
-        // If this is a null check, then add the start of the previous instruction to the list
+          // If this is a null check, then add the start of the previous instruction to the list
         else if( mach->is_MachNullCheck() ) {
           inct_starts[inct_cnt++] = previous_offset;
         }
 
-        // If this is a branch, then fill in the label with the target BB's label
+          // If this is a branch, then fill in the label with the target BB's label
         else if (mach->is_MachBranch()) {
           // This requires the TRUE branch target be in succs[0]
           uint block_num = block->non_connector_successor(0)->_pre_order;
@@ -1284,8 +1291,8 @@
           bool delay_slot_is_used = valid_bundle_info(n) &&
                                     node_bundling(n)->use_unconditional_delay();
           if (!delay_slot_is_used && mach->may_be_short_branch()) {
-           assert(delay_slot == NULL, "not expecting delay slot node");
-           int br_size = n->size(_regalloc);
+            assert(delay_slot == NULL, "not expecting delay slot node");
+            int br_size = n->size(_regalloc);
             int offset = blk_starts[block_num] - current_offset;
             if (block_num >= i) {
               // Current and following block's offset are not
@@ -1343,7 +1350,7 @@
           }
         }
 #ifdef ASSERT
-        // Check that oop-store precedes the card-mark
+          // Check that oop-store precedes the card-mark
         else if (mach->ideal_Opcode() == Op_StoreCM) {
           uint storeCM_idx = j;
           int count = 0;
@@ -1514,6 +1521,10 @@
   }
 #endif
 
+  BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
+  bs->emit_stubs(*cb);
+  if (failing())  return;
+
 #ifndef PRODUCT
   // Information on the size of the method, without the extraneous code
   Scheduling::increment_method_size(cb->insts_size());
@@ -1688,20 +1699,20 @@
 // Initializer for class Scheduling
 
 Scheduling::Scheduling(Arena *arena, Compile &compile)
-  : _arena(arena),
-    _cfg(compile.cfg()),
-    _regalloc(compile.regalloc()),
-    _scheduled(arena),
-    _available(arena),
-    _reg_node(arena),
-    _pinch_free_list(arena),
-    _next_node(NULL),
-    _bundle_instr_count(0),
-    _bundle_cycle_number(0),
-    _bundle_use(0, 0, resource_count, &_bundle_use_elements[0])
+        : _arena(arena),
+          _cfg(compile.cfg()),
+          _regalloc(compile.regalloc()),
+          _scheduled(arena),
+          _available(arena),
+          _reg_node(arena),
+          _pinch_free_list(arena),
+          _next_node(NULL),
+          _bundle_instr_count(0),
+          _bundle_cycle_number(0),
+          _bundle_use(0, 0, resource_count, &_bundle_use_elements[0])
 #ifndef PRODUCT
-  , _branches(0)
-  , _unconditional_delays(0)
+        , _branches(0)
+        , _unconditional_delays(0)
 #endif
 {
   // Create a MachNopNode
@@ -1782,8 +1793,8 @@
   _bundle_use.reset();
 
   memcpy(_bundle_use_elements,
-    Pipeline_Use::elaborated_elements,
-    sizeof(Pipeline_Use::elaborated_elements));
+         Pipeline_Use::elaborated_elements,
+         sizeof(Pipeline_Use::elaborated_elements));
 }
 
 // Perform instruction scheduling and bundling over the sequence of
@@ -1810,6 +1821,22 @@
   // Walk backwards over each basic block, computing the needed alignment
   // Walk over all the basic blocks
   scheduling.DoScheduling();
+
+#ifndef PRODUCT
+  if (trace_opto_output()) {
+    tty->print("\n---- After ScheduleAndBundle ----\n");
+    for (uint i = 0; i < _cfg->number_of_blocks(); i++) {
+      tty->print("\nBB#%03d:\n", i);
+      Block* block = _cfg->get_block(i);
+      for (uint j = 0; j < block->number_of_nodes(); j++) {
+        Node* n = block->get_node(j);
+        OptoReg::Name reg = _regalloc->get_reg_first(n);
+        tty->print(" %-6s ", reg >= 0 && reg < REG_COUNT ? Matcher::regName[reg] : "");
+        n->dump();
+      }
+    }
+  }
+#endif
 }
 
 // Compute the latency of all the instructions.  This is fairly simple,
@@ -1878,7 +1905,7 @@
 #ifndef PRODUCT
     if (_cfg->C->trace_opto_output())
       tty->print("#     NodeFitsInBundle [%4d]: FALSE; latency %4d > %d\n",
-        n->_idx, _current_latency[n_idx], _bundle_cycle_number);
+                 n->_idx, _current_latency[n_idx], _bundle_cycle_number);
 #endif
     return (false);
   }
@@ -1895,7 +1922,7 @@
 #ifndef PRODUCT
     if (_cfg->C->trace_opto_output())
       tty->print("#     NodeFitsInBundle [%4d]: FALSE; too many instructions: %d > %d\n",
-        n->_idx, _bundle_instr_count + instruction_count, Pipeline::_max_instrs_per_cycle);
+                 n->_idx, _bundle_instr_count + instruction_count, Pipeline::_max_instrs_per_cycle);
 #endif
     return (false);
   }
@@ -2103,12 +2130,12 @@
         // Don't allow safepoints in the branch shadow, that will
         // cause a number of difficulties
         if ( avail_pipeline->instructionCount() == 1 &&
-            !avail_pipeline->hasMultipleBundles() &&
-            !avail_pipeline->hasBranchDelay() &&
-            Pipeline::instr_has_unit_size() &&
-            d->size(_regalloc) == Pipeline::instr_unit_size() &&
-            NodeFitsInBundle(d) &&
-            !node_bundling(d)->used_in_delay()) {
+             !avail_pipeline->hasMultipleBundles() &&
+             !avail_pipeline->hasBranchDelay() &&
+             Pipeline::instr_has_unit_size() &&
+             d->size(_regalloc) == Pipeline::instr_unit_size() &&
+             NodeFitsInBundle(d) &&
+             !node_bundling(d)->used_in_delay()) {
 
           if (d->is_Mach() && !d->is_MachSafePoint()) {
             // A node that fits in the delay slot was found, so we need to
@@ -2153,13 +2180,13 @@
     // step of the bundles
     if (!NodeFitsInBundle(n)) {
 #ifndef PRODUCT
-        if (_cfg->C->trace_opto_output())
-          tty->print("#  *** STEP(branch won't fit) ***\n");
+      if (_cfg->C->trace_opto_output())
+        tty->print("#  *** STEP(branch won't fit) ***\n");
 #endif
-        // Update the state information
-        _bundle_instr_count = 0;
-        _bundle_cycle_number += 1;
-        _bundle_use.step(1);
+      // Update the state information
+      _bundle_instr_count = 0;
+      _bundle_cycle_number += 1;
+      _bundle_use.step(1);
     }
   }
 
@@ -2205,8 +2232,8 @@
 #ifndef PRODUCT
         if (_cfg->C->trace_opto_output())
           tty->print("#  *** STEP(%d >= %d instructions) ***\n",
-            instruction_count + _bundle_instr_count,
-            Pipeline::_max_instrs_per_cycle);
+                     instruction_count + _bundle_instr_count,
+                     Pipeline::_max_instrs_per_cycle);
 #endif
         step(1);
       }
@@ -2412,7 +2439,7 @@
     }
     assert(!last->is_Mach() || last->as_Mach()->ideal_Opcode() != Op_Con, "");
     if( last->is_Catch() ||
-       (last->is_Mach() && last->as_Mach()->ideal_Opcode() == Op_Halt) ) {
+        (last->is_Mach() && last->as_Mach()->ideal_Opcode() == Op_Halt) ) {
       // There might be a prior call.  Skip it.
       while (_bb_start < _bb_end && bb->get_node(--_bb_end)->is_MachProj());
     } else if( last->is_MachNullCheck() ) {
@@ -2482,7 +2509,7 @@
     }
 #endif
 #ifdef ASSERT
-  verify_good_schedule(bb,"after block local scheduling");
+    verify_good_schedule(bb,"after block local scheduling");
 #endif
   }
 
@@ -2830,31 +2857,31 @@
 //
 void Scheduling::garbage_collect_pinch_nodes() {
 #ifndef PRODUCT
-    if (_cfg->C->trace_opto_output()) tty->print("Reclaimed pinch nodes:");
+  if (_cfg->C->trace_opto_output()) tty->print("Reclaimed pinch nodes:");
 #endif
-    int trace_cnt = 0;
-    for (uint k = 0; k < _reg_node.Size(); k++) {
-      Node* pinch = _reg_node[k];
-      if ((pinch != NULL) && pinch->Opcode() == Op_Node &&
-          // no predecence input edges
-          (pinch->req() == pinch->len() || pinch->in(pinch->req()) == NULL) ) {
-        cleanup_pinch(pinch);
-        _pinch_free_list.push(pinch);
-        _reg_node.map(k, NULL);
+  int trace_cnt = 0;
+  for (uint k = 0; k < _reg_node.Size(); k++) {
+    Node* pinch = _reg_node[k];
+    if ((pinch != NULL) && pinch->Opcode() == Op_Node &&
+        // no predecence input edges
+        (pinch->req() == pinch->len() || pinch->in(pinch->req()) == NULL) ) {
+      cleanup_pinch(pinch);
+      _pinch_free_list.push(pinch);
+      _reg_node.map(k, NULL);
 #ifndef PRODUCT
-        if (_cfg->C->trace_opto_output()) {
-          trace_cnt++;
-          if (trace_cnt > 40) {
-            tty->print("\n");
-            trace_cnt = 0;
-          }
-          tty->print(" %d", pinch->_idx);
+      if (_cfg->C->trace_opto_output()) {
+        trace_cnt++;
+        if (trace_cnt > 40) {
+          tty->print("\n");
+          trace_cnt = 0;
         }
+        tty->print(" %d", pinch->_idx);
+      }
 #endif
-      }
     }
+  }
 #ifndef PRODUCT
-    if (_cfg->C->trace_opto_output()) tty->print("\n");
+  if (_cfg->C->trace_opto_output()) tty->print("\n");
 #endif
 }
 
@@ -2891,19 +2918,19 @@
 void Scheduling::print_statistics() {
   // Print the size added by nops for bundling
   tty->print("Nops added %d bytes to total of %d bytes",
-    _total_nop_size, _total_method_size);
+             _total_nop_size, _total_method_size);
   if (_total_method_size > 0)
     tty->print(", for %.2f%%",
-      ((double)_total_nop_size) / ((double) _total_method_size) * 100.0);
+               ((double)_total_nop_size) / ((double) _total_method_size) * 100.0);
   tty->print("\n");
 
   // Print the number of branch shadows filled
   if (Pipeline::_branch_has_delay_slot) {
     tty->print("Of %d branches, %d had unconditional delay slots filled",
-      _total_branches, _total_unconditional_delays);
+               _total_branches, _total_unconditional_delays);
     if (_total_branches > 0)
       tty->print(", for %.2f%%",
-        ((double)_total_unconditional_delays) / ((double)_total_branches) * 100.0);
+                 ((double)_total_unconditional_delays) / ((double)_total_branches) * 100.0);
     tty->print("\n");
   }
 
@@ -2917,6 +2944,6 @@
 
   if (total_bundles > 0)
     tty->print("Average ILP (excluding nops) is %.2f\n",
-      ((double)total_instructions) / ((double)total_bundles));
+               ((double)total_instructions) / ((double)total_bundles));
 }
 #endif
--- a/src/hotspot/share/opto/output.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/output.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -40,7 +40,6 @@
 class PhaseChaitin;
 class Pipeline_Use_Element;
 class Pipeline_Use;
-
 #ifndef PRODUCT
 #define DEBUG_ARG(x) , x
 #else
@@ -49,10 +48,7 @@
 
 // Define the initial sizes for allocation of the resizable code buffer
 enum {
-  initial_code_capacity  =  16 * 1024,
-  initial_stub_capacity  =   4 * 1024,
-  initial_const_capacity =   4 * 1024,
-  initial_locs_capacity  =   3 * 1024
+  initial_const_capacity =   4 * 1024
 };
 
 //------------------------------Scheduling----------------------------------
--- a/src/hotspot/share/opto/phaseX.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/phaseX.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1648,14 +1648,14 @@
     // of the mirror load depends on the type of 'n'. See LoadNode::Value().
     //   LoadBarrier?(LoadP(LoadP(AddP(foo:Klass, #java_mirror))))
     BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
-    bool has_load_barriers = bs->has_load_barriers();
+    bool has_load_barrier_nodes = bs->has_load_barrier_nodes();
 
     if (use_op == Op_LoadP && use->bottom_type()->isa_rawptr()) {
       for (DUIterator_Fast i2max, i2 = use->fast_outs(i2max); i2 < i2max; i2++) {
         Node* u = use->fast_out(i2);
         const Type* ut = u->bottom_type();
         if (u->Opcode() == Op_LoadP && ut->isa_instptr()) {
-          if (has_load_barriers) {
+          if (has_load_barrier_nodes) {
             // Search for load barriers behind the load
             for (DUIterator_Fast i3max, i3 = u->fast_outs(i3max); i3 < i3max; i3++) {
               Node* b = u->fast_out(i3);
@@ -1808,14 +1808,14 @@
         // Loading the java mirror from a Klass requires two loads and the type
         // of the mirror load depends on the type of 'n'. See LoadNode::Value().
         BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
-        bool has_load_barriers = bs->has_load_barriers();
+        bool has_load_barrier_nodes = bs->has_load_barrier_nodes();
 
         if (m_op == Op_LoadP && m->bottom_type()->isa_rawptr()) {
           for (DUIterator_Fast i2max, i2 = m->fast_outs(i2max); i2 < i2max; i2++) {
             Node* u = m->fast_out(i2);
             const Type* ut = u->bottom_type();
             if (u->Opcode() == Op_LoadP && ut->isa_instptr() && ut != type(u)) {
-              if (has_load_barriers) {
+              if (has_load_barrier_nodes) {
                 // Search for load barriers behind the load
                 for (DUIterator_Fast i3max, i3 = u->fast_outs(i3max); i3 < i3max; i3++) {
                   Node* b = u->fast_out(i3);
--- a/src/hotspot/share/opto/split_if.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/opto/split_if.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -110,83 +110,90 @@
         n->dump();
       }
 #endif
-      // Clone down any block-local BoolNode uses of this CmpNode
-      for (DUIterator i = n->outs(); n->has_out(i); i++) {
-        Node* bol = n->out(i);
-        assert( bol->is_Bool(), "" );
-        if (bol->outcnt() == 1) {
-          Node* use = bol->unique_out();
-          if (use->Opcode() == Op_Opaque4) {
-            if (use->outcnt() == 1) {
-              Node* iff = use->unique_out();
-              assert(iff->is_If(), "unexpected node type");
-              Node *use_c = iff->in(0);
+      if (!n->is_FastLock()) {
+        // Clone down any block-local BoolNode uses of this CmpNode
+        for (DUIterator i = n->outs(); n->has_out(i); i++) {
+          Node* bol = n->out(i);
+          assert( bol->is_Bool(), "" );
+          if (bol->outcnt() == 1) {
+            Node* use = bol->unique_out();
+            if (use->Opcode() == Op_Opaque4) {
+              if (use->outcnt() == 1) {
+                Node* iff = use->unique_out();
+                assert(iff->is_If(), "unexpected node type");
+                Node *use_c = iff->in(0);
+                if (use_c == blk1 || use_c == blk2) {
+                  continue;
+                }
+              }
+            } else {
+              // We might see an Opaque1 from a loop limit check here
+              assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1, "unexpected node type");
+              Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use);
               if (use_c == blk1 || use_c == blk2) {
+                assert(use->is_CMove(), "unexpected node type");
                 continue;
               }
             }
-          } else {
-            // We might see an Opaque1 from a loop limit check here
-            assert(use->is_If() || use->is_CMove() || use->Opcode() == Op_Opaque1, "unexpected node type");
-            Node *use_c = use->is_If() ? use->in(0) : get_ctrl(use);
-            if (use_c == blk1 || use_c == blk2) {
-              assert(use->is_CMove(), "unexpected node type");
-              continue;
+          }
+          if (get_ctrl(bol) == blk1 || get_ctrl(bol) == blk2) {
+            // Recursively sink any BoolNode
+#ifndef PRODUCT
+            if( PrintOpto && VerifyLoopOptimizations ) {
+              tty->print("Cloning down: ");
+              bol->dump();
             }
-          }
-        }
-        if (get_ctrl(bol) == blk1 || get_ctrl(bol) == blk2) {
-          // Recursively sink any BoolNode
-#ifndef PRODUCT
-          if( PrintOpto && VerifyLoopOptimizations ) {
-            tty->print("Cloning down: ");
-            bol->dump();
-          }
 #endif
-          for (DUIterator j = bol->outs(); bol->has_out(j); j++) {
-            Node* u = bol->out(j);
-            // Uses are either IfNodes, CMoves or Opaque4
-            if (u->Opcode() == Op_Opaque4) {
-              assert(u->in(1) == bol, "bad input");
-              for (DUIterator_Last kmin, k = u->last_outs(kmin); k >= kmin; --k) {
-                Node* iff = u->last_out(k);
-                assert(iff->is_If() || iff->is_CMove(), "unexpected node type");
-                assert( iff->in(1) == u, "" );
+            for (DUIterator j = bol->outs(); bol->has_out(j); j++) {
+              Node* u = bol->out(j);
+              // Uses are either IfNodes, CMoves or Opaque4
+              if (u->Opcode() == Op_Opaque4) {
+                assert(u->in(1) == bol, "bad input");
+                for (DUIterator_Last kmin, k = u->last_outs(kmin); k >= kmin; --k) {
+                  Node* iff = u->last_out(k);
+                  assert(iff->is_If() || iff->is_CMove(), "unexpected node type");
+                  assert( iff->in(1) == u, "" );
+                  // Get control block of either the CMove or the If input
+                  Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff);
+                  Node *x1 = bol->clone();
+                  Node *x2 = u->clone();
+                  register_new_node(x1, iff_ctrl);
+                  register_new_node(x2, iff_ctrl);
+                  _igvn.replace_input_of(x2, 1, x1);
+                  _igvn.replace_input_of(iff, 1, x2);
+                }
+                _igvn.remove_dead_node(u);
+                --j;
+              } else {
+                // We might see an Opaque1 from a loop limit check here
+                assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1, "unexpected node type");
+                assert(u->in(1) == bol, "");
                 // Get control block of either the CMove or the If input
-                Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff);
-                Node *x1 = bol->clone();
-                Node *x2 = u->clone();
-                register_new_node(x1, iff_ctrl);
-                register_new_node(x2, iff_ctrl);
-                _igvn.replace_input_of(x2, 1, x1);
-                _igvn.replace_input_of(iff, 1, x2);
+                Node *u_ctrl = u->is_If() ? u->in(0) : get_ctrl(u);
+                assert((u_ctrl != blk1 && u_ctrl != blk2) || u->is_CMove(), "won't converge");
+                Node *x = bol->clone();
+                register_new_node(x, u_ctrl);
+                _igvn.replace_input_of(u, 1, x);
+                --j;
               }
-              _igvn.remove_dead_node(u);
-              --j;
-            } else {
-              // We might see an Opaque1 from a loop limit check here
-              assert(u->is_If() || u->is_CMove() || u->Opcode() == Op_Opaque1, "unexpected node type");
-              assert(u->in(1) == bol, "");
-              // Get control block of either the CMove or the If input
-              Node *u_ctrl = u->is_If() ? u->in(0) : get_ctrl(u);
-              assert((u_ctrl != blk1 && u_ctrl != blk2) || u->is_CMove(), "won't converge");
-              Node *x = bol->clone();
-              register_new_node(x, u_ctrl);
-              _igvn.replace_input_of(u, 1, x);
-              --j;
             }
+            _igvn.remove_dead_node(bol);
+            --i;
           }
-          _igvn.remove_dead_node(bol);
-          --i;
         }
       }
       // Clone down this CmpNode
       for (DUIterator_Last jmin, j = n->last_outs(jmin); j >= jmin; --j) {
-        Node* bol = n->last_out(j);
-        assert( bol->in(1) == n, "" );
+        Node* use = n->last_out(j);
+        uint pos = 1;
+        if (n->is_FastLock()) {
+          pos = TypeFunc::Parms + 2;
+          assert(use->is_Lock(), "FastLock only used by LockNode");
+        }
+        assert(use->in(pos) == n, "" );
         Node *x = n->clone();
-        register_new_node(x, get_ctrl(bol));
-        _igvn.replace_input_of(bol, 1, x);
+        register_new_node(x, ctrl_or_self(use));
+        _igvn.replace_input_of(use, pos, x);
       }
       _igvn.remove_dead_node( n );
 
--- a/src/hotspot/share/prims/jniCheck.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jniCheck.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -448,16 +448,16 @@
 Method* jniCheck::validate_jmethod_id(JavaThread* thr, jmethodID method_id) {
   ASSERT_OOPS_ALLOWED;
   // do the fast jmethodID check first
-  Method* moop = Method::checked_resolve_jmethod_id(method_id);
-  if (moop == NULL) {
+  Method* m = Method::checked_resolve_jmethod_id(method_id);
+  if (m == NULL) {
     ReportJNIFatalError(thr, fatal_wrong_class_or_method);
   }
-  // jmethodIDs are supposed to be weak handles in the class loader data,
+  // jmethodIDs are handles in the class loader data,
   // but that can be expensive so check it last
   else if (!Method::is_method_id(method_id)) {
     ReportJNIFatalError(thr, fatal_non_weak_method);
   }
-  return moop;
+  return m;
 }
 
 
@@ -518,18 +518,29 @@
   }
 }
 
-void jniCheck::validate_call_object(JavaThread* thr, jobject obj, jmethodID method_id) {
-  /* validate the object being passed */
+void jniCheck::validate_call(JavaThread* thr, jclass clazz, jmethodID method_id, jobject obj) {
   ASSERT_OOPS_ALLOWED;
-  jniCheck::validate_jmethod_id(thr, method_id);
-  jniCheck::validate_object(thr, obj);
-}
+  Method* m = jniCheck::validate_jmethod_id(thr, method_id);
+  InstanceKlass* holder = m->method_holder();
+
+  if (clazz != NULL) {
+    Klass* k = jniCheck::validate_class(thr, clazz, false);
+    // Check that method is in the class, must be InstanceKlass
+    if (!InstanceKlass::cast(k)->is_subtype_of(holder)) {
+      ReportJNIFatalError(thr, fatal_wrong_class_or_method);
+    }
+  }
 
-void jniCheck::validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id) {
-  /* validate the class being passed */
-  ASSERT_OOPS_ALLOWED;
-  jniCheck::validate_jmethod_id(thr, method_id);
-  jniCheck::validate_class(thr, clazz, false);
+  if (obj != NULL) {
+    oop recv = jniCheck::validate_object(thr, obj);
+    assert(recv != NULL, "validate_object checks that");
+    Klass* ik = recv->klass();
+
+    // Check that the object is a subtype of method holder too.
+    if (!InstanceKlass::cast(ik)->is_subtype_of(holder)) {
+      ReportJNIFatalError(thr, fatal_wrong_class_or_method);
+    }
+  }
 }
 
 
@@ -595,8 +606,7 @@
                                 jboolean isStatic))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_class(thr, cls, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID,
                                                     isStatic);
@@ -852,8 +862,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_class(thr, clazz, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, clazz, methodID);
     )
     va_start(args, methodID);
     jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
@@ -869,8 +878,7 @@
                          va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_class(thr, clazz, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, clazz, methodID);
     )
     jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
     functionExit(thr);
@@ -884,8 +892,7 @@
                          const jvalue *args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_class(thr, clazz, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, clazz, methodID);
     )
     jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args);
     functionExit(thr);
@@ -941,7 +948,7 @@
     functionEnter(thr); \
     va_list args; \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
+      jniCheck::validate_call(thr, NULL, methodID, obj); \
     ) \
     va_start(args,methodID); \
     ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \
@@ -959,7 +966,7 @@
                                     va_list args)) \
     functionEnter(thr); \
     IN_VM(\
-      jniCheck::validate_call_object(thr, obj, methodID); \
+      jniCheck::validate_call(thr, NULL, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\
                                                            args); \
@@ -975,7 +982,7 @@
                                     const jvalue * args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
+      jniCheck::validate_call(thr, NULL, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\
                                                            args); \
@@ -1002,7 +1009,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
+      jniCheck::validate_call(thr, NULL, methodID, obj);
     )
     va_start(args,methodID);
     UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
@@ -1018,7 +1025,7 @@
                               va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
+      jniCheck::validate_call(thr, NULL, methodID, obj);
     )
     UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
     thr->set_pending_jni_exception_check("CallVoidMethodV");
@@ -1032,7 +1039,7 @@
                               const jvalue * args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
+      jniCheck::validate_call(thr, NULL, methodID, obj);
     )
     UNCHECKED()->CallVoidMethodA(env,obj,methodID,args);
     thr->set_pending_jni_exception_check("CallVoidMethodA");
@@ -1049,8 +1056,7 @@
     functionEnter(thr); \
     va_list args; \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
-      jniCheck::validate_call_class(thr, clazz, methodID); \
+      jniCheck::validate_call(thr, clazz, methodID, obj); \
     ) \
     va_start(args,methodID); \
     ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \
@@ -1072,8 +1078,7 @@
                                               va_list args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
-      jniCheck::validate_call_class(thr, clazz, methodID); \
+      jniCheck::validate_call(thr, clazz, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \
                                                                      obj, \
@@ -1093,8 +1098,7 @@
                                               const jvalue * args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
-      jniCheck::validate_call_class(thr, clazz, methodID); \
+      jniCheck::validate_call(thr, clazz, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodA(env, \
                                                                      obj, \
@@ -1125,8 +1129,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
-      jniCheck::validate_call_class(thr, clazz, methodID);
+      jniCheck::validate_call(thr, clazz, methodID, obj);
     )
     va_start(args,methodID);
     UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
@@ -1143,8 +1146,7 @@
                                         va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
-      jniCheck::validate_call_class(thr, clazz, methodID);
+      jniCheck::validate_call(thr, clazz, methodID, obj);
     )
     UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
     thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV");
@@ -1159,8 +1161,7 @@
                                         const jvalue * args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
-      jniCheck::validate_call_class(thr, clazz, methodID);
+      jniCheck::validate_call(thr, clazz, methodID, obj);
     )
     UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args);
     thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA");
@@ -1253,8 +1254,7 @@
     functionEnter(thr); \
     va_list args; \
     IN_VM( \
-      jniCheck::validate_jmethod_id(thr, methodID); \
-      jniCheck::validate_class(thr, clazz, false); \
+      jniCheck::validate_call(thr, clazz, methodID); \
     ) \
     va_start(args,methodID); \
     ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \
@@ -1274,8 +1274,7 @@
                                           va_list args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_jmethod_id(thr, methodID); \
-      jniCheck::validate_class(thr, clazz, false); \
+      jniCheck::validate_call(thr, clazz, methodID); \
     ) \
     ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \
                                                                  clazz, \
@@ -1293,8 +1292,7 @@
                                           const jvalue *args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_jmethod_id(thr, methodID); \
-      jniCheck::validate_class(thr, clazz, false); \
+      jniCheck::validate_call(thr, clazz, methodID); \
     ) \
     ReturnType result = UNCHECKED()->CallStatic##Result##MethodA(env, \
                                                                  clazz, \
@@ -1323,8 +1321,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_jmethod_id(thr, methodID);
-      jniCheck::validate_class(thr, cls, false);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     va_start(args,methodID);
     UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
@@ -1340,8 +1337,7 @@
                                     va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_jmethod_id(thr, methodID);
-      jniCheck::validate_class(thr, cls, false);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
     thr->set_pending_jni_exception_check("CallStaticVoidMethodV");
@@ -1355,8 +1351,7 @@
                                     const jvalue * args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_jmethod_id(thr, methodID);
-      jniCheck::validate_class(thr, cls, false);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args);
     thr->set_pending_jni_exception_check("CallStaticVoidMethodA");
--- a/src/hotspot/share/prims/jniCheck.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jniCheck.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -51,8 +51,7 @@
   static Klass* validate_class(JavaThread* thr, jclass clazz, bool allow_primitive = false);
   static void validate_class_descriptor(JavaThread* thr, const char* name);
   static void validate_throwable_klass(JavaThread* thr, Klass* klass);
-  static void validate_call_object(JavaThread* thr, jobject obj, jmethodID method_id);
-  static void validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id);
+  static void validate_call(JavaThread* thr, jclass clazz, jmethodID method_id, jobject obj = NULL);
   static Method* validate_jmethod_id(JavaThread* thr, jmethodID method_id);
 };
 
--- a/src/hotspot/share/prims/jvm.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jvm.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -990,13 +990,21 @@
   ResourceMark rm(THREAD);
 
   Handle h_name (THREAD, JNIHandles::resolve_non_null(name));
-  Handle string = java_lang_String::internalize_classname(h_name, CHECK_NULL);
-
-  const char* str   = java_lang_String::as_utf8_string(string());
+  char* str = java_lang_String::as_utf8_string(h_name());
+
   // Sanity check, don't expect null
   if (str == NULL) return NULL;
 
-  const int str_len = (int)strlen(str);
+  // Internalize the string, converting '.' to '/' in string.
+  char* p = (char*)str;
+  while (*p != '\0') {
+      if (*p == '.') {
+          *p = '/';
+      }
+      p++;
+  }
+
+  const int str_len = (int)(p - str);
   if (str_len > Symbol::max_length()) {
     // It's impossible to create this class;  the name cannot fit
     // into the constant pool.
--- a/src/hotspot/share/prims/jvmtiEnv.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -3229,23 +3229,23 @@
 jvmtiError
 JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {
   if (Threads::number_of_threads() == 0) {
-    // Remove this  monitor from pending raw monitors list
+    // Remove this monitor from pending raw monitors list
     // if it has entered in onload or start phase.
     JvmtiPendingMonitors::destroy(rmonitor);
   } else {
     Thread* thread  = Thread::current();
-    if (rmonitor->is_entered(thread)) {
+    if (rmonitor->owner() == thread) {
       // The caller owns this monitor which we are about to destroy.
       // We exit the underlying synchronization object so that the
       // "delete monitor" call below can work without an assertion
       // failure on systems that don't like destroying synchronization
       // objects that are locked.
       int r;
-      intptr_t recursion = rmonitor->recursions();
-      for (intptr_t i = 0; i <= recursion; i++) {
+      int recursion = rmonitor->recursions();
+      for (int i = 0; i <= recursion; i++) {
         r = rmonitor->raw_exit(thread);
-        assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked");
-        if (r != ObjectMonitor::OM_OK) {  // robustness
+        assert(r == JvmtiRawMonitor::M_OK, "raw_exit should have worked");
+        if (r != JvmtiRawMonitor::M_OK) {  // robustness
           return JVMTI_ERROR_INTERNAL;
         }
       }
@@ -3271,7 +3271,7 @@
 jvmtiError
 JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {
   if (Threads::number_of_threads() == 0) {
-    // No JavaThreads exist so ObjectMonitor enter cannot be
+    // No JavaThreads exist so JvmtiRawMonitor enter cannot be
     // used, add this raw monitor to the pending list.
     // The pending monitors will be actually entered when
     // the VM is setup.
@@ -3279,20 +3279,10 @@
     // in thread.cpp.
     JvmtiPendingMonitors::enter(rmonitor);
   } else {
-    int r = 0;
     Thread* thread = Thread::current();
-
     if (thread->is_Java_thread()) {
       JavaThread* current_thread = (JavaThread*)thread;
 
-#ifdef PROPER_TRANSITIONS
-      // Not really unknown but ThreadInVMfromNative does more than we want
-      ThreadInVMfromUnknown __tiv;
-      {
-        ThreadBlockInVM __tbivm(current_thread);
-        r = rmonitor->raw_enter(current_thread);
-      }
-#else
       /* 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       */
@@ -3308,22 +3298,11 @@
              current_thread->frame_anchor()->walkable(), "Must be walkable");
       current_thread->set_thread_state(_thread_blocked);
 
-      r = rmonitor->raw_enter(current_thread);
+      rmonitor->raw_enter(current_thread);
       // restore state, still at a safepoint safe state
       current_thread->set_thread_state(state);
-
-#endif /* PROPER_TRANSITIONS */
-      assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
     } else {
-      if (thread->is_Named_thread()) {
-        r = rmonitor->raw_enter(thread);
-      } else {
-        ShouldNotReachHere();
-      }
-    }
-
-    if (r != ObjectMonitor::OM_OK) {  // robustness
-      return JVMTI_ERROR_INTERNAL;
+      rmonitor->raw_enter(thread);
     }
   }
   return JVMTI_ERROR_NONE;
@@ -3342,31 +3321,10 @@
       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
     }
   } else {
-    int r = 0;
     Thread* thread = Thread::current();
-
-    if (thread->is_Java_thread()) {
-      JavaThread* current_thread = (JavaThread*)thread;
-#ifdef PROPER_TRANSITIONS
-      // Not really unknown but ThreadInVMfromNative does more than we want
-      ThreadInVMfromUnknown __tiv;
-#endif /* PROPER_TRANSITIONS */
-      r = rmonitor->raw_exit(current_thread);
-    } else {
-      if (thread->is_Named_thread()) {
-        r = rmonitor->raw_exit(thread);
-      } else {
-        ShouldNotReachHere();
-      }
-    }
-
-    if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
+    int r = rmonitor->raw_exit(thread);
+    if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
-    } else {
-      assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked");
-      if (r != ObjectMonitor::OM_OK) {  // robustness
-        err = JVMTI_ERROR_INTERNAL;
-      }
     }
   }
   return err;
@@ -3381,14 +3339,7 @@
 
   if (thread->is_Java_thread()) {
     JavaThread* current_thread = (JavaThread*)thread;
-#ifdef PROPER_TRANSITIONS
-    // Not really unknown but ThreadInVMfromNative does more than we want
-    ThreadInVMfromUnknown __tiv;
-    {
-      ThreadBlockInVM __tbivm(current_thread);
-      r = rmonitor->raw_wait(millis, true, current_thread);
-    }
-#else
+
     /* 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       */
@@ -3408,57 +3359,31 @@
     // restore state, still at a safepoint safe state
     current_thread->set_thread_state(state);
 
-#endif /* PROPER_TRANSITIONS */
   } else {
-    if (thread->is_Named_thread()) {
       r = rmonitor->raw_wait(millis, false, thread);
-    } else {
-      ShouldNotReachHere();
-    }
+      assert(r != JvmtiRawMonitor::M_INTERRUPTED, "non-JavaThread can't be interrupted");
   }
 
   switch (r) {
-  case ObjectMonitor::OM_INTERRUPTED:
+  case JvmtiRawMonitor::M_INTERRUPTED:
     return JVMTI_ERROR_INTERRUPT;
-  case ObjectMonitor::OM_ILLEGAL_MONITOR_STATE:
+  case JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE:
     return JVMTI_ERROR_NOT_MONITOR_OWNER;
+  default:
+    return JVMTI_ERROR_NONE;
   }
-  assert(r == ObjectMonitor::OM_OK, "raw_wait should have worked");
-  if (r != ObjectMonitor::OM_OK) {  // robustness
-    return JVMTI_ERROR_INTERNAL;
-  }
-
-  return JVMTI_ERROR_NONE;
 } /* end RawMonitorWait */
 
 
 // rmonitor - pre-checked for validity
 jvmtiError
 JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {
-  int r = 0;
   Thread* thread = Thread::current();
-
-  if (thread->is_Java_thread()) {
-    JavaThread* current_thread = (JavaThread*)thread;
-    // Not really unknown but ThreadInVMfromNative does more than we want
-    ThreadInVMfromUnknown __tiv;
-    r = rmonitor->raw_notify(current_thread);
-  } else {
-    if (thread->is_Named_thread()) {
-      r = rmonitor->raw_notify(thread);
-    } else {
-      ShouldNotReachHere();
-    }
-  }
-
-  if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
+  int r = rmonitor->raw_notify(thread);
+
+  if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
     return JVMTI_ERROR_NOT_MONITOR_OWNER;
   }
-  assert(r == ObjectMonitor::OM_OK, "raw_notify should have worked");
-  if (r != ObjectMonitor::OM_OK) {  // robustness
-    return JVMTI_ERROR_INTERNAL;
-  }
-
   return JVMTI_ERROR_NONE;
 } /* end RawMonitorNotify */
 
@@ -3466,29 +3391,12 @@
 // rmonitor - pre-checked for validity
 jvmtiError
 JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) {
-  int r = 0;
   Thread* thread = Thread::current();
-
-  if (thread->is_Java_thread()) {
-    JavaThread* current_thread = (JavaThread*)thread;
-    ThreadInVMfromUnknown __tiv;
-    r = rmonitor->raw_notifyAll(current_thread);
-  } else {
-    if (thread->is_Named_thread()) {
-      r = rmonitor->raw_notifyAll(thread);
-    } else {
-      ShouldNotReachHere();
-    }
-  }
-
-  if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
+  int r = rmonitor->raw_notifyAll(thread);
+
+  if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
     return JVMTI_ERROR_NOT_MONITOR_OWNER;
   }
-  assert(r == ObjectMonitor::OM_OK, "raw_notifyAll should have worked");
-  if (r != ObjectMonitor::OM_OK) {  // robustness
-    return JVMTI_ERROR_INTERNAL;
-  }
-
   return JVMTI_ERROR_NONE;
 } /* end RawMonitorNotifyAll */
 
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -659,10 +659,9 @@
     // thread is not doing an Object.wait() call
     mon = java_thread->current_pending_monitor();
     if (mon != NULL) {
-      // The thread is trying to enter() or raw_enter() an ObjectMonitor.
+      // The thread is trying to enter() an ObjectMonitor.
       obj = (oop)mon->object();
-      // If obj == NULL, then ObjectMonitor is raw which doesn't count
-      // as contended for this API
+      assert(obj != NULL, "ObjectMonitor should have a valid object!");
     }
     // implied else: no contended ObjectMonitor
   } else {
--- a/src/hotspot/share/prims/jvmtiExport.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiExport.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1202,6 +1202,7 @@
 bool              JvmtiExport::_can_post_method_exit                      = false;
 bool              JvmtiExport::_can_pop_frame                             = false;
 bool              JvmtiExport::_can_force_early_return                    = false;
+bool              JvmtiExport::_can_get_owned_monitor_info                = false;
 
 bool              JvmtiExport::_early_vmstart_recorded                    = false;
 
--- a/src/hotspot/share/prims/jvmtiExport.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiExport.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -91,6 +91,7 @@
   JVMTI_SUPPORT_FLAG(can_force_early_return)
 
   JVMTI_SUPPORT_FLAG(early_vmstart_recorded)
+  JVMTI_SUPPORT_FLAG(can_get_owned_monitor_info) // includes can_get_owned_monitor_stack_depth_info
 
   friend class JvmtiEventControllerPrivate;  // should only modify these flags
   JVMTI_SUPPORT_FLAG(should_post_single_step)
--- a/src/hotspot/share/prims/jvmtiManageCapabilities.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiManageCapabilities.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -367,6 +367,8 @@
   JvmtiExport::set_can_pop_frame(avail.can_pop_frame);
   JvmtiExport::set_can_force_early_return(avail.can_force_early_return);
   JvmtiExport::set_should_clean_up_heap_objects(avail.can_generate_breakpoint_events);
+  JvmtiExport::set_can_get_owned_monitor_info(avail.can_get_owned_monitor_info ||
+                                              avail.can_get_owned_monitor_stack_depth_info);
 }
 
 #ifndef PRODUCT
--- a/src/hotspot/share/prims/jvmtiRawMonitor.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -30,21 +30,23 @@
 #include "runtime/orderAccess.hpp"
 #include "runtime/thread.inline.hpp"
 
-GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1,true);
+JvmtiRawMonitor::QNode::QNode(Thread* thread) : _next(NULL), _prev(NULL),
+                                                _event(thread->_ParkEvent),
+                                                _notified(0), _t_state(TS_RUN) {
+}
+
+GrowableArray<JvmtiRawMonitor*>* JvmtiPendingMonitors::_monitors =
+  new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1, true);
 
 void JvmtiPendingMonitors::transition_raw_monitors() {
   assert((Threads::number_of_threads()==1),
-         "Java thread has not created yet or more than one java thread \
-is running. Raw monitor transition will not work");
-  JavaThread *current_java_thread = JavaThread::current();
+         "Java thread has not been created yet or more than one java thread "
+         "is running. Raw monitor transition will not work");
+  JavaThread* current_java_thread = JavaThread::current();
   assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
-  {
-    ThreadBlockInVM __tbivm(current_java_thread);
-    for(int i=0; i< count(); i++) {
-      JvmtiRawMonitor *rmonitor = monitors()->at(i);
-      int r = rmonitor->raw_enter(current_java_thread);
-      assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
-    }
+  for (int i = 0; i < count(); i++) {
+    JvmtiRawMonitor* rmonitor = monitors()->at(i);
+    rmonitor->raw_enter(current_java_thread);
   }
   // pending monitors are converted to real monitor so delete them all.
   dispose();
@@ -54,13 +56,16 @@
 // class JvmtiRawMonitor
 //
 
-JvmtiRawMonitor::JvmtiRawMonitor(const char *name) {
+JvmtiRawMonitor::JvmtiRawMonitor(const char* name) : _owner(NULL),
+                                                     _recursions(0),
+                                                     _entry_list(NULL),
+                                                     _wait_set(NULL),
+                                                     _waiters(0),
+                                                     _magic(JVMTI_RM_MAGIC),
+                                                     _name(NULL) {
 #ifdef ASSERT
   _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
-#else
-  _name = NULL;
 #endif
-  _magic = JVMTI_RM_MAGIC;
 }
 
 JvmtiRawMonitor::~JvmtiRawMonitor() {
@@ -100,181 +105,179 @@
 }
 
 // -------------------------------------------------------------------------
-// The raw monitor subsystem is entirely distinct from normal
-// java-synchronization or jni-synchronization.  raw monitors are not
+// The JVMTI raw monitor subsystem is entirely distinct from normal
+// java-synchronization or jni-synchronization.  JVMTI raw monitors are not
 // associated with objects.  They can be implemented in any manner
 // that makes sense.  The original implementors decided to piggy-back
-// the raw-monitor implementation on the existing Java objectMonitor mechanism.
-// This flaw needs to fixed.  We should reimplement raw monitors as sui-generis.
-// Specifically, we should not implement raw monitors via java monitors.
-// Time permitting, we should disentangle and deconvolve the two implementations
-// and move the resulting raw monitor implementation over to the JVMTI directories.
-// Ideally, the raw monitor implementation would be built on top of
-// park-unpark and nothing else.
-//
-// raw monitors are used mainly by JVMTI
-// The raw monitor implementation borrows the ObjectMonitor structure,
-// but the operators are degenerate and extremely simple.
-//
-// Mixed use of a single objectMonitor instance -- as both a raw monitor
-// and a normal java monitor -- is not permissible.
+// the raw-monitor implementation on the existing Java ObjectMonitor mechanism.
+// Now we just use a simplified form of that ObjectMonitor code.
 //
 // Note that we use the single RawMonitor_lock to protect queue operations for
 // _all_ raw monitors.  This is a scalability impediment, but since raw monitor usage
-// is deprecated and rare, this is not of concern.  The RawMonitor_lock can not
+// is fairly rare, this is not of concern.  The RawMonitor_lock can not
 // be held indefinitely.  The critical sections must be short and bounded.
 //
 // -------------------------------------------------------------------------
 
-int JvmtiRawMonitor::SimpleEnter (Thread * Self) {
+void JvmtiRawMonitor::simple_enter(Thread* self) {
   for (;;) {
-    if (Atomic::replace_if_null(Self, &_owner)) {
-       return OS_OK ;
+    if (Atomic::replace_if_null(self, &_owner)) {
+      return;
     }
 
-    ObjectWaiter Node (Self) ;
-    Self->_ParkEvent->reset() ;     // strictly optional
-    Node.TState = ObjectWaiter::TS_ENTER ;
+    QNode node(self);
+    self->_ParkEvent->reset();     // strictly optional
+    node._t_state = QNode::TS_ENTER;
 
-    RawMonitor_lock->lock_without_safepoint_check() ;
-    Node._next  = _EntryList ;
-    _EntryList  = &Node ;
-    OrderAccess::fence() ;
-    if (_owner == NULL && Atomic::replace_if_null(Self, &_owner)) {
-        _EntryList = Node._next ;
-        RawMonitor_lock->unlock() ;
-        return OS_OK ;
+    RawMonitor_lock->lock_without_safepoint_check();
+    node._next = _entry_list;
+    _entry_list = &node;
+    OrderAccess::fence();
+    if (_owner == NULL && Atomic::replace_if_null(self, &_owner)) {
+      _entry_list = node._next;
+      RawMonitor_lock->unlock();
+      return;
     }
-    RawMonitor_lock->unlock() ;
-    while (Node.TState == ObjectWaiter::TS_ENTER) {
-       Self->_ParkEvent->park() ;
+    RawMonitor_lock->unlock();
+    while (node._t_state == QNode::TS_ENTER) {
+      self->_ParkEvent->park();
     }
   }
 }
 
-int JvmtiRawMonitor::SimpleExit (Thread * Self) {
-  guarantee (_owner == Self, "invariant") ;
-  OrderAccess::release_store(&_owner, (void*)NULL) ;
-  OrderAccess::fence() ;
-  if (_EntryList == NULL) return OS_OK ;
-  ObjectWaiter * w ;
+void JvmtiRawMonitor::simple_exit(Thread* self) {
+  guarantee(_owner == self, "invariant");
+  OrderAccess::release_store(&_owner, (Thread*)NULL);
+  OrderAccess::fence();
+  if (_entry_list == NULL) {
+    return;
+  }
 
-  RawMonitor_lock->lock_without_safepoint_check() ;
-  w = _EntryList ;
+  RawMonitor_lock->lock_without_safepoint_check();
+  QNode* w = _entry_list;
   if (w != NULL) {
-      _EntryList = w->_next ;
+    _entry_list = w->_next;
   }
-  RawMonitor_lock->unlock() ;
+  RawMonitor_lock->unlock();
   if (w != NULL) {
-      guarantee (w ->TState == ObjectWaiter::TS_ENTER, "invariant") ;
-      // Once we set TState to TS_RUN the waiting thread can complete
-      // SimpleEnter and 'w' is pointing into random stack space. So we have
-      // to ensure we extract the ParkEvent (which is in type-stable memory)
-      // before we set the state, and then don't access 'w'.
-      ParkEvent * ev = w->_event ;
-      OrderAccess::loadstore();
-      w->TState = ObjectWaiter::TS_RUN ;
-      OrderAccess::fence() ;
-      ev->unpark() ;
+    guarantee(w ->_t_state == QNode::TS_ENTER, "invariant");
+    // Once we set _t_state to TS_RUN the waiting thread can complete
+    // simple_enter and 'w' is pointing into random stack space. So we have
+    // to ensure we extract the ParkEvent (which is in type-stable memory)
+    // before we set the state, and then don't access 'w'.
+    ParkEvent* ev = w->_event;
+    OrderAccess::loadstore();
+    w->_t_state = QNode::TS_RUN;
+    OrderAccess::fence();
+    ev->unpark();
   }
-  return OS_OK ;
+  return;
 }
 
-int JvmtiRawMonitor::SimpleWait (Thread * Self, jlong millis) {
-  guarantee (_owner == Self  , "invariant") ;
-  guarantee (_recursions == 0, "invariant") ;
+int JvmtiRawMonitor::simple_wait(Thread* self, jlong millis) {
+  guarantee(_owner == self  , "invariant");
+  guarantee(_recursions == 0, "invariant");
 
-  ObjectWaiter Node (Self) ;
-  Node._notified = 0 ;
-  Node.TState    = ObjectWaiter::TS_WAIT ;
+  QNode node(self);
+  node._notified = 0;
+  node._t_state = QNode::TS_WAIT;
 
-  RawMonitor_lock->lock_without_safepoint_check() ;
-  Node._next     = _WaitSet ;
-  _WaitSet       = &Node ;
-  RawMonitor_lock->unlock() ;
+  RawMonitor_lock->lock_without_safepoint_check();
+  node._next = _wait_set;
+  _wait_set = &node;
+  RawMonitor_lock->unlock();
 
-  SimpleExit (Self) ;
-  guarantee (_owner != Self, "invariant") ;
+  simple_exit(self);
+  guarantee(_owner != self, "invariant");
 
-  int ret = OS_OK ;
+  int ret = OS_OK;
   if (millis <= 0) {
-    Self->_ParkEvent->park();
+    self->_ParkEvent->park();
   } else {
-    ret = Self->_ParkEvent->park(millis);
+    ret = self->_ParkEvent->park(millis);
   }
 
   // If thread still resides on the waitset then unlink it.
   // Double-checked locking -- the usage is safe in this context
-  // as TState is volatile and the lock-unlock operators are
+  // as _t_state is volatile and the lock-unlock operators are
   // serializing (barrier-equivalent).
 
-  if (Node.TState == ObjectWaiter::TS_WAIT) {
-    RawMonitor_lock->lock_without_safepoint_check() ;
-    if (Node.TState == ObjectWaiter::TS_WAIT) {
+  if (node._t_state == QNode::TS_WAIT) {
+    RawMonitor_lock->lock_without_safepoint_check();
+    if (node._t_state == QNode::TS_WAIT) {
       // Simple O(n) unlink, but performance isn't critical here.
-      ObjectWaiter * p ;
-      ObjectWaiter * q = NULL ;
-      for (p = _WaitSet ; p != &Node; p = p->_next) {
-         q = p ;
+      QNode* p;
+      QNode* q = NULL;
+      for (p = _wait_set; p != &node; p = p->_next) {
+        q = p;
       }
-      guarantee (p == &Node, "invariant") ;
+      guarantee(p == &node, "invariant");
       if (q == NULL) {
-        guarantee (p == _WaitSet, "invariant") ;
-        _WaitSet = p->_next ;
+        guarantee (p == _wait_set, "invariant");
+        _wait_set = p->_next;
       } else {
-        guarantee (p == q->_next, "invariant") ;
-        q->_next = p->_next ;
+        guarantee(p == q->_next, "invariant");
+        q->_next = p->_next;
       }
-      Node.TState = ObjectWaiter::TS_RUN ;
+      node._t_state = QNode::TS_RUN;
     }
-    RawMonitor_lock->unlock() ;
+    RawMonitor_lock->unlock();
   }
 
-  guarantee (Node.TState == ObjectWaiter::TS_RUN, "invariant") ;
-  SimpleEnter (Self) ;
+  guarantee(node._t_state == QNode::TS_RUN, "invariant");
+  simple_enter(self);
 
-  guarantee (_owner == Self, "invariant") ;
-  guarantee (_recursions == 0, "invariant") ;
-  return ret ;
+  guarantee(_owner == self, "invariant");
+  guarantee(_recursions == 0, "invariant");
+  return ret;
 }
 
-int JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) {
-  guarantee (_owner == Self, "invariant") ;
-  if (_WaitSet == NULL) return OS_OK ;
+void JvmtiRawMonitor::simple_notify(Thread* self, bool all) {
+  guarantee(_owner == self, "invariant");
+  if (_wait_set == NULL) {
+    return;
+  }
 
   // We have two options:
-  // A. Transfer the threads from the WaitSet to the EntryList
-  // B. Remove the thread from the WaitSet and unpark() it.
+  // A. Transfer the threads from the _wait_set to the _entry_list
+  // B. Remove the thread from the _wait_set and unpark() it.
   //
   // We use (B), which is crude and results in lots of futile
   // context switching.  In particular (B) induces lots of contention.
 
-  ParkEvent * ev = NULL ;       // consider using a small auto array ...
-  RawMonitor_lock->lock_without_safepoint_check() ;
+  ParkEvent* ev = NULL;       // consider using a small auto array ...
+  RawMonitor_lock->lock_without_safepoint_check();
   for (;;) {
-      ObjectWaiter * w = _WaitSet ;
-      if (w == NULL) break ;
-      _WaitSet = w->_next ;
-      if (ev != NULL) { ev->unpark(); ev = NULL; }
-      ev = w->_event ;
-      OrderAccess::loadstore() ;
-      w->TState = ObjectWaiter::TS_RUN ;
-      OrderAccess::storeload();
-      if (!All) break ;
+    QNode* w = _wait_set;
+    if (w == NULL) break;
+    _wait_set = w->_next;
+    if (ev != NULL) {
+      ev->unpark();
+      ev = NULL;
+    }
+    ev = w->_event;
+    OrderAccess::loadstore();
+    w->_t_state = QNode::TS_RUN;
+    OrderAccess::storeload();
+    if (!all) {
+      break;
+    }
   }
-  RawMonitor_lock->unlock() ;
-  if (ev != NULL) ev->unpark();
-  return OS_OK ;
+  RawMonitor_lock->unlock();
+  if (ev != NULL) {
+    ev->unpark();
+  }
+  return;
 }
 
 // Any JavaThread will enter here with state _thread_blocked
-int JvmtiRawMonitor::raw_enter(TRAPS) {
-  void * Contended ;
-
+void JvmtiRawMonitor::raw_enter(Thread* self) {
+  void* contended;
+  JavaThread* jt = NULL;
   // don't enter raw monitor if thread is being externally suspended, it will
   // surprise the suspender if a "suspended" thread can still enter monitor
-  JavaThread * jt = (JavaThread *)THREAD;
-  if (THREAD->is_Java_thread()) {
+  if (self->is_Java_thread()) {
+    jt = (JavaThread*)self;
     jt->SR_lock()->lock_without_safepoint_check();
     while (jt->is_external_suspend()) {
       jt->SR_lock()->unlock();
@@ -282,150 +285,140 @@
       jt->SR_lock()->lock_without_safepoint_check();
     }
     // guarded by SR_lock to avoid racing with new external suspend requests.
-    Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL);
+    contended = Atomic::cmpxchg(jt, &_owner, (Thread*)NULL);
     jt->SR_lock()->unlock();
   } else {
-    Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL);
+    contended = Atomic::cmpxchg(self, &_owner, (Thread*)NULL);
   }
 
-  if (Contended == THREAD) {
-     _recursions ++ ;
-     return OM_OK ;
+  if (contended == self) {
+    _recursions++;
+    return;
   }
 
-  if (Contended == NULL) {
-     guarantee (_owner == THREAD, "invariant") ;
-     guarantee (_recursions == 0, "invariant") ;
-     return OM_OK ;
+  if (contended == NULL) {
+    guarantee(_owner == self, "invariant");
+    guarantee(_recursions == 0, "invariant");
+    return;
   }
 
-  THREAD->set_current_pending_monitor(this);
-
-  if (!THREAD->is_Java_thread()) {
-     // No other non-Java threads besides VM thread would acquire
-     // a raw monitor.
-     assert(THREAD->is_VM_thread(), "must be VM thread");
-     SimpleEnter (THREAD) ;
-   } else {
-     guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
-     for (;;) {
-       jt->set_suspend_equivalent();
-       // cleared by handle_special_suspend_equivalent_condition() or
-       // java_suspend_self()
-       SimpleEnter (THREAD) ;
-
-       // were we externally suspended while we were waiting?
-       if (!jt->handle_special_suspend_equivalent_condition()) break ;
+  self->set_current_pending_raw_monitor(this);
 
-       // This thread was externally suspended
-       //
-       // This logic isn't needed for JVMTI raw monitors,
-       // but doesn't hurt just in case the suspend rules change. This
-           // logic is needed for the JvmtiRawMonitor.wait() reentry phase.
-           // We have reentered the contended monitor, but while we were
-           // waiting another thread suspended us. We don't want to reenter
-           // the monitor while suspended because that would surprise the
-           // thread that suspended us.
-           //
-           // Drop the lock -
-       SimpleExit (THREAD) ;
-
-           jt->java_suspend_self();
-         }
-
-     assert(_owner == THREAD, "Fatal error with monitor owner!");
-     assert(_recursions == 0, "Fatal error with monitor recursions!");
-  }
+  if (!self->is_Java_thread()) {
+    simple_enter(self);
+  } else {
+    guarantee(jt->thread_state() == _thread_blocked, "invariant");
+    for (;;) {
+      jt->set_suspend_equivalent();
+      // cleared by handle_special_suspend_equivalent_condition() or
+      // java_suspend_self()
+      simple_enter(jt);
 
-  THREAD->set_current_pending_monitor(NULL);
-  guarantee (_recursions == 0, "invariant") ;
-  return OM_OK;
-}
-
-// Used mainly for JVMTI raw monitor implementation
-// Also used for JvmtiRawMonitor::wait().
-int JvmtiRawMonitor::raw_exit(TRAPS) {
-  if (THREAD != _owner) {
-    return OM_ILLEGAL_MONITOR_STATE;
-  }
-  if (_recursions > 0) {
-    --_recursions ;
-    return OM_OK ;
-  }
-
-  void * List = _EntryList ;
-  SimpleExit (THREAD) ;
+      // were we externally suspended while we were waiting?
+      if (!jt->handle_special_suspend_equivalent_condition()) {
+        break;
+      }
 
-  return OM_OK;
-}
-
-// Used for JVMTI raw monitor implementation.
-// All JavaThreads will enter here with state _thread_blocked
-
-int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, TRAPS) {
-  if (THREAD != _owner) {
-    return OM_ILLEGAL_MONITOR_STATE;
-  }
+      // This thread was externally suspended
+      // We have reentered the contended monitor, but while we were
+      // waiting another thread suspended us. We don't want to reenter
+      // the monitor while suspended because that would surprise the
+      // thread that suspended us.
+      //
+      // Drop the lock
+      simple_exit(jt);
 
-  // To avoid spurious wakeups we reset the parkevent -- This is strictly optional.
-  // The caller must be able to tolerate spurious returns from raw_wait().
-  THREAD->_ParkEvent->reset() ;
-  OrderAccess::fence() ;
-
-  // check interrupt event
-  if (interruptible) {
-    assert(THREAD->is_Java_thread(), "Only JavaThreads can be interruptible");
-    JavaThread* jt = (JavaThread*) THREAD;
-    if (jt->is_interrupted(true)) {
-      return OM_INTERRUPTED;
+      jt->java_suspend_self();
     }
   }
 
-  intptr_t save = _recursions ;
-  _recursions = 0 ;
-  _waiters ++ ;
-  if (THREAD->is_Java_thread()) {
-    guarantee (((JavaThread *) THREAD)->thread_state() == _thread_blocked, "invariant") ;
-    ((JavaThread *)THREAD)->set_suspend_equivalent();
-  }
-  int rv = SimpleWait (THREAD, millis) ;
-  _recursions = save ;
-  _waiters -- ;
+  self->set_current_pending_raw_monitor(NULL);
+
+  guarantee(_owner == self, "invariant");
+  guarantee(_recursions == 0, "invariant");
+}
 
-  guarantee (THREAD == _owner, "invariant") ;
-  if (THREAD->is_Java_thread()) {
-     JavaThread * jSelf = (JavaThread *) THREAD ;
-     for (;;) {
-        if (!jSelf->handle_special_suspend_equivalent_condition()) break ;
-        SimpleExit (THREAD) ;
-        jSelf->java_suspend_self();
-        SimpleEnter (THREAD) ;
-        jSelf->set_suspend_equivalent() ;
-     }
+int JvmtiRawMonitor::raw_exit(Thread* self) {
+  if (self != _owner) {
+    return M_ILLEGAL_MONITOR_STATE;
   }
-  guarantee (THREAD == _owner, "invariant") ;
+  if (_recursions > 0) {
+    _recursions--;
+  } else {
+    simple_exit(self);
+  }
 
-  if (interruptible) {
-    JavaThread* jt = (JavaThread*) THREAD;
-    if (jt->is_interrupted(true)) {
-      return OM_INTERRUPTED;
-    }
-  }
-  return OM_OK ;
+  return M_OK;
 }
 
-int JvmtiRawMonitor::raw_notify(TRAPS) {
-  if (THREAD != _owner) {
-    return OM_ILLEGAL_MONITOR_STATE;
+// All JavaThreads will enter here with state _thread_blocked
+
+int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, Thread* self) {
+  if (self != _owner) {
+    return M_ILLEGAL_MONITOR_STATE;
+  }
+
+  // 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");
   }
-  SimpleNotify (THREAD, false) ;
-  return OM_OK;
+
+  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);
+  _recursions = save;
+  _waiters--;
+
+  guarantee(self == _owner, "invariant");
+  if (self->is_Java_thread()) {
+    for (;;) {
+      if (!jt->handle_special_suspend_equivalent_condition()) {
+        break;
+      }
+      simple_exit(jt);
+      jt->java_suspend_self();
+      simple_enter(jt);
+      jt->set_suspend_equivalent();
+    }
+    guarantee(jt == _owner, "invariant");
+  }
+
+  if (interruptible && jt->is_interrupted(true)) {
+    return M_INTERRUPTED;
+  }
+
+  return M_OK;
 }
 
-int JvmtiRawMonitor::raw_notifyAll(TRAPS) {
-  if (THREAD != _owner) {
-    return OM_ILLEGAL_MONITOR_STATE;
+int JvmtiRawMonitor::raw_notify(Thread* self) {
+  if (self != _owner) {
+    return M_ILLEGAL_MONITOR_STATE;
   }
-  SimpleNotify (THREAD, true) ;
-  return OM_OK;
+  simple_notify(self, false);
+  return M_OK;
 }
+
+int JvmtiRawMonitor::raw_notifyAll(Thread* self) {
+  if (self != _owner) {
+    return M_ILLEGAL_MONITOR_STATE;
+  }
+  simple_notify(self, true);
+  return M_OK;
+}
--- a/src/hotspot/share/prims/jvmtiRawMonitor.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -25,7 +25,8 @@
 #ifndef SHARE_PRIMS_JVMTIRAWMONITOR_HPP
 #define SHARE_PRIMS_JVMTIRAWMONITOR_HPP
 
-#include "runtime/objectMonitor.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/park.hpp"
 #include "utilities/growableArray.hpp"
 
 //
@@ -33,32 +34,70 @@
 //
 // Used by JVMTI methods: All RawMonitor methods (CreateRawMonitor, EnterRawMonitor, etc.)
 //
-// Wrapper for ObjectMonitor class that saves the Monitor's name
+// A simplified version of the ObjectMonitor code.
 //
 
-class JvmtiRawMonitor : public ObjectMonitor  {
-private:
-  int           _magic;
-  char *        _name;
+class JvmtiRawMonitor : public CHeapObj<mtSynchronizer>  {
+
+  // Helper class to allow Threads to be linked into queues.
+  // This is a stripped down version of ObjectWaiter.
+  class QNode : public StackObj {
+    friend class JvmtiRawMonitor;
+    enum TStates { TS_READY, TS_RUN, TS_WAIT, TS_ENTER };
+    QNode* volatile _next;
+    QNode* volatile _prev;
+    ParkEvent* _event;
+    volatile int _notified;
+    volatile TStates _t_state;
+
+    QNode(Thread* thread);
+  };
+
+  Thread* volatile _owner;      // pointer to owning thread
+  volatile int _recursions;     // recursion count, 0 for first entry
+  QNode* volatile _entry_list;  // Threads blocked on entry or reentry.
+                                // The list is actually composed of nodes,
+                                // acting as proxies for Threads.
+  QNode* volatile _wait_set;    // Threads wait()ing on the monitor
+  volatile jint _waiters;       // number of waiting threads
+  int _magic;
+  char* _name;
   // JVMTI_RM_MAGIC is set in contructor and unset in destructor.
   enum { JVMTI_RM_MAGIC = (int)(('T' << 24) | ('I' << 16) | ('R' << 8) | 'M') };
 
-  int       SimpleEnter (Thread * Self) ;
-  int       SimpleExit  (Thread * Self) ;
-  int       SimpleWait  (Thread * Self, jlong millis) ;
-  int       SimpleNotify (Thread * Self, bool All) ;
+  void simple_enter(Thread* self);
+  void simple_exit(Thread* self);
+  int simple_wait(Thread* self, jlong millis);
+  void simple_notify(Thread* self, bool all);
+
+ public:
 
-public:
-  JvmtiRawMonitor(const char *name);
+  // return codes
+  enum {
+    M_OK,                    // no error
+    M_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
+    M_INTERRUPTED            // Thread.interrupt()
+  };
+
+  // Non-aborting operator new
+  void* operator new(size_t size) throw() {
+    return CHeapObj::operator new(size, std::nothrow);
+  }
+
+  JvmtiRawMonitor(const char* name);
   ~JvmtiRawMonitor();
-  int       raw_enter(TRAPS);
-  int       raw_exit(TRAPS);
-  int       raw_wait(jlong millis, bool interruptable, TRAPS);
-  int       raw_notify(TRAPS);
-  int       raw_notifyAll(TRAPS);
-  int            magic()   { return _magic;  }
-  const char *get_name()   { return _name; }
-  bool        is_valid();
+
+  Thread* owner() const { return _owner; }
+  void set_owner(Thread* owner) { _owner = owner; }
+  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_notify(Thread* self);
+  int raw_notifyAll(Thread* self);
+  int magic() const { return _magic; }
+  const char* get_name() const { return _name; }
+  bool is_valid();
 };
 
 // Onload pending raw monitors
@@ -67,8 +106,8 @@
 // VM is fully initialized.
 class JvmtiPendingMonitors : public AllStatic {
 
-private:
-  static GrowableArray<JvmtiRawMonitor*> *_monitors; // Cache raw monitor enter
+ private:
+  static GrowableArray<JvmtiRawMonitor*>* _monitors; // Cache raw monitor enter
 
   inline static GrowableArray<JvmtiRawMonitor*>* monitors() { return _monitors; }
 
@@ -76,8 +115,8 @@
     delete monitors();
   }
 
-public:
-  static void enter(JvmtiRawMonitor *monitor) {
+ public:
+  static void enter(JvmtiRawMonitor* monitor) {
     monitors()->append(monitor);
   }
 
@@ -85,14 +124,14 @@
     return monitors()->length();
   }
 
-  static void destroy(JvmtiRawMonitor *monitor) {
+  static void destroy(JvmtiRawMonitor* monitor) {
     while (monitors()->contains(monitor)) {
       monitors()->remove(monitor);
     }
   }
 
   // Return false if monitor is not found in the list.
-  static bool exit(JvmtiRawMonitor *monitor) {
+  static bool exit(JvmtiRawMonitor* monitor) {
     if (monitors()->contains(monitor)) {
       monitors()->remove(monitor);
       return true;
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -3528,15 +3528,6 @@
              "should be replaced");
     }
   }
-  // Update deleted jmethodID
-  for (int j = 0; j < _deleted_methods_length; ++j) {
-    Method* old_method = _deleted_methods[j];
-    jmethodID jmid = old_method->find_jmethod_id_or_null();
-    if (jmid != NULL) {
-      // Change the jmethodID to point to NSME.
-      Method::change_method_associated_with_jmethod_id(jmid, Universe::throw_no_such_method_error());
-    }
-  }
 }
 
 int VM_RedefineClasses::check_methods_and_mark_as_obsolete() {
--- a/src/hotspot/share/prims/jvmtiThreadState.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiThreadState.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
--- a/src/hotspot/share/runtime/arguments.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/arguments.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1454,7 +1454,7 @@
                                       "--patch-module"
                                     };
 void Arguments::check_unsupported_dumping_properties() {
-  assert(DumpSharedSpaces || DynamicDumpSharedSpaces,
+  assert(is_dumping_archive(),
          "this function is only used with CDS dump time");
   assert(ARRAY_SIZE(unsupported_properties) == ARRAY_SIZE(unsupported_options), "must be");
   // If a vm option is found in the unsupported_options array, vm will exit with an error message.
@@ -3537,7 +3537,7 @@
     SharedArchivePath = get_default_shared_archive_path();
   } else {
     int archives = num_archives(SharedArchiveFile);
-    if (DynamicDumpSharedSpaces || DumpSharedSpaces) {
+    if (is_dumping_archive()) {
       if (archives > 1) {
         vm_exit_during_initialization(
           "Cannot have more than 1 archive file specified in -XX:SharedArchiveFile during CDS dumping");
@@ -3550,7 +3550,7 @@
         }
       }
     }
-    if (!DynamicDumpSharedSpaces && !DumpSharedSpaces){
+    if (!is_dumping_archive()){
       if (archives > 2) {
         vm_exit_during_initialization(
           "Cannot have more than 2 archive files specified in the -XX:SharedArchiveFile option");
--- a/src/hotspot/share/runtime/arguments.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/arguments.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -647,6 +647,12 @@
   static bool atojulong(const char *s, julong* result);
 
   static bool has_jfr_option() NOT_JFR_RETURN_(false);
+
+  static bool is_dumping_archive() { return DumpSharedSpaces || DynamicDumpSharedSpaces; }
+
+  static void assert_is_dumping_archive() {
+    assert(Arguments::is_dumping_archive(), "dump time only");
+  }
 };
 
 // Disable options not supported in this release, with a warning if they
--- a/src/hotspot/share/runtime/globals.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/globals.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -385,7 +385,7 @@
   notproduct(ccstrlist, DeoptimizeOnlyAt, "",                               \
           "A comma separated list of bcis to deoptimize at")                \
                                                                             \
-  product(bool, DeoptimizeRandom, false,                                    \
+  develop(bool, DeoptimizeRandom, false,                                    \
           "Deoptimize random frames on random exit from the runtime system")\
                                                                             \
   notproduct(bool, ZombieALot, false,                                       \
@@ -1047,6 +1047,9 @@
   diagnostic(bool, EnableThreadSMRStatistics, trueInDebug,                  \
              "Enable Thread SMR Statistics")                                \
                                                                             \
+  product(bool, UseNotificationThread, true,                                \
+          "Use Notification Thread")                                        \
+                                                                            \
   product(bool, Inline, true,                                               \
           "Enable inlining")                                                \
                                                                             \
--- a/src/hotspot/share/runtime/interfaceSupport.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/interfaceSupport.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -55,12 +55,6 @@
   if (WalkStackALot) {
     InterfaceSupport::walk_stack();
   }
-#ifdef COMPILER2
-  // This option is not used by Compiler 1
-  if (StressDerivedPointers) {
-    InterfaceSupport::stress_derived_pointers();
-  }
-#endif
   if (DeoptimizeALot || DeoptimizeRandom) {
     InterfaceSupport::deoptimizeAll();
   }
@@ -234,31 +228,6 @@
 }
 
 
-void InterfaceSupport::stress_derived_pointers() {
-#ifdef COMPILER2
-  JavaThread *thread = JavaThread::current();
-  if (!is_init_completed()) return;
-  ResourceMark rm(thread);
-  bool found = false;
-  for (StackFrameStream sfs(thread); !sfs.is_done() && !found; sfs.next()) {
-    CodeBlob* cb = sfs.current()->cb();
-    if (cb != NULL && cb->oop_maps() ) {
-      // Find oopmap for current method
-      const ImmutableOopMap* map = cb->oop_map_for_return_address(sfs.current()->pc());
-      assert(map != NULL, "no oopmap found for pc");
-      found = map->has_derived_pointer();
-    }
-  }
-  if (found) {
-    // $$$ Not sure what to do here.
-    /*
-    Scavenge::invoke(0);
-    */
-  }
-#endif
-}
-
-
 void InterfaceSupport::verify_stack() {
   JavaThread* thread = JavaThread::current();
   ResourceMark rm(thread);
--- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -62,7 +62,6 @@
 
   static void zombieAll();
   static void deoptimizeAll();
-  static void stress_derived_pointers();
   static void verify_stack();
   static void verify_last_frame();
 # endif
--- a/src/hotspot/share/runtime/mutex.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/mutex.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -70,22 +70,16 @@
 }
 #endif // ASSERT
 
-void Mutex::lock(Thread* self) {
-  check_safepoint_state(self);
-
-  assert(_owner != self, "invariant");
-
-  Mutex* in_flight_mutex = NULL;
+void Mutex::lock_contended(Thread* self) {
+  Mutex *in_flight_mutex = NULL;
   DEBUG_ONLY(int retry_cnt = 0;)
   bool is_active_Java_thread = self->is_active_Java_thread();
-  while (!_lock.try_lock()) {
-    // The lock is contended
-
-  #ifdef ASSERT
+  do {
+    #ifdef ASSERT
     if (retry_cnt++ > 3) {
       log_trace(vmmutex)("JavaThread " INTPTR_FORMAT " on %d attempt trying to acquire vmmutex %s", p2i(self), retry_cnt, _name);
     }
-  #endif // ASSERT
+    #endif // ASSERT
 
     // Is it a JavaThread participating in the safepoint protocol.
     if (is_active_Java_thread) {
@@ -102,6 +96,17 @@
       _lock.lock();
       break;
     }
+  } while (!_lock.try_lock());
+}
+
+void Mutex::lock(Thread* self) {
+  check_safepoint_state(self);
+
+  assert(_owner != self, "invariant");
+
+  if (!_lock.try_lock()) {
+    // The lock is contended, use contended slow-path function to lock
+    lock_contended(self);
   }
 
   assert_owner(NULL);
@@ -109,7 +114,7 @@
 }
 
 void Mutex::lock() {
-  this->lock(Thread::current());
+  lock(Thread::current());
 }
 
 // Lock without safepoint check - a degenerate variant of lock() for use by
--- a/src/hotspot/share/runtime/mutex.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/mutex.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -152,6 +152,9 @@
   bool is_locked() const                     { return _owner != NULL; }
 
   bool try_lock(); // Like lock(), but unblocking. It returns false instead
+ private:
+  void lock_contended(Thread *thread); // contended slow-path
+ public:
 
   void release_for_safepoint();
 
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -66,7 +66,6 @@
 Mutex*   RetData_lock                 = NULL;
 Monitor* VMOperationQueue_lock        = NULL;
 Monitor* VMOperationRequest_lock      = NULL;
-Monitor* SerializePage_lock           = NULL;
 Monitor* Threads_lock                 = NULL;
 Mutex*   NonJavaThreadsList_lock      = NULL;
 Mutex*   NonJavaThreadsListSync_lock  = NULL;
@@ -116,8 +115,10 @@
 
 Mutex*   Management_lock              = NULL;
 Monitor* Service_lock                 = NULL;
+Monitor* Notification_lock            = NULL;
 Monitor* PeriodicTask_lock            = NULL;
 Monitor* RedefineClasses_lock         = NULL;
+Mutex*   Verify_lock                  = NULL;
 
 #if INCLUDE_JFR
 Mutex*   JfrStacktrace_lock           = NULL;
@@ -236,6 +237,13 @@
   def(Patching_lock                , PaddedMutex  , special,     true,  _safepoint_check_never);      // used for safepointing and code patching.
   def(CompiledMethod_lock          , PaddedMutex  , special-1,   true,  _safepoint_check_never);
   def(Service_lock                 , PaddedMonitor, special,     true,  _safepoint_check_never);      // used for service thread operations
+
+  if (UseNotificationThread) {
+    def(Notification_lock            , PaddedMonitor, special,     true,  _safepoint_check_never);  // used for notification thread operations
+  } else {
+    Notification_lock = Service_lock;
+  }
+
   def(JmethodIdCreation_lock       , PaddedMutex  , leaf,        true,  _safepoint_check_always); // used for creating jmethodIDs.
 
   def(SystemDictionary_lock        , PaddedMonitor, leaf,        true,  _safepoint_check_always);
@@ -298,6 +306,7 @@
   def(CompileThread_lock           , PaddedMonitor, nonleaf+5,   false, _safepoint_check_always);
   def(PeriodicTask_lock            , PaddedMonitor, nonleaf+5,   true,  _safepoint_check_always);
   def(RedefineClasses_lock         , PaddedMonitor, nonleaf+5,   true,  _safepoint_check_always);
+  def(Verify_lock                  , PaddedMutex,   nonleaf+5,   true,  _safepoint_check_always);
 
   if (WhiteBoxAPI) {
     def(Compilation_lock           , PaddedMonitor, leaf,        false, _safepoint_check_never);
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -103,7 +103,6 @@
 extern Mutex*   RawMonitor_lock;
 extern Mutex*   PerfDataMemAlloc_lock;           // a lock on the allocator for PerfData memory for performance data
 extern Mutex*   PerfDataManager_lock;            // a long on access to PerfDataManager resources
-extern Mutex*   ParkerFreeList_lock;
 extern Mutex*   OopMapCacheAlloc_lock;           // protects allocation of oop_map caches
 
 extern Mutex*   FreeList_lock;                   // protects the free region list during safepoints
@@ -112,8 +111,10 @@
 
 extern Mutex*   Management_lock;                 // a lock used to serialize JVM management
 extern Monitor* Service_lock;                    // a lock used for service thread operation
+extern Monitor* Notification_lock;               // a lock used for notification thread operation
 extern Monitor* PeriodicTask_lock;               // protects the periodic task structure
 extern Monitor* RedefineClasses_lock;            // locks classes from parallel redefinition
+extern Mutex*   Verify_lock;                     // synchronize initialization of verify library
 extern Monitor* ThreadsSMRDelete_lock;           // Used by ThreadsSMRSupport to take pressure off the Threads_lock
 extern Mutex*   ThreadIdTableCreate_lock;        // Used by ThreadIdTable to lazily create the thread id table
 extern Mutex*   SharedDecoder_lock;              // serializes access to the decoder during normal (not error reporting) use
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/notificationThread.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,128 @@
+/*
+ * 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/universe.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+#include "runtime/javaCalls.hpp"
+#include "runtime/notificationThread.hpp"
+#include "services/diagnosticArgument.hpp"
+#include "services/diagnosticFramework.hpp"
+#include "services/gcNotifier.hpp"
+#include "services/lowMemoryDetector.hpp"
+
+NotificationThread* NotificationThread::_instance = NULL;
+
+void NotificationThread::initialize() {
+  EXCEPTION_MARK;
+
+  const char* name = "Notification Thread";
+  Handle string = java_lang_String::create_from_str(name, CHECK);
+
+  // Initialize thread_oop to put it into the system threadGroup
+  Handle thread_group (THREAD, Universe::system_thread_group());
+  Handle thread_oop = JavaCalls::construct_new_instance(
+                          SystemDictionary::Thread_klass(),
+                          vmSymbols::threadgroup_string_void_signature(),
+                          thread_group,
+                          string,
+                          CHECK);
+
+  Klass* group = SystemDictionary::ThreadGroup_klass();
+  JavaValue result(T_VOID);
+  JavaCalls::call_special(&result,
+                          thread_group,
+                          group,
+                          vmSymbols::add_method_name(),
+                          vmSymbols::thread_void_signature(),
+                          thread_oop,
+                          THREAD);
+  {
+    MutexLocker mu(Threads_lock);
+    NotificationThread* thread =  new NotificationThread(&notification_thread_entry);
+
+    // At this point it may be possible that no osthread was created for the
+    // JavaThread due to lack of memory. We would have to throw an exception
+    // in that case. However, since this must work and we do not allow
+    // exceptions anyway, check and abort if this fails.
+    if (thread == NULL || thread->osthread() == NULL) {
+      vm_exit_during_initialization("java.lang.OutOfMemoryError",
+                                    os::native_thread_creation_failed_msg());
+    }
+
+    java_lang_Thread::set_thread(thread_oop(), thread);
+    java_lang_Thread::set_priority(thread_oop(), NearMaxPriority);
+    java_lang_Thread::set_daemon(thread_oop());
+    thread->set_threadObj(thread_oop());
+    _instance = thread;
+
+    Threads::add(thread);
+    Thread::start(thread);
+  }
+}
+
+
+
+void NotificationThread::notification_thread_entry(JavaThread* jt, TRAPS) {
+  while (true) {
+    bool sensors_changed = false;
+    bool has_dcmd_notification_event = false;
+    bool has_gc_notification_event = false;
+    {
+      // Need state transition ThreadBlockInVM so that this thread
+      // will be handled by safepoint correctly when this thread is
+      // notified at a safepoint.
+
+      ThreadBlockInVM tbivm(jt);
+
+      MonitorLocker ml(Notification_lock, Mutex::_no_safepoint_check_flag);
+      // Process all available work on each (outer) iteration, rather than
+      // only the first recognized bit of work, to avoid frequently true early
+      // tests from potentially starving later work.  Hence the use of
+      // arithmetic-or to combine results; we don't want short-circuiting.
+      while (((sensors_changed = LowMemoryDetector::has_pending_requests()) |
+              (has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification()) |
+              (has_gc_notification_event = GCNotifier::has_event()))
+             == 0) {
+        // Wait as a suspend equalent until notified that there is some work to do.
+        ml.wait(0, true);
+      }
+
+    }
+
+    if (sensors_changed) {
+      LowMemoryDetector::process_sensor_changes(jt);
+    }
+
+    if(has_gc_notification_event) {
+      GCNotifier::sendNotification(CHECK);
+    }
+
+    if(has_dcmd_notification_event) {
+      DCmdFactory::send_notification(CHECK);
+    }
+
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/runtime/notificationThread.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_RUNTIME_NOTIFICATIONTHREAD_HPP
+#define SHARE_RUNTIME_NOTIFICATIONTHREAD_HPP
+
+#include "runtime/thread.hpp"
+
+// A JavaThread for low memory detection support, GC and
+// diagnostic framework notifications. This thread is not hidden
+// from the external view to allow the debugger to stop at the
+// breakpoints inside registred MXBean notification listeners.
+
+class NotificationThread : public JavaThread {
+  friend class VMStructs;
+ private:
+
+  static NotificationThread* _instance;
+
+  static void notification_thread_entry(JavaThread* thread, TRAPS);
+  NotificationThread(ThreadFunction entry_point) : JavaThread(entry_point) {};
+
+ public:
+  static void initialize();
+
+};
+
+#endif // SHARE_RUNTIME_NOTIFICATIONTHREAD_HPP
--- a/src/hotspot/share/runtime/objectMonitor.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/objectMonitor.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -43,7 +43,6 @@
 class ObjectWaiter : public StackObj {
  public:
   enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ };
-  enum Sorted  { PREPEND, APPEND, SORTED };
   ObjectWaiter* volatile _next;
   ObjectWaiter* volatile _prev;
   Thread*       _thread;
@@ -51,7 +50,6 @@
   ParkEvent *   _event;
   volatile int  _notified;
   volatile TStates TState;
-  Sorted        _Sorted;           // List placement disposition
   bool          _active;           // Contention monitoring is enabled
  public:
   ObjectWaiter(Thread* thread);
@@ -68,10 +66,6 @@
 // WARNING: This is a very sensitive and fragile class. DO NOT make any
 // changes unless you are fully aware of the underlying semantics.
 //
-// Class JvmtiRawMonitor currently inherits from ObjectMonitor so
-// changes in this class must be careful to not break JvmtiRawMonitor.
-// These two subsystems should be separated.
-//
 // ObjectMonitor Layout Overview/Highlights/Restrictions:
 //
 // - The _header field must be at offset 0 because the displaced header
@@ -127,16 +121,6 @@
 //     in a 64-bit JVM.
 
 class ObjectMonitor {
- public:
-  enum {
-    OM_OK,                    // no error
-    OM_SYSTEM_ERROR,          // operating system error
-    OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
-    OM_INTERRUPTED,           // Thread.interrupt()
-    OM_TIMED_OUT              // Object.wait() timed out
-  };
-
- private:
   friend class ObjectSynchronizer;
   friend class ObjectWaiter;
   friend class VMStructs;
@@ -158,16 +142,13 @@
   DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE,
                         sizeof(volatile markWord) + sizeof(void* volatile) +
                         sizeof(ObjectMonitor *));
- protected:                         // protected for JvmtiRawMonitor
   void* volatile _owner;            // pointer to owning thread OR BasicLock
- private:
   volatile jlong _previous_owner_tid;  // thread id of the previous owner of the monitor
- protected:                         // protected for JvmtiRawMonitor
   volatile intptr_t _recursions;    // recursion count, 0 for first entry
   ObjectWaiter* volatile _EntryList;  // Threads blocked on entry or reentry.
                                       // The list is actually composed of WaitNodes,
                                       // acting as proxies for Threads.
- private:
+
   ObjectWaiter* volatile _cxq;      // LL of recently-arrived threads blocked on entry.
   Thread* volatile _succ;           // Heir presumptive thread - used for futile wakeup throttling
   Thread* volatile _Responsible;
--- a/src/hotspot/share/runtime/os.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/os.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -536,14 +536,6 @@
     char buffer[JVM_MAXPATHLEN];
     char ebuf[1024];
 
-    // Try to load verify dll first. In 1.3 java dll depends on it and is not
-    // always able to find it when the loading executable is outside the JDK.
-    // In order to keep working with 1.2 we ignore any loading errors.
-    if (dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(),
-                       "verify")) {
-      dll_load(buffer, ebuf, sizeof(ebuf));
-    }
-
     // Load java dll
     if (dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(),
                        "java")) {
--- a/src/hotspot/share/runtime/serviceThread.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/serviceThread.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -43,6 +43,7 @@
 #include "services/diagnosticFramework.hpp"
 #include "services/gcNotifier.hpp"
 #include "services/lowMemoryDetector.hpp"
+#include "services/threadIdTable.hpp"
 
 ServiceThread* ServiceThread::_instance = NULL;
 
@@ -101,6 +102,7 @@
     bool stringtable_work = false;
     bool symboltable_work = false;
     bool resolved_method_table_work = false;
+    bool thread_id_table_work = false;
     bool protection_domain_table_work = false;
     bool oopstorage_work = false;
     JvmtiDeferredEvent jvmti_event;
@@ -120,13 +122,14 @@
       // only the first recognized bit of work, to avoid frequently true early
       // tests from potentially starving later work.  Hence the use of
       // arithmetic-or to combine results; we don't want short-circuiting.
-      while (((sensors_changed = LowMemoryDetector::has_pending_requests()) |
+      while (((sensors_changed = (!UseNotificationThread && LowMemoryDetector::has_pending_requests())) |
               (has_jvmti_events = JvmtiDeferredEventQueue::has_events()) |
-              (has_gc_notification_event = GCNotifier::has_event()) |
-              (has_dcmd_notification_event = DCmdFactory::has_pending_jmx_notification()) |
+              (has_gc_notification_event = (!UseNotificationThread && GCNotifier::has_event())) |
+              (has_dcmd_notification_event = (!UseNotificationThread && DCmdFactory::has_pending_jmx_notification())) |
               (stringtable_work = StringTable::has_work()) |
               (symboltable_work = SymbolTable::has_work()) |
               (resolved_method_table_work = ResolvedMethodTable::has_work()) |
+              (thread_id_table_work = ThreadIdTable::has_work()) |
               (protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) |
               (oopstorage_work = OopStorage::has_cleanup_work_and_reset())
              ) == 0) {
@@ -151,22 +154,28 @@
       jvmti_event.post();
     }
 
-    if (sensors_changed) {
-      LowMemoryDetector::process_sensor_changes(jt);
-    }
+    if (!UseNotificationThread) {
+      if (sensors_changed) {
+        LowMemoryDetector::process_sensor_changes(jt);
+      }
 
-    if(has_gc_notification_event) {
-      GCNotifier::sendNotification(CHECK);
-    }
+      if(has_gc_notification_event) {
+        GCNotifier::sendNotification(CHECK);
+      }
 
-    if(has_dcmd_notification_event) {
-      DCmdFactory::send_notification(CHECK);
+      if(has_dcmd_notification_event) {
+        DCmdFactory::send_notification(CHECK);
+      }
     }
 
     if (resolved_method_table_work) {
       ResolvedMethodTable::do_concurrent_work(jt);
     }
 
+    if (thread_id_table_work) {
+      ThreadIdTable::do_concurrent_work(jt);
+    }
+
     if (protection_domain_table_work) {
       SystemDictionary::pd_cache_table()->unlink();
     }
--- a/src/hotspot/share/runtime/serviceThread.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/serviceThread.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -27,8 +27,10 @@
 
 #include "runtime/thread.hpp"
 
-// A JavaThread for low memory detection support and JVMTI
-// compiled-method-load events.
+// A hidden from external view JavaThread for JVMTI compiled-method-load
+// events, oop storage cleanup, and the maintainance of string, symbol,
+// protection domain, and resolved method tables.
+
 class ServiceThread : public JavaThread {
   friend class VMStructs;
  private:
--- a/src/hotspot/share/runtime/thread.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/thread.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -258,6 +258,7 @@
   _current_pending_monitor = NULL;
   _current_pending_monitor_is_from_java = true;
   _current_waiting_monitor = NULL;
+  _current_pending_raw_monitor = NULL;
   _num_nested_signal = 0;
   om_free_list = NULL;
   om_free_count = 0;
@@ -3847,7 +3848,7 @@
   // Create the VMThread
   { TraceTime timer("Start VMThread", TRACETIME_LOG(Info, startuptime));
 
-  VMThread::create();
+    VMThread::create();
     Thread* vmthread = VMThread::vm_thread();
 
     if (!os::create_thread(vmthread, os::vm_thread)) {
@@ -4185,7 +4186,7 @@
   for (agent = Arguments::agents(); agent != NULL; agent = agent->next()) {
     // CDS dumping does not support native JVMTI agent.
     // CDS dumping supports Java agent if the AllowArchivingWithJavaAgent diagnostic option is specified.
-    if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
+    if (Arguments::is_dumping_archive()) {
       if(!agent->is_instrument_lib()) {
         vm_exit_during_cds_dumping("CDS dumping does not support native JVMTI agent, name", agent->name());
       } else if (!AllowArchivingWithJavaAgent) {
--- a/src/hotspot/share/runtime/thread.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/thread.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -62,6 +62,7 @@
 class ThreadsList;
 class ThreadsSMRSupport;
 
+class JvmtiRawMonitor;
 class JvmtiThreadState;
 class ThreadStatistics;
 class ConcurrentLocksDump;
@@ -404,6 +405,9 @@
   ObjectMonitor* _current_pending_monitor;      // ObjectMonitor this thread
                                                 // is waiting to lock
   bool _current_pending_monitor_is_from_java;   // locking is from Java code
+  JvmtiRawMonitor* _current_pending_raw_monitor; // JvmtiRawMonitor this thread
+                                                 // is waiting to lock
+
 
   // ObjectMonitor on which this thread called Object.wait()
   ObjectMonitor* _current_waiting_monitor;
@@ -640,6 +644,14 @@
     _current_waiting_monitor = monitor;
   }
 
+  // For tracking the Jvmti raw monitor the thread is pending on.
+  JvmtiRawMonitor* current_pending_raw_monitor() {
+    return _current_pending_raw_monitor;
+  }
+  void set_current_pending_raw_monitor(JvmtiRawMonitor* monitor) {
+    _current_pending_raw_monitor = monitor;
+  }
+
   // GC support
   // Apply "f->do_oop" to all root oops in "this".
   //   Used by JavaThread::oops_do.
@@ -786,7 +798,7 @@
  public:
   volatile intptr_t _Stalled;
   volatile int _TypeTag;
-  ParkEvent * _ParkEvent;                     // for synchronized()
+  ParkEvent * _ParkEvent;                     // for Object monitors and JVMTI raw monitors
   ParkEvent * _MuxEvent;                      // for low-level muxAcquire-muxRelease
   int NativeSyncRecursion;                    // diagnostic
 
--- a/src/hotspot/share/runtime/vmStructs.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -88,6 +88,7 @@
 #include "runtime/globals.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
+#include "runtime/notificationThread.hpp"
 #include "runtime/os.hpp"
 #include "runtime/perfMemory.hpp"
 #include "runtime/serviceThread.hpp"
@@ -1366,6 +1367,7 @@
       declare_type(JavaThread, Thread)                                    \
         declare_type(JvmtiAgentThread, JavaThread)                        \
         declare_type(ServiceThread, JavaThread)                           \
+        declare_type(NotificationThread, JavaThread)                      \
         declare_type(CompilerThread, JavaThread)                          \
         declare_type(CodeCacheSweeperThread, JavaThread)                  \
   declare_toplevel_type(OSThread)                                         \
--- a/src/hotspot/share/services/diagnosticFramework.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/services/diagnosticFramework.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -437,9 +437,9 @@
 }
 
 void DCmdFactory::push_jmx_notification_request() {
-  MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
+  MutexLocker ml(Notification_lock, Mutex::_no_safepoint_check_flag);
   _has_pending_jmx_notification = true;
-  Service_lock->notify_all();
+  Notification_lock->notify_all();
 }
 
 void DCmdFactory::send_notification(TRAPS) {
@@ -455,7 +455,7 @@
   HandleMark hm(THREAD);
   bool notif = false;
   {
-    MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
+    MutexLocker ml(Notification_lock, Mutex::_no_safepoint_check_flag);
     notif = _has_pending_jmx_notification;
     _has_pending_jmx_notification = false;
   }
--- a/src/hotspot/share/services/gcNotifier.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/services/gcNotifier.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -54,18 +54,18 @@
  }
 
 void GCNotifier::addRequest(GCNotificationRequest *request) {
-  MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
+  MutexLocker ml(Notification_lock, Mutex::_no_safepoint_check_flag);
   if(first_request == NULL) {
     first_request = request;
   } else {
     last_request->next = request;
   }
   last_request = request;
-  Service_lock->notify_all();
+  Notification_lock->notify_all();
 }
 
 GCNotificationRequest *GCNotifier::getRequest() {
-  MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
+  MutexLocker ml(Notification_lock, Mutex::_no_safepoint_check_flag);
   GCNotificationRequest *request = first_request;
   if(first_request != NULL) {
     first_request = first_request->next;
--- a/src/hotspot/share/services/lowMemoryDetector.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/services/lowMemoryDetector.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -40,7 +40,7 @@
 volatile jint LowMemoryDetector::_disabled_count = 0;
 
 bool LowMemoryDetector::has_pending_requests() {
-  assert(Service_lock->owned_by_self(), "Must own Service_lock");
+  assert(Notification_lock->owned_by_self(), "Must own Notification_lock");
   bool has_requests = false;
   int num_memory_pools = MemoryService::num_memory_pools();
   for (int i = 0; i < num_memory_pools; i++) {
@@ -62,7 +62,7 @@
   ResourceMark rm(THREAD);
   HandleMark hm(THREAD);
 
-  // No need to hold Service_lock to call out to Java
+  // No need to hold Notification_lock to call out to Java
   int num_memory_pools = MemoryService::num_memory_pools();
   for (int i = 0; i < num_memory_pools; i++) {
     MemoryPool* pool = MemoryService::get_memory_pool(i);
@@ -80,7 +80,7 @@
 // This method could be called from any Java threads
 // and also VMThread.
 void LowMemoryDetector::detect_low_memory() {
-  MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
+  MutexLocker ml(Notification_lock, Mutex::_no_safepoint_check_flag);
 
   bool has_pending_requests = false;
   int num_memory_pools = MemoryService::num_memory_pools();
@@ -98,7 +98,7 @@
   }
 
   if (has_pending_requests) {
-    Service_lock->notify_all();
+    Notification_lock->notify_all();
   }
 }
 
@@ -113,14 +113,14 @@
   }
 
   {
-    MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
+    MutexLocker ml(Notification_lock, Mutex::_no_safepoint_check_flag);
 
     MemoryUsage usage = pool->get_memory_usage();
     sensor->set_gauge_sensor_level(usage,
                                    pool->usage_threshold());
     if (sensor->has_pending_requests()) {
       // notify sensor state update
-      Service_lock->notify_all();
+      Notification_lock->notify_all();
     }
   }
 }
@@ -135,14 +135,14 @@
   }
 
   {
-    MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
+    MutexLocker ml(Notification_lock, Mutex::_no_safepoint_check_flag);
 
     MemoryUsage usage = pool->get_last_collection_usage();
     sensor->set_counter_sensor_level(usage, pool->gc_usage_threshold());
 
     if (sensor->has_pending_requests()) {
       // notify sensor state update
-      Service_lock->notify_all();
+      Notification_lock->notify_all();
     }
   }
 }
@@ -205,7 +205,7 @@
 // If the current level is between high and low threshold, no change.
 //
 void SensorInfo::set_gauge_sensor_level(MemoryUsage usage, ThresholdSupport* high_low_threshold) {
-  assert(Service_lock->owned_by_self(), "Must own Service_lock");
+  assert(Notification_lock->owned_by_self(), "Must own Notification_lock");
   assert(high_low_threshold->is_high_threshold_supported(), "just checking");
 
   bool is_over_high = high_low_threshold->is_high_threshold_crossed(usage);
@@ -260,7 +260,7 @@
 //      the sensor will be on (i.e. sensor is currently off
 //      and has pending trigger requests).
 void SensorInfo::set_counter_sensor_level(MemoryUsage usage, ThresholdSupport* counter_threshold) {
-  assert(Service_lock->owned_by_self(), "Must own Service_lock");
+  assert(Notification_lock->owned_by_self(), "Must own Notification_lock");
   assert(counter_threshold->is_high_threshold_supported(), "just checking");
 
   bool is_over_high = counter_threshold->is_high_threshold_crossed(usage);
@@ -334,8 +334,8 @@
   }
 
   {
-    // Holds Service_lock and update the sensor state
-    MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
+    // Holds Notification_lock and update the sensor state
+    MutexLocker ml(Notification_lock, Mutex::_no_safepoint_check_flag);
     assert(_pending_trigger_count > 0, "Must have pending trigger");
     _sensor_on = true;
     _sensor_count += count;
@@ -345,8 +345,8 @@
 
 void SensorInfo::clear(int count, TRAPS) {
   {
-    // Holds Service_lock and update the sensor state
-    MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
+    // Holds Notification_lock and update the sensor state
+    MutexLocker ml(Notification_lock, Mutex::_no_safepoint_check_flag);
     if (_pending_clear_count == 0) {
       // Bail out if we lost a race to set_*_sensor_level() which may have
       // reactivated the sensor in the meantime because it was triggered again.
--- a/src/hotspot/share/services/lowMemoryDetector.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/services/lowMemoryDetector.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -59,7 +59,8 @@
 //
 // May need to deal with hysteresis effect.
 //
-// Memory detection code runs in the Service thread (serviceThread.hpp).
+// Memory detection code runs in the Notification thread or
+// ServiceThread depending on UseNotificationThread flag.
 
 class OopClosure;
 class MemoryPool;
@@ -214,6 +215,7 @@
 class LowMemoryDetector : public AllStatic {
   friend class LowMemoryDetectorDisabler;
   friend class ServiceThread;
+  friend class NotificationThread;
 private:
   // true if any collected heap has low memory detection enabled
   static volatile bool _enabled_for_collected_pools;
--- a/src/hotspot/share/services/management.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/services/management.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -44,6 +44,7 @@
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jniHandles.inline.hpp"
+#include "runtime/notificationThread.hpp"
 #include "runtime/os.hpp"
 #include "runtime/serviceThread.hpp"
 #include "runtime/thread.inline.hpp"
@@ -148,7 +149,9 @@
 void Management::initialize(TRAPS) {
   // Start the service thread
   ServiceThread::initialize();
-
+  if (UseNotificationThread) {
+    NotificationThread::initialize();
+  }
   if (ManagementServer) {
     ResourceMark rm(THREAD);
     HandleMark hm(THREAD);
--- a/src/hotspot/share/services/threadIdTable.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/services/threadIdTable.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -46,6 +46,7 @@
 static volatile size_t _items_count = 0;
 
 volatile bool ThreadIdTable::_is_initialized = false;
+volatile bool ThreadIdTable::_has_work = false;
 
 class ThreadIdTableEntry : public CHeapObj<mtInternal> {
 private:
@@ -141,6 +142,26 @@
   return (size_t)1 << _local_table->get_size_log2(Thread::current());
 }
 
+void ThreadIdTable::check_concurrent_work() {
+  if (_has_work) {
+    return;
+  }
+
+  double load_factor = get_load_factor();
+  // Resize if we have more items than preferred load factor
+  if ( load_factor > PREF_AVG_LIST_LEN && !_local_table->is_max_size_reached()) {
+    log_debug(thread, table)("Concurrent work triggered, load factor: %g",
+                             load_factor);
+    trigger_concurrent_work();
+  }
+}
+
+void ThreadIdTable::trigger_concurrent_work() {
+  MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag);
+  _has_work = true;
+  Service_lock->notify_all();
+}
+
 void ThreadIdTable::grow(JavaThread* jt) {
   ThreadIdTableHash::GrowTask gt(_local_table);
   if (!gt.prepare(jt)) {
@@ -192,13 +213,13 @@
   }
 };
 
-void ThreadIdTable::grow_if_required() {
-  assert(Thread::current()->is_Java_thread(),"Must be Java thread");
+void ThreadIdTable::do_concurrent_work(JavaThread* jt) {
   assert(_is_initialized, "Thread table is not initialized");
+  _has_work = false;
   double load_factor = get_load_factor();
   log_debug(thread, table)("Concurrent work, load factor: %g", load_factor);
   if (load_factor > PREF_AVG_LIST_LEN && !_local_table->is_max_size_reached()) {
-    grow(JavaThread::current());
+    grow(jt);
   }
 }
 
@@ -215,7 +236,7 @@
     // The hash table takes ownership of the ThreadTableEntry,
     // even if it's not inserted.
     if (_local_table->insert(thread, lookup, entry)) {
-      grow_if_required();
+      check_concurrent_work();
       return java_thread;
     }
   }
--- a/src/hotspot/share/services/threadIdTable.hpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/services/threadIdTable.hpp	Thu Oct 10 10:57:42 2019 -0400
@@ -36,6 +36,7 @@
   friend class ThreadIdTableConfig;
 
   static volatile bool _is_initialized;
+  static volatile bool _has_work;
 
 public:
   // Initialization
@@ -47,12 +48,17 @@
   static JavaThread* add_thread(jlong tid, JavaThread* thread);
   static bool remove_thread(jlong tid);
 
+  // Growing
+  static bool has_work() { return _has_work; }
+  static void do_concurrent_work(JavaThread* jt);
+
 private:
   static void create_table(size_t size);
 
   static size_t table_size();
   static double get_load_factor();
-  static void grow_if_required();
+  static void check_concurrent_work();
+  static void trigger_concurrent_work();
   static void grow(JavaThread* jt);
 
   static void item_added();
--- a/src/hotspot/share/services/threadService.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/hotspot/share/services/threadService.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -32,6 +32,7 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "prims/jvmtiRawMonitor.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
@@ -217,10 +218,10 @@
   } else {
     ObjectMonitor *enter_obj = thread->current_pending_monitor();
     if (enter_obj != NULL) {
-      // thread is trying to enter() or raw_enter() an ObjectMonitor.
+      // thread is trying to enter() an ObjectMonitor.
       obj = (oop) enter_obj->object();
+      assert(obj != NULL, "ObjectMonitor should have an associated object!");
     }
-    // If obj == NULL, then ObjectMonitor is raw which doesn't count.
   }
 
   Handle h(Thread::current(), obj);
@@ -354,13 +355,15 @@
   }
 }
 
-// Find deadlocks involving object monitors and concurrent locks if concurrent_locks is true
+// Find deadlocks involving raw monitors, object monitors and concurrent locks
+// if concurrent_locks is true.
 DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(ThreadsList * t_list, bool concurrent_locks) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 
   // This code was modified from the original Threads::find_deadlocks code.
   int globalDfn = 0, thisDfn;
   ObjectMonitor* waitingToLockMonitor = NULL;
+  JvmtiRawMonitor* waitingToLockRawMonitor = NULL;
   oop waitingToLockBlocker = NULL;
   bool blocked_on_monitor = false;
   JavaThread *currentThread, *previousThread;
@@ -391,13 +394,30 @@
     // When there is a deadlock, all the monitors involved in the dependency
     // cycle must be contended and heavyweight. So we only care about the
     // heavyweight monitor a thread is waiting to lock.
-    waitingToLockMonitor = (ObjectMonitor*)jt->current_pending_monitor();
+    waitingToLockMonitor = jt->current_pending_monitor();
+    // JVM TI raw monitors can also be involved in deadlocks, and we can be
+    // waiting to lock both a raw monitor and ObjectMonitor at the same time.
+    // It isn't clear how to make deadlock detection work correctly if that
+    // happens.
+    waitingToLockRawMonitor = jt->current_pending_raw_monitor();
+
     if (concurrent_locks) {
       waitingToLockBlocker = jt->current_park_blocker();
     }
-    while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) {
+
+    while (waitingToLockMonitor != NULL ||
+           waitingToLockRawMonitor != NULL ||
+           waitingToLockBlocker != NULL) {
       cycle->add_thread(currentThread);
-      if (waitingToLockMonitor != NULL) {
+      // Give preference to the raw monitor
+      if (waitingToLockRawMonitor != NULL) {
+        Thread* owner = waitingToLockRawMonitor->owner();
+        if (owner != NULL && // the raw monitor could be released at any time
+            owner->is_Java_thread()) {
+          // only JavaThreads can be reported here
+          currentThread = (JavaThread*) owner;
+        }
+      } else if (waitingToLockMonitor != NULL) {
         address currentOwner = (address)waitingToLockMonitor->owner();
         if (currentOwner != NULL) {
           currentThread = Threads::owning_thread_from_monitor_owner(t_list,
@@ -948,28 +968,44 @@
 
   JavaThread* currentThread;
   ObjectMonitor* waitingToLockMonitor;
+  JvmtiRawMonitor* waitingToLockRawMonitor;
   oop waitingToLockBlocker;
   int len = _threads->length();
   for (int i = 0; i < len; i++) {
     currentThread = _threads->at(i);
-    waitingToLockMonitor = (ObjectMonitor*)currentThread->current_pending_monitor();
+    waitingToLockMonitor = currentThread->current_pending_monitor();
+    waitingToLockRawMonitor = currentThread->current_pending_raw_monitor();
     waitingToLockBlocker = currentThread->current_park_blocker();
     st->cr();
     st->print_cr("\"%s\":", currentThread->get_thread_name());
     const char* owner_desc = ",\n  which is held by";
+
+    // Note: As the JVM TI "monitor contended enter" event callback is executed after ObjectMonitor
+    // sets the current pending monitor, it is possible to then see a pending raw monitor as well.
+    if (waitingToLockRawMonitor != NULL) {
+      st->print("  waiting to lock JVM TI raw monitor " INTPTR_FORMAT, p2i(waitingToLockRawMonitor));
+      Thread* owner = waitingToLockRawMonitor->owner();
+      // Could be NULL as the raw monitor could be released at any time if held by non-JavaThread
+      if (owner != NULL) {
+        if (owner->is_Java_thread()) {
+          currentThread = (JavaThread*) owner;
+          st->print_cr("%s \"%s\"", owner_desc, currentThread->get_thread_name());
+        } else {
+          st->print_cr(",\n  which has now been released");
+        }
+      } else {
+        st->print_cr("%s non-Java thread=" PTR_FORMAT, owner_desc, p2i(owner));
+      }
+    }
+
     if (waitingToLockMonitor != NULL) {
       st->print("  waiting to lock monitor " INTPTR_FORMAT, p2i(waitingToLockMonitor));
       oop obj = (oop)waitingToLockMonitor->object();
-      if (obj != NULL) {
-        st->print(" (object " INTPTR_FORMAT ", a %s)", p2i(obj),
-                   obj->klass()->external_name());
+      st->print(" (object " INTPTR_FORMAT ", a %s)", p2i(obj),
+                 obj->klass()->external_name());
 
-        if (!currentThread->current_pending_monitor_is_from_java()) {
-          owner_desc = "\n  in JNI, which is held by";
-        }
-      } else {
-        // No Java object associated - a JVMTI raw monitor
-        owner_desc = " (JVMTI raw monitor),\n  which is held by";
+      if (!currentThread->current_pending_monitor_is_from_java()) {
+        owner_desc = "\n  in JNI, which is held by";
       }
       currentThread = Threads::owning_thread_from_monitor_owner(t_list,
                                                                 (address)waitingToLockMonitor->owner());
@@ -978,7 +1014,7 @@
         // that owns waitingToLockMonitor should be findable, but
         // if it is not findable, then the previous currentThread is
         // blocked permanently.
-        st->print("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc,
+        st->print_cr("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc,
                   p2i(waitingToLockMonitor->owner()));
         continue;
       }
@@ -992,11 +1028,10 @@
       currentThread = java_lang_Thread::thread(ownerObj);
       assert(currentThread != NULL, "AbstractOwnableSynchronizer owning thread is unexpectedly NULL");
     }
-    st->print("%s \"%s\"", owner_desc, currentThread->get_thread_name());
+    st->print_cr("%s \"%s\"", owner_desc, currentThread->get_thread_name());
   }
 
   st->cr();
-  st->cr();
 
   // Print stack traces
   bool oldJavaMonitorsInStackTrace = JavaMonitorsInStackTrace;
--- a/src/java.base/share/classes/java/io/BufferedReader.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/io/BufferedReader.java	Thu Oct 10 10:57:42 2019 -0400
@@ -314,7 +314,7 @@
      * @throws     IOException  If an I/O error occurs
      */
     String readLine(boolean ignoreLF, boolean[] term) throws IOException {
-        StringBuffer s = null;
+        StringBuilder s = null;
         int startChar;
 
         synchronized (lock) {
@@ -372,7 +372,7 @@
                 }
 
                 if (s == null)
-                    s = new StringBuffer(defaultExpectedLineLength);
+                    s = new StringBuilder(defaultExpectedLineLength);
                 s.append(cb, startChar, i - startChar);
             }
         }
--- a/src/java.base/share/classes/java/lang/Throwable.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/lang/Throwable.java	Thu Oct 10 10:57:42 2019 -0400
@@ -230,6 +230,7 @@
      * @serial
      * @since 1.7
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
 
     /** Message for trying to suppress a null exception. */
--- a/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/lang/invoke/SerializedLambda.java	Thu Oct 10 10:57:42 2019 -0400
@@ -76,6 +76,7 @@
     private final String implMethodSignature;
     private final int implMethodKind;
     private final String instantiatedMethodType;
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private final Object[] capturedArgs;
 
     /**
--- a/src/java.base/share/classes/java/lang/reflect/Proxy.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/lang/reflect/Proxy.java	Thu Oct 10 10:57:42 2019 -0400
@@ -308,6 +308,7 @@
      * the invocation handler for this proxy instance.
      * @serial
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     protected InvocationHandler h;
 
     /**
--- a/src/java.base/share/classes/java/net/DatagramSocket.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/net/DatagramSocket.java	Thu Oct 10 10:57:42 2019 -0400
@@ -434,14 +434,15 @@
      * verify that datagrams are permitted to be sent and received
      * respectively.
      *
-     * <p> When a socket is connected, {@link #receive receive} and
-     * {@link #send send} <b>will not perform any security checks</b>
-     * on incoming and outgoing packets, other than matching the packet's
-     * and the socket's address and port. On a send operation, if the
-     * packet's address is set and the packet's address and the socket's
-     * address do not match, an {@code IllegalArgumentException} will be
-     * thrown. A socket connected to a multicast address may only be used
-     * to send packets.
+     * <p> Care should be taken to ensure that a connected datagram socket
+     * is not shared with untrusted code. When a socket is connected,
+     * {@link #receive receive} and {@link #send send} <b>will not perform
+     * any security checks</b> on incoming and outgoing packets, other than
+     * matching the packet's and the socket's address and port. On a send
+     * operation, if the packet's address is set and the packet's address
+     * and the socket's address do not match, an {@code IllegalArgumentException}
+     * will be thrown. A socket connected to a multicast address may only
+     * be used to send packets.
      *
      * @param address the remote address for the socket
      *
@@ -708,9 +709,11 @@
      * the length of the received message. If the message is longer than
      * the packet's length, the message is truncated.
      * <p>
-     * If there is a security manager, a packet cannot be received if the
-     * security manager's {@code checkAccept} method
-     * does not allow it.
+     * If there is a security manager, and the socket is not currently
+     * connected to a remote address, a packet cannot be received if the
+     * security manager's {@code checkAccept} method does not allow it.
+     * Datagrams that are not permitted by the security manager are silently
+     * discarded.
      *
      * @param      p   the {@code DatagramPacket} into which to place
      *                 the incoming data.
@@ -896,12 +899,15 @@
      *
      * @param timeout the specified timeout in milliseconds.
      * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
+     * @throws IllegalArgumentException if {@code timeout} is negative
      * @since   1.1
      * @see #getSoTimeout()
      */
     public synchronized void setSoTimeout(int timeout) throws SocketException {
         if (isClosed())
             throw new SocketException("Socket is closed");
+        if (timeout < 0)
+            throw new IllegalArgumentException("timeout < 0");
         getImpl().setOption(SocketOptions.SO_TIMEOUT, timeout);
     }
 
--- a/src/java.base/share/classes/java/nio/channels/DatagramChannel.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/nio/channels/DatagramChannel.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -265,7 +265,10 @@
      * java.lang.SecurityManager#checkAccept checkAccept} and {@link
      * java.lang.SecurityManager#checkConnect checkConnect} methods permit
      * datagrams to be received from and sent to, respectively, the given
-     * remote address.
+     * remote address. Once connected, no further security checks are performed
+     * for datagrams received from, or sent to, the given remote address. Care
+     * 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
@@ -325,6 +328,10 @@
      * <p> If this channel's socket is not connected, or if the channel is
      * closed, then invoking this method has no effect.  </p>
      *
+     * @apiNote If this method throws an IOException, the channel's socket
+     * may be left in an unspecified state. It is strongly recommended that
+     * the channel be closed when disconnect fails.
+     *
      * @return  This datagram channel
      *
      * @throws  IOException
@@ -369,9 +376,10 @@
      * to a specific remote address and a security manager has been installed
      * then for each datagram received this method verifies that the source's
      * address and port number are permitted by the security manager's {@link
-     * java.lang.SecurityManager#checkAccept checkAccept} method.  The overhead
-     * of this security check can be avoided by first connecting the socket via
-     * the {@link #connect connect} method.
+     * java.lang.SecurityManager#checkAccept checkAccept} method. Datagrams
+     * that are not permitted by the security manager are silently discarded.
+     * The overhead of this security check can be avoided by first connecting
+     * the socket via the {@link #connect connect} method.
      *
      * <p> This method may be invoked at any time.  If another thread has
      * already initiated a read operation upon this channel, however, then an
@@ -401,11 +409,6 @@
      *          closing the channel and setting the current thread's
      *          interrupt status
      *
-     * @throws  SecurityException
-     *          If a security manager has been installed
-     *          and it does not permit datagrams to be accepted
-     *          from the datagram's sender
-     *
      * @throws  IOException
      *          If some other I/O error occurs
      */
--- a/src/java.base/share/classes/java/nio/channels/SelectionKey.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/nio/channels/SelectionKey.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,8 @@
 
 package java.nio.channels;
 
-import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
 
 /**
  * A token representing the registration of a {@link SelectableChannel} with a
@@ -428,13 +429,17 @@
 
     // -- Attachments --
 
+    private static final VarHandle ATTACHMENT;
+    static {
+        try {
+            MethodHandles.Lookup l = MethodHandles.lookup();
+            ATTACHMENT = l.findVarHandle(SelectionKey.class, "attachment", Object.class);
+        } catch (Exception e) {
+            throw new InternalError(e);
+        }
+    }
     private volatile Object attachment;
 
-    private static final AtomicReferenceFieldUpdater<SelectionKey,Object>
-        attachmentUpdater = AtomicReferenceFieldUpdater.newUpdater(
-            SelectionKey.class, Object.class, "attachment"
-        );
-
     /**
      * Attaches the given object to this key.
      *
@@ -450,7 +455,7 @@
      *          otherwise {@code null}
      */
     public final Object attach(Object ob) {
-        return attachmentUpdater.getAndSet(this, ob);
+        return ATTACHMENT.getAndSet(this, ob);
     }
 
     /**
--- a/src/java.base/share/classes/java/nio/channels/spi/AbstractSelectionKey.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/nio/channels/spi/AbstractSelectionKey.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,13 @@
 
 package java.nio.channels.spi;
 
-import java.nio.channels.*;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.Selector;
 
+import sun.nio.ch.SelectionKeyImpl;
+import sun.nio.ch.SelectorImpl;
 
 /**
  * Base implementation class for selection keys.
@@ -41,20 +46,29 @@
 public abstract class AbstractSelectionKey
     extends SelectionKey
 {
+    private static final VarHandle INVALID;
+    static {
+        try {
+            MethodHandles.Lookup l = MethodHandles.lookup();
+            INVALID = l.findVarHandle(AbstractSelectionKey.class, "invalid", boolean.class);
+        } catch (Exception e) {
+            throw new InternalError(e);
+        }
+    }
 
     /**
      * Initializes a new instance of this class.
      */
     protected AbstractSelectionKey() { }
 
-    private volatile boolean valid = true;
+    private volatile boolean invalid;
 
     public final boolean isValid() {
-        return valid;
+        return !invalid;
     }
 
     void invalidate() {                                 // package-private
-        valid = false;
+        invalid = true;
     }
 
     /**
@@ -64,13 +78,14 @@
      * selector's cancelled-key set while synchronized on that set.  </p>
      */
     public final void cancel() {
-        // Synchronizing "this" to prevent this key from getting canceled
-        // multiple times by different threads, which might cause race
-        // condition between selector's select() and channel's close().
-        synchronized (this) {
-            if (valid) {
-                valid = false;
-                ((AbstractSelector)selector()).cancel(this);
+        boolean changed = (boolean) INVALID.compareAndSet(this, false, true);
+        if (changed) {
+            Selector sel = selector();
+            if (sel instanceof SelectorImpl) {
+                // queue cancelled key directly
+                ((SelectorImpl) sel).cancel((SelectionKeyImpl) this);
+            } else {
+                ((AbstractSelector) sel).cancel(this);
             }
         }
     }
--- a/src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/nio/channels/spi/AbstractSelector.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,12 +26,14 @@
 package java.nio.channels.spi;
 
 import java.io.IOException;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
 import java.util.HashSet;
 import java.util.Set;
 import sun.nio.ch.Interruptible;
-import java.util.concurrent.atomic.AtomicBoolean;
+import sun.nio.ch.SelectorImpl;
 
 
 /**
@@ -69,12 +71,23 @@
 public abstract class AbstractSelector
     extends Selector
 {
-
-    private final AtomicBoolean selectorOpen = new AtomicBoolean(true);
+    private static final VarHandle CLOSED;
+    static {
+        try {
+            MethodHandles.Lookup l = MethodHandles.lookup();
+            CLOSED = l.findVarHandle(AbstractSelector.class, "closed", boolean.class);
+        } catch (Exception e) {
+            throw new InternalError(e);
+        }
+    }
+    private volatile boolean closed;
 
     // The provider that created this selector
     private final SelectorProvider provider;
 
+    // cancelled-key, not used by the JDK Selector implementations
+    private final Set<SelectionKey> cancelledKeys;
+
     /**
      * Initializes a new instance of this class.
      *
@@ -83,10 +96,14 @@
      */
     protected AbstractSelector(SelectorProvider provider) {
         this.provider = provider;
+        if (this instanceof SelectorImpl) {
+            // not used in JDK Selector implementations
+            this.cancelledKeys = Set.of();
+        } else {
+            this.cancelledKeys = new HashSet<>();
+        }
     }
 
-    private final Set<SelectionKey> cancelledKeys = new HashSet<SelectionKey>();
-
     void cancel(SelectionKey k) {                       // package-private
         synchronized (cancelledKeys) {
             cancelledKeys.add(k);
@@ -105,10 +122,10 @@
      *          If an I/O error occurs
      */
     public final void close() throws IOException {
-        boolean open = selectorOpen.getAndSet(false);
-        if (!open)
-            return;
-        implCloseSelector();
+        boolean changed = (boolean) CLOSED.compareAndSet(this, false, true);
+        if (changed) {
+            implCloseSelector();
+        }
     }
 
     /**
@@ -130,7 +147,7 @@
     protected abstract void implCloseSelector() throws IOException;
 
     public final boolean isOpen() {
-        return selectorOpen.get();
+        return !closed;
     }
 
     /**
--- a/src/java.base/share/classes/java/nio/file/Files.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/nio/file/Files.java	Thu Oct 10 10:57:42 2019 -0400
@@ -3550,8 +3550,8 @@
         // ensure lines is not null before opening file
         Objects.requireNonNull(lines);
         CharsetEncoder encoder = cs.newEncoder();
-        OutputStream out = newOutputStream(path, options);
-        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
+        try (OutputStream out = newOutputStream(path, options);
+             BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out, encoder))) {
             for (CharSequence line: lines) {
                 writer.append(line);
                 writer.newLine();
--- a/src/java.base/share/classes/java/security/GuardedObject.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/security/GuardedObject.java	Thu Oct 10 10:57:42 2019 -0400
@@ -52,7 +52,9 @@
     @java.io.Serial
     private static final long serialVersionUID = -5240450096227834308L;
 
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private Object object; // the object we are guarding
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private Guard guard;   // the guard
 
     /**
--- a/src/java.base/share/classes/java/security/SecureRandom.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/security/SecureRandom.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1043,6 +1043,7 @@
     /**
      * @serial
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private MessageDigest digest = null;
     /**
      * @serial
--- a/src/java.base/share/classes/java/time/Clock.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/time/Clock.java	Thu Oct 10 10:57:42 2019 -0400
@@ -641,6 +641,7 @@
     static final class OffsetClock extends Clock implements Serializable {
         @java.io.Serial
         private static final long serialVersionUID = 2007484719125426256L;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         private final Clock baseClock;
         private final Duration offset;
 
@@ -692,6 +693,7 @@
     static final class TickClock extends Clock implements Serializable {
         @java.io.Serial
         private static final long serialVersionUID = 6504659149906368850L;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         private final Clock baseClock;
         private final long tickNanos;
 
--- a/src/java.base/share/classes/java/time/chrono/ChronoPeriodImpl.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/time/chrono/ChronoPeriodImpl.java	Thu Oct 10 10:57:42 2019 -0400
@@ -109,6 +109,7 @@
     /**
      * The chronology.
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private final Chronology chrono;
     /**
      * The number of years.
--- a/src/java.base/share/classes/java/util/AbstractMap.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/AbstractMap.java	Thu Oct 10 10:57:42 2019 -0400
@@ -607,7 +607,9 @@
         @java.io.Serial
         private static final long serialVersionUID = -8499721149061103585L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final K key;
+        @SuppressWarnings("serial") // Conditionally serializable
         private V value;
 
         /**
@@ -738,7 +740,9 @@
         @java.io.Serial
         private static final long serialVersionUID = 7138329143949025153L;
 
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         private final K key;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         private final V value;
 
         /**
--- a/src/java.base/share/classes/java/util/ArrayPrefixHelpers.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/ArrayPrefixHelpers.java	Thu Oct 10 10:57:42 2019 -0400
@@ -103,10 +103,15 @@
     static final int MIN_PARTITION = 16;
 
     static final class CumulateTask<T> extends CountedCompleter<Void> {
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         final T[] array;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         final BinaryOperator<T> function;
         CumulateTask<T> left, right;
-        T in, out;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
+        T in;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
+        T out;
         final int lo, hi, origin, fence, threshold;
 
         /** Root task constructor */
@@ -257,6 +262,7 @@
 
     static final class LongCumulateTask extends CountedCompleter<Void> {
         final long[] array;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         final LongBinaryOperator function;
         LongCumulateTask left, right;
         long in, out;
@@ -408,6 +414,7 @@
 
     static final class DoubleCumulateTask extends CountedCompleter<Void> {
         final double[] array;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         final DoubleBinaryOperator function;
         DoubleCumulateTask left, right;
         double in, out;
@@ -559,6 +566,7 @@
 
     static final class IntCumulateTask extends CountedCompleter<Void> {
         final int[] array;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         final IntBinaryOperator function;
         IntCumulateTask left, right;
         int in, out;
--- a/src/java.base/share/classes/java/util/Arrays.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/Arrays.java	Thu Oct 10 10:57:42 2019 -0400
@@ -4339,6 +4339,7 @@
     {
         @java.io.Serial
         private static final long serialVersionUID = -2764017481108945198L;
+        @SuppressWarnings("serial") // Conditionally serializable
         private final E[] a;
 
         ArrayList(E[] array) {
--- a/src/java.base/share/classes/java/util/ArraysParallelSortHelpers.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/ArraysParallelSortHelpers.java	Thu Oct 10 10:57:42 2019 -0400
@@ -115,8 +115,12 @@
         static final class Sorter<T> extends CountedCompleter<Void> {
             @java.io.Serial
             static final long serialVersionUID = 2446542900576103244L;
-            final T[] a, w;
+            @SuppressWarnings("serial") // Not statically typed as Serializable
+            final T[] a;
+            @SuppressWarnings("serial") // Not statically typed as Serializable
+            final T[] w;
             final int base, size, wbase, gran;
+            @SuppressWarnings("serial") // Not statically typed as Serializable
             Comparator<? super T> comparator;
             Sorter(CountedCompleter<?> par, T[] a, T[] w, int base, int size,
                    int wbase, int gran,
@@ -153,8 +157,13 @@
         static final class Merger<T> extends CountedCompleter<Void> {
             @java.io.Serial
             static final long serialVersionUID = 2446542900576103244L;
-            final T[] a, w; // main and workspace arrays
+             // main and workspace arrays
+            @SuppressWarnings("serial") // Not statically typed as Serializable
+            final T[] a;
+            @SuppressWarnings("serial") // Not statically typed as Serializable
+            final T[] w;
             final int lbase, lsize, rbase, rsize, wbase, gran;
+            @SuppressWarnings("serial") // Not statically typed as Serializable
             Comparator<? super T> comparator;
             Merger(CountedCompleter<?> par, T[] a, T[] w,
                    int lbase, int lsize, int rbase,
--- a/src/java.base/share/classes/java/util/Collection.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/Collection.java	Thu Oct 10 10:57:42 2019 -0400
@@ -188,6 +188,38 @@
  * or if the only reference to the backing collection is through an
  * unmodifiable view, the view can be considered effectively immutable.
  *
+ * <h2><a id="serializable">Serializability of Collections</a></h2>
+ *
+ * <p>Serializability of collections is optional. As such, none of the collections
+ * interfaces are declared to implement the {@link java.io.Serializable} interface.
+ * However, serializability is regarded as being generally useful, so most collection
+ * implementations are serializable.
+ *
+ * <p>The collection implementations that are public classes (such as {@code ArrayList}
+ * or {@code HashMap}) are declared to implement the {@code Serializable} interface if they
+ * are in fact serializable. Some collections implementations are not public classes,
+ * such as the <a href="#unmodifiable">unmodifiable collections.</a> In such cases, the
+ * serializability of such collections is described in the specification of the method
+ * that creates them, or in some other suitable place. In cases where the serializability
+ * of a collection is not specified, there is no guarantee about the serializability of such
+ * collections. In particular, many <a href="#view">view collections</a> are not serializable.
+ *
+ * <p>A collection implementation that implements the {@code Serializable} interface cannot
+ * be guaranteed to be serializable. The reason is that in general, collections
+ * contain elements of other types, and it is not possible to determine statically
+ * whether instances of some element type are actually serializable. For example, consider
+ * a serializable {@code Collection<E>}, where {@code E} does not implement the
+ * {@code Serializable} interface. The collection may be serializable, if it contains only
+ * elements of some serializable subtype of {@code E}, or if it is empty. Collections are
+ * thus said to be <i>conditionally serializable,</i> as the serializability of the collection
+ * as a whole depends on whether the collection itself is serializable and on whether all
+ * contained elements are also serializable.
+ *
+ * <p>An additional case occurs with instances of {@link SortedSet} and {@link SortedMap}.
+ * These collections can be created with a {@link Comparator} that imposes an ordering on
+ * the set elements or map keys. Such a collection is serializable only if the provided
+ * {@code Comparator} is also serializable.
+ *
  * <p>This interface is a member of the
  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
  * Java Collections Framework</a>.
--- a/src/java.base/share/classes/java/util/Collections.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/Collections.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1024,6 +1024,7 @@
         @java.io.Serial
         private static final long serialVersionUID = 1820017752578914078L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         final Collection<? extends E> c;
 
         UnmodifiableCollection(Collection<? extends E> c) {
@@ -1164,6 +1165,7 @@
                              implements SortedSet<E>, Serializable {
         @java.io.Serial
         private static final long serialVersionUID = -4929149591599911165L;
+        @SuppressWarnings("serial") // Conditionally serializable
         private final SortedSet<E> ss;
 
         UnmodifiableSortedSet(SortedSet<E> s) {super(s); ss = s;}
@@ -1244,6 +1246,7 @@
         /**
          * The instance we are protecting.
          */
+        @SuppressWarnings("serial") // Conditionally serializable
         private final NavigableSet<E> ns;
 
         UnmodifiableNavigableSet(NavigableSet<E> s)         {super(s); ns = s;}
@@ -1304,6 +1307,7 @@
         @java.io.Serial
         private static final long serialVersionUID = -283967356065247728L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         final List<? extends E> list;
 
         UnmodifiableList(List<? extends E> list) {
@@ -1450,6 +1454,7 @@
         @java.io.Serial
         private static final long serialVersionUID = -1034234728574286014L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final Map<? extends K, ? extends V> m;
 
         UnmodifiableMap(Map<? extends K, ? extends V> m) {
@@ -1809,6 +1814,7 @@
         @java.io.Serial
         private static final long serialVersionUID = -8806743815996713206L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final SortedMap<K, ? extends V> sm;
 
         UnmodifiableSortedMap(SortedMap<K, ? extends V> m) {super(m); sm = m; }
@@ -1886,6 +1892,7 @@
         /**
          * The instance we wrap and protect.
          */
+        @SuppressWarnings("serial") // Conditionally serializable
         private final NavigableMap<K, ? extends V> nm;
 
         UnmodifiableNavigableMap(NavigableMap<K, ? extends V> m)
@@ -2017,7 +2024,9 @@
         @java.io.Serial
         private static final long serialVersionUID = 3053995032091335093L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         final Collection<E> c;  // Backing Collection
+        @SuppressWarnings("serial") // Conditionally serializable
         final Object mutex;     // Object on which to synchronize
 
         SynchronizedCollection(Collection<E> c) {
@@ -2219,6 +2228,7 @@
         @java.io.Serial
         private static final long serialVersionUID = 8695801310862127406L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final SortedSet<E> ss;
 
         SynchronizedSortedSet(SortedSet<E> s) {
@@ -2314,6 +2324,7 @@
         @java.io.Serial
         private static final long serialVersionUID = -5505529816273629798L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final NavigableSet<E> ns;
 
         SynchronizedNavigableSet(NavigableSet<E> s) {
@@ -2424,6 +2435,7 @@
         @java.io.Serial
         private static final long serialVersionUID = -7754090372962971524L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         final List<E> list;
 
         SynchronizedList(List<E> list) {
@@ -2591,7 +2603,9 @@
         @java.io.Serial
         private static final long serialVersionUID = 1978198479659022715L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final Map<K,V> m;     // Backing Map
+        @SuppressWarnings("serial") // Conditionally serializable
         final Object      mutex;        // Object on which to synchronize
 
         SynchronizedMap(Map<K,V> m) {
@@ -2788,6 +2802,7 @@
         @java.io.Serial
         private static final long serialVersionUID = -8798146769416483793L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final SortedMap<K,V> sm;
 
         SynchronizedSortedMap(SortedMap<K,V> m) {
@@ -2891,6 +2906,7 @@
         @java.io.Serial
         private static final long serialVersionUID = 699392247599746807L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final NavigableMap<K,V> nm;
 
         SynchronizedNavigableMap(NavigableMap<K,V> m) {
@@ -3070,7 +3086,9 @@
         @java.io.Serial
         private static final long serialVersionUID = 1578914078182001775L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         final Collection<E> c;
+        @SuppressWarnings("serial") // Conditionally serializable
         final Class<E> type;
 
         @SuppressWarnings("unchecked")
@@ -3126,6 +3144,7 @@
 
         public boolean add(E e)          { return c.add(typeCheck(e)); }
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private E[] zeroLengthElementArray; // Lazily initialized
 
         private E[] zeroLengthElementArray() {
@@ -3219,6 +3238,7 @@
     {
         @java.io.Serial
         private static final long serialVersionUID = 1433151992604707767L;
+        @SuppressWarnings("serial") // Conditionally serializable
         final Queue<E> queue;
 
         CheckedQueue(Queue<E> queue, Class<E> elementType) {
@@ -3323,6 +3343,7 @@
         @java.io.Serial
         private static final long serialVersionUID = 1599911165492914959L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final SortedSet<E> ss;
 
         CheckedSortedSet(SortedSet<E> s, Class<E> type) {
@@ -3387,6 +3408,7 @@
         @java.io.Serial
         private static final long serialVersionUID = -5429120189805438922L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final NavigableSet<E> ns;
 
         CheckedNavigableSet(NavigableSet<E> s, Class<E> type) {
@@ -3470,6 +3492,7 @@
     {
         @java.io.Serial
         private static final long serialVersionUID = 65247728283967356L;
+        @SuppressWarnings("serial") // Conditionally serializable
         final List<E> list;
 
         CheckedList(List<E> list, Class<E> type) {
@@ -3619,8 +3642,11 @@
         @java.io.Serial
         private static final long serialVersionUID = 5742860141034234728L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final Map<K, V> m;
+        @SuppressWarnings("serial") // Conditionally serializable
         final Class<K> keyType;
+        @SuppressWarnings("serial") // Conditionally serializable
         final Class<V> valueType;
 
         private void typeCheck(Object key, Object value) {
@@ -4019,6 +4045,7 @@
         @java.io.Serial
         private static final long serialVersionUID = 1599671320688067438L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final SortedMap<K, V> sm;
 
         CheckedSortedMap(SortedMap<K, V> m,
@@ -4094,6 +4121,7 @@
         @java.io.Serial
         private static final long serialVersionUID = -4852462692372534096L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final NavigableMap<K, V> nm;
 
         CheckedNavigableMap(NavigableMap<K, V> m,
@@ -4825,6 +4853,7 @@
         @java.io.Serial
         private static final long serialVersionUID = 3193687207550431679L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final E element;
 
         SingletonSet(E e) {element = e;}
@@ -4879,6 +4908,7 @@
         @java.io.Serial
         private static final long serialVersionUID = 3093736618740652951L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final E element;
 
         SingletonList(E obj)                {element = obj;}
@@ -4948,7 +4978,9 @@
         @java.io.Serial
         private static final long serialVersionUID = -6979724477215052911L;
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final K k;
+        @SuppressWarnings("serial") // Conditionally serializable
         private final V v;
 
         SingletonMap(K key, V value) {
@@ -5087,6 +5119,7 @@
         private static final long serialVersionUID = 2739099268398711800L;
 
         final int n;
+        @SuppressWarnings("serial") // Conditionally serializable
         final E element;
 
         CopiesList(int n, E e) {
@@ -5320,6 +5353,7 @@
          *
          * @serial
          */
+        @SuppressWarnings("serial") // Conditionally serializable
         final Comparator<T> cmp;
 
         ReverseComparator2(Comparator<T> cmp) {
@@ -5601,6 +5635,7 @@
     private static class SetFromMap<E> extends AbstractSet<E>
         implements Set<E>, Serializable
     {
+        @SuppressWarnings("serial") // Conditionally serializable
         private final Map<E, Boolean> m;  // The backing map
         private transient Set<E> s;       // Its keySet
 
@@ -5686,6 +5721,7 @@
         implements Queue<E>, Serializable {
         @java.io.Serial
         private static final long serialVersionUID = 1802017725587941708L;
+        @SuppressWarnings("serial") // Conditionally serializable
         private final Deque<E> q;
         AsLIFOQueue(Deque<E> q)                     { this.q = q; }
         public boolean add(E e)                     { q.addFirst(e); return true; }
--- a/src/java.base/share/classes/java/util/Comparators.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/Comparators.java	Thu Oct 10 10:57:42 2019 -0400
@@ -66,6 +66,7 @@
         private static final long serialVersionUID = -7569533591570686392L;
         private final boolean nullFirst;
         // if null, non-null Ts are considered equal
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         private final Comparator<T> real;
 
         @SuppressWarnings("unchecked")
--- a/src/java.base/share/classes/java/util/PriorityQueue.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/PriorityQueue.java	Thu Oct 10 10:57:42 2019 -0400
@@ -111,6 +111,7 @@
      * The comparator, or null if priority queue uses elements'
      * natural ordering.
      */
+    @SuppressWarnings("serial") // Conditionally serializable
     private final Comparator<? super E> comparator;
 
     /**
--- a/src/java.base/share/classes/java/util/TreeMap.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/TreeMap.java	Thu Oct 10 10:57:42 2019 -0400
@@ -118,6 +118,7 @@
      *
      * @serial
      */
+    @SuppressWarnings("serial") // Conditionally serializable
     private final Comparator<? super K> comparator;
 
     private transient Entry<K,V> root;
@@ -1353,7 +1354,10 @@
          * if loInclusive is true, lo is the inclusive bound, else lo
          * is the exclusive bound. Similarly for the upper bound.
          */
-        final K lo, hi;
+        @SuppressWarnings("serial") // Conditionally serializable
+        final K lo;
+        @SuppressWarnings("serial") // Conditionally serializable
+        final K hi;
         final boolean fromStart, toEnd;
         final boolean loInclusive, hiInclusive;
 
@@ -1936,6 +1940,7 @@
             super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
         }
 
+        @SuppressWarnings("serial") // Conditionally serializable
         private final Comparator<? super K> reverseComparator =
             Collections.reverseOrder(m.comparator);
 
@@ -2024,7 +2029,10 @@
         @java.io.Serial
         private static final long serialVersionUID = -6520786458950516097L;
         private boolean fromStart = false, toEnd = false;
-        private K fromKey, toKey;
+        @SuppressWarnings("serial") // Conditionally serializable
+        private K fromKey;
+        @SuppressWarnings("serial") // Conditionally serializable
+        private K toKey;
         @java.io.Serial
         private Object readResolve() {
             return new AscendingSubMap<>(TreeMap.this,
--- a/src/java.base/share/classes/java/util/Vector.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/Vector.java	Thu Oct 10 10:57:42 2019 -0400
@@ -102,6 +102,7 @@
      *
      * @serial
      */
+    @SuppressWarnings("serial") // Conditionally serializable
     protected Object[] elementData;
 
     /**
--- a/src/java.base/share/classes/java/util/jar/JarVerifier.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/jar/JarVerifier.java	Thu Oct 10 10:57:42 2019 -0400
@@ -590,6 +590,7 @@
         URL vlocation;
         CodeSigner[] vsigners;
         java.security.cert.Certificate[] vcerts;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         Object csdomain;
 
         VerifierCodeSource(Object csdomain, URL location, CodeSigner[] signers) {
--- a/src/java.base/share/classes/java/util/stream/Collector.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/stream/Collector.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -33,6 +33,10 @@
 import java.util.function.Function;
 import java.util.function.Supplier;
 
+// A compilation test for the code snippets in this class-level javadoc can be found at:
+// test/jdk/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectorExample.java
+// The test needs to be updated if the examples in this javadoc change or new examples are added.
+
 /**
  * A <a href="package-summary.html#Reduction">mutable reduction operation</a> that
  * accumulates input elements into a mutable result container, optionally transforming
@@ -154,7 +158,7 @@
  * Performing a reduction operation with a {@code Collector} should produce a
  * result equivalent to:
  * <pre>{@code
- *     R container = collector.supplier().get();
+ *     A container = collector.supplier().get();
  *     for (T t : data)
  *         collector.accumulator().accept(container, t);
  *     return collector.finisher().apply(container);
--- a/src/java.base/share/classes/javax/crypto/CryptoPermission.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/javax/crypto/CryptoPermission.java	Thu Oct 10 10:57:42 2019 -0400
@@ -55,6 +55,7 @@
     private String alg;
     private int maxKeySize = Integer.MAX_VALUE; // no restriction on maxKeySize
     private String exemptionMechanism = null;
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private AlgorithmParameterSpec algParamSpec = null;
     private boolean checkParam = false; // no restriction on param
 
--- a/src/java.base/share/classes/javax/security/auth/PrivateCredentialPermission.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/javax/security/auth/PrivateCredentialPermission.java	Thu Oct 10 10:57:42 2019 -0400
@@ -119,6 +119,7 @@
      *          The set contains elements of type,
      *          {@code PrivateCredentialPermission.CredOwner}.
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private Set<Principal> principals;  // ignored - kept around for compatibility
     private transient CredOwner[] credOwners;
 
--- a/src/java.base/share/classes/javax/security/auth/Subject.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/javax/security/auth/Subject.java	Thu Oct 10 10:57:42 2019 -0400
@@ -111,6 +111,7 @@
      *          {@code java.security.Principal}.
      *          The set is a {@code Subject.SecureSet}.
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     Set<Principal> principals;
 
     /**
--- a/src/java.base/share/classes/javax/security/auth/callback/UnsupportedCallbackException.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/javax/security/auth/callback/UnsupportedCallbackException.java	Thu Oct 10 10:57:42 2019 -0400
@@ -39,6 +39,7 @@
     /**
      * @serial
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private Callback callback;
 
     /**
--- a/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java	Thu Oct 10 10:57:42 2019 -0400
@@ -49,6 +49,7 @@
     private static final long serialVersionUID = 100L;
     private static final PlatformLogger logger = HttpURLConnection.getHttpLogger();
 
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private final HttpCallerInfo hci;
 
     // These maps are used to manage the GSS availability for diffrent
@@ -67,6 +68,7 @@
     }
 
     // The HTTP Negotiate Helper
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private Negotiator negotiator = null;
 
    /**
--- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java	Thu Oct 10 10:57:42 2019 -0400
@@ -875,6 +875,11 @@
                     if (state == ST_CONNECTED)
                         throw new AlreadyConnectedException();
 
+                    // ensure that the socket is bound
+                    if (localAddress == null) {
+                        bindInternal(null);
+                    }
+
                     int n = Net.connect(family,
                                         fd,
                                         isa.getAddress(),
@@ -932,8 +937,21 @@
                     remoteAddress = null;
                     state = ST_UNCONNECTED;
 
-                    // refresh local address
-                    localAddress = Net.localAddress(fd);
+                    // check whether rebind is needed
+                    InetSocketAddress isa = Net.localAddress(fd);
+                    if (isa.getPort() == 0) {
+                        // On Linux, if bound to ephemeral port,
+                        // disconnect does not preserve that port.
+                        // In this case, try to rebind to the previous port.
+                        int port = localAddress.getPort();
+                        localAddress = isa; // in case Net.bind fails
+                        Net.bind(family, fd, isa.getAddress(), port);
+                        isa = Net.localAddress(fd); // refresh address
+                        assert isa.getPort() == port;
+                    }
+
+                    // refresh localAddress
+                    localAddress = isa;
                 }
             } finally {
                 writeLock.unlock();
--- a/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/nio/ch/SelectorImpl.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,9 @@
 import java.nio.channels.spi.AbstractSelectableChannel;
 import java.nio.channels.spi.AbstractSelector;
 import java.nio.channels.spi.SelectorProvider;
+import java.util.ArrayDeque;
 import java.util.Collections;
+import java.util.Deque;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Objects;
@@ -46,7 +48,7 @@
  * Base Selector implementation class.
  */
 
-abstract class SelectorImpl
+public abstract class SelectorImpl
     extends AbstractSelector
 {
     // The set of keys registered with this Selector
@@ -59,6 +61,9 @@
     private final Set<SelectionKey> publicKeys;             // Immutable
     private final Set<SelectionKey> publicSelectedKeys;     // Removal allowed, but not addition
 
+    // pending cancelled keys for deregistration
+    private final Deque<SelectionKeyImpl> cancelledKeys = new ArrayDeque<>();
+
     // used to check for reentrancy
     private boolean inSelect;
 
@@ -203,7 +208,8 @@
         if (!(ch instanceof SelChImpl))
             throw new IllegalSelectorException();
         SelectionKeyImpl k = new SelectionKeyImpl((SelChImpl)ch, this);
-        k.attach(attachment);
+        if (attachment != null)
+            k.attach(attachment);
 
         // register (if needed) before adding to key set
         implRegister(k);
@@ -239,33 +245,36 @@
     protected abstract void implDereg(SelectionKeyImpl ski) throws IOException;
 
     /**
-     * Invoked by selection operations to process the cancelled-key set
+     * Queue a cancelled key for the next selection operation
+     */
+    public void cancel(SelectionKeyImpl ski) {
+        synchronized (cancelledKeys) {
+            cancelledKeys.addLast(ski);
+        }
+    }
+
+    /**
+     * Invoked by selection operations to process the cancelled keys
      */
     protected final void processDeregisterQueue() throws IOException {
         assert Thread.holdsLock(this);
         assert Thread.holdsLock(publicSelectedKeys);
 
-        Set<SelectionKey> cks = cancelledKeys();
-        synchronized (cks) {
-            if (!cks.isEmpty()) {
-                Iterator<SelectionKey> i = cks.iterator();
-                while (i.hasNext()) {
-                    SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
-                    i.remove();
-
-                    // remove the key from the selector
-                    implDereg(ski);
+        synchronized (cancelledKeys) {
+            SelectionKeyImpl ski;
+            while ((ski = cancelledKeys.pollFirst()) != null) {
+                // remove the key from the selector
+                implDereg(ski);
 
-                    selectedKeys.remove(ski);
-                    keys.remove(ski);
+                selectedKeys.remove(ski);
+                keys.remove(ski);
 
-                    // remove from channel's key set
-                    deregister(ski);
+                // remove from channel's key set
+                deregister(ski);
 
-                    SelectableChannel ch = ski.channel();
-                    if (!ch.isOpen() && !ch.isRegistered())
-                        ((SelChImpl)ch).kill();
-                }
+                SelectableChannel ch = ski.channel();
+                if (!ch.isOpen() && !ch.isRegistered())
+                    ((SelChImpl)ch).kill();
             }
         }
     }
--- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java	Thu Oct 10 10:57:42 2019 -0400
@@ -44,6 +44,7 @@
     @java.io.Serial
     private static final long serialVersionUID = 6182022883658399397L;
     private final Class<? extends Annotation> type;
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private final Map<String, Object> memberValues;
 
     AnnotationInvocationHandler(Class<? extends Annotation> type, Map<String, Object> memberValues) {
--- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy.java	Thu Oct 10 10:57:42 2019 -0400
@@ -36,7 +36,8 @@
 class AnnotationTypeMismatchExceptionProxy extends ExceptionProxy {
     @java.io.Serial
     private static final long serialVersionUID = 7844069490309503934L;
-    private Method member;
+    @SuppressWarnings("serial") // Not statically typed as Serializable
+    private Method member; // Would be more robust to null-out in a writeObject method.
     private final String foundType;
 
     /**
--- a/src/java.base/share/classes/sun/security/internal/spec/TlsKeyMaterialSpec.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/internal/spec/TlsKeyMaterialSpec.java	Thu Oct 10 10:57:42 2019 -0400
@@ -50,7 +50,11 @@
 
     private final SecretKey clientMacKey, serverMacKey;
     private final SecretKey clientCipherKey, serverCipherKey;
-    private final IvParameterSpec clientIv, serverIv;
+
+    @SuppressWarnings("serial") // Not statically typed as Serializable
+    private final IvParameterSpec clientIv;
+    @SuppressWarnings("serial") // Not statically typed as Serializable
+    private final IvParameterSpec serverIv;
 
     /**
      * Constructs a new TlsKeymaterialSpec from the client and server MAC
--- a/src/java.base/share/classes/sun/security/provider/PolicyParser.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/provider/PolicyParser.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1315,7 +1315,9 @@
         private static final long serialVersionUID = -4330692689482574072L;
 
         private String i18nMessage;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         private LocalizedMessage localizedMsg;
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         private Object[] source;
 
         /**
--- a/src/java.base/share/classes/sun/security/provider/SubjectCodeSource.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/provider/SubjectCodeSource.java	Thu Oct 10 10:57:42 2019 -0400
@@ -54,6 +54,7 @@
     private static final Class<?>[] PARAMS = { String.class };
     private static final sun.security.util.Debug debug =
         sun.security.util.Debug.getInstance("auth", "\t[Auth Access]");
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private ClassLoader sysClassLoader;
 
     /**
--- a/src/java.base/share/classes/sun/security/provider/certpath/X509CertPath.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/provider/certpath/X509CertPath.java	Thu Oct 10 10:57:42 2019 -0400
@@ -69,6 +69,7 @@
     /**
      * List of certificates in this chain
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private List<X509Certificate> certs;
 
     /**
--- a/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/rsa/RSAPrivateCrtKeyImpl.java	Thu Oct 10 10:57:42 2019 -0400
@@ -70,6 +70,7 @@
     // Optional parameters associated with this RSA key
     // specified in the encoding of its AlgorithmId.
     // Must be null for "RSA" keys.
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private AlgorithmParameterSpec keyParams;
 
     /**
--- a/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/rsa/RSAPrivateKeyImpl.java	Thu Oct 10 10:57:42 2019 -0400
@@ -61,6 +61,7 @@
     // optional parameters associated with this RSA key
     // specified in the encoding of its AlgorithmId.
     // must be null for "RSA" keys.
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private final AlgorithmParameterSpec keyParams;
 
     /**
--- a/src/java.base/share/classes/sun/security/rsa/RSAPublicKeyImpl.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/rsa/RSAPublicKeyImpl.java	Thu Oct 10 10:57:42 2019 -0400
@@ -62,6 +62,7 @@
     // optional parameters associated with this RSA key
     // specified in the encoding of its AlgorithmId
     // must be null for "RSA" keys.
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private AlgorithmParameterSpec keyParams;
 
     /**
--- a/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/util/ObjectIdentifier.java	Thu Oct 10 10:57:42 2019 -0400
@@ -98,6 +98,7 @@
      * Changed to Object
      * @serial
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private Object      components   = null;          // path from root
     /**
      * @serial
--- a/src/java.base/share/classes/sun/security/validator/ValidatorException.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/validator/ValidatorException.java	Thu Oct 10 10:57:42 2019 -0400
@@ -62,6 +62,7 @@
     public static final Object T_UNTRUSTED_CERT =
         "Untrusted certificate";
 
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private Object type;
     private X509Certificate cert;
 
--- a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java	Thu Oct 10 10:57:42 2019 -0400
@@ -72,6 +72,7 @@
     private ObjectIdentifier algid;
 
     // The (parsed) parameters
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private AlgorithmParameters algParams;
     private boolean constructedFromDer = true;
 
@@ -80,6 +81,7 @@
      * DER-encoded form; subclasses can be made to automaticaly parse
      * them so there is fast access to these parameters.
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     protected DerValue          params;
 
 
--- a/src/java.base/share/classes/sun/security/x509/X509CertImpl.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/x509/X509CertImpl.java	Thu Oct 10 10:57:42 2019 -0400
@@ -70,6 +70,7 @@
  * @author Hemma Prafullchandra
  * @see X509CertInfo
  */
+@SuppressWarnings("serial") // See writeReplace method in Certificate
 public class X509CertImpl extends X509Certificate implements DerEncoder {
 
     @java.io.Serial
--- a/src/java.base/share/classes/sun/security/x509/X509Key.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/x509/X509Key.java	Thu Oct 10 10:57:42 2019 -0400
@@ -84,7 +84,7 @@
     private int unusedBits = 0;
 
     /* BitArray form of key */
-    private BitArray bitStringKey = null;
+    private transient BitArray bitStringKey = null;
 
     /* The encoding for the key. */
     protected byte[] encodedKey;
--- a/src/java.base/share/native/libjava/Class.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/native/libjava/Class.c	Thu Oct 10 10:57:42 2019 -0400
@@ -35,12 +35,9 @@
 #include "jni.h"
 #include "jni_util.h"
 #include "jvm.h"
+#include "check_classname.h"
 #include "java_lang_Class.h"
 
-/* defined in libverify.so/verify.dll (src file common/check_format.c) */
-extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed);
-extern jboolean VerifyFixClassname(char *utf_name);
-
 #define OBJ "Ljava/lang/Object;"
 #define CLS "Ljava/lang/Class;"
 #define CPL "Ljdk/internal/reflect/ConstantPool;"
@@ -123,14 +120,14 @@
     }
     (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);
 
-    if (VerifyFixClassname(clname) == JNI_TRUE) {
+    if (verifyFixClassname(clname) == JNI_TRUE) {
         /* slashes present in clname, use name b4 translation for exception */
         (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);
         JNU_ThrowClassNotFoundException(env, clname);
         goto done;
     }
 
-    if (!VerifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */
+    if (!verifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */
         JNU_ThrowClassNotFoundException(env, clname);
         goto done;
     }
--- a/src/java.base/share/native/libjava/ClassLoader.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/native/libjava/ClassLoader.c	Thu Oct 10 10:57:42 2019 -0400
@@ -30,14 +30,11 @@
 #include "jni_util.h"
 #include "jlong.h"
 #include "jvm.h"
+#include "check_classname.h"
 #include "java_lang_ClassLoader.h"
 #include "java_lang_ClassLoader_NativeLibrary.h"
 #include <string.h>
 
-/* defined in libverify.so/verify.dll (src file common/check_format.c) */
-extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed);
-extern jboolean VerifyFixClassname(char *utf_name);
-
 static JNINativeMethod methods[] = {
     {"retrieveDirectives",  "()Ljava/lang/AssertionStatusDirectives;", (void *)&JVM_AssertionStatusDirectives}
 };
@@ -120,7 +117,7 @@
         if (utfName == NULL) {
             goto free_body;
         }
-        VerifyFixClassname(utfName);
+        fixClassname(utfName);
     } else {
         utfName = NULL;
     }
@@ -185,7 +182,7 @@
             JNU_ThrowOutOfMemoryError(env, NULL);
             return result;
         }
-        VerifyFixClassname(utfName);
+        fixClassname(utfName);
     } else {
         utfName = NULL;
     }
@@ -231,9 +228,9 @@
         JNU_ThrowOutOfMemoryError(env, NULL);
         return NULL;
     }
-    VerifyFixClassname(clname);
+    fixClassname(clname);
 
-    if (!VerifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */
+    if (!verifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */
         goto done;
     }
 
--- a/src/java.base/share/native/libjava/VM.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/native/libjava/VM.c	Thu Oct 10 10:57:42 2019 -0400
@@ -42,11 +42,6 @@
 
 JNIEXPORT void JNICALL
 Java_jdk_internal_misc_VM_initialize(JNIEnv *env, jclass cls) {
-    if (!JDK_InitJvmHandle()) {
-        JNU_ThrowInternalError(env, "Handle for JVM not found for symbol lookup");
-        return;
-    }
-
     // Registers implementations of native methods described in methods[]
     // above.
     // In particular, registers JVM_GetNanoTimeAdjustment as the implementation
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/native/libjava/check_classname.c	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,292 @@
+/*
+ * 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "jni.h"
+#include "jvm.h"
+#include "check_classname.h"
+
+typedef unsigned short unicode;
+
+static char *
+skip_over_fieldname(char *name, jboolean slash_okay,
+                    unsigned int len);
+static char *
+skip_over_field_signature(char *name, jboolean void_okay,
+                          unsigned int len);
+
+/*
+ * Return non-zero if the character is a valid in JVM class name, zero
+ * otherwise.  The only characters currently disallowed from JVM class
+ * names are given in the table below:
+ *
+ * Character    Hex     Decimal
+ * '.'          0x2e    46
+ * '/'          0x2f    47
+ * ';'          0x3b    59
+ * '['          0x5b    91
+ *
+ * (Method names have further restrictions dealing with the '<' and
+ * '>' characters.)
+ */
+static int isJvmIdentifier(unicode ch) {
+  if( ch > 91 || ch < 46 )
+    return 1;   /* Lowercase ASCII letters are > 91 */
+  else { /* 46 <= ch <= 91 */
+    if (ch <= 90 && ch >= 60) {
+      return 1; /* Uppercase ASCII recognized here */
+    } else { /* ch == 91 || 46 <= ch <= 59 */
+      if (ch == 91 || ch == 59 || ch <= 47)
+        return 0;
+      else
+        return 1;
+    }
+  }
+}
+
+static unicode
+next_utf2unicode(char **utfstring_ptr, int * valid)
+{
+    unsigned char *ptr = (unsigned char *)(*utfstring_ptr);
+    unsigned char ch, ch2, ch3;
+    int length = 1;             /* default length */
+    unicode result = 0x80;      /* default bad result; */
+    *valid = 1;
+    switch ((ch = ptr[0]) >> 4) {
+        default:
+            result = ch;
+            break;
+
+        case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
+            /* Shouldn't happen. */
+            *valid = 0;
+            break;
+
+        case 0xC: case 0xD:
+            /* 110xxxxx  10xxxxxx */
+            if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
+                unsigned char high_five = ch & 0x1F;
+                unsigned char low_six = ch2 & 0x3F;
+                result = (high_five << 6) + low_six;
+                length = 2;
+            }
+            break;
+
+        case 0xE:
+            /* 1110xxxx 10xxxxxx 10xxxxxx */
+            if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
+                if (((ch3 = ptr[2]) & 0xC0) == 0x80) {
+                    unsigned char high_four = ch & 0x0f;
+                    unsigned char mid_six = ch2 & 0x3f;
+                    unsigned char low_six = ch3 & 0x3f;
+                    result = (((high_four << 6) + mid_six) << 6) + low_six;
+                    length = 3;
+                } else {
+                    length = 2;
+                }
+            }
+            break;
+        } /* end of switch */
+
+    *utfstring_ptr = (char *)(ptr + length);
+    return result;
+}
+
+/* Take pointer to a string.  Skip over the longest part of the string that
+ * could be taken as a fieldname.  Allow '/' if slash_okay is JNI_TRUE.
+ *
+ * Return a pointer to just past the fieldname.  Return NULL if no fieldname
+ * at all was found, or in the case of slash_okay being true, we saw
+ * consecutive slashes (meaning we were looking for a qualified path but
+ * found something that was badly-formed).
+ */
+static char *
+skip_over_fieldname(char *name, jboolean slash_okay,
+                    unsigned int length)
+{
+    char *p;
+    unicode ch;
+    unicode last_ch = 0;
+    int valid = 1;
+    /* last_ch == 0 implies we are looking at the first char. */
+    for (p = name; p != name + length; last_ch = ch) {
+        char *old_p = p;
+        ch = *p;
+        if (ch < 128) {
+            p++;
+            if (isJvmIdentifier(ch)) {
+                continue;
+            }
+        } else {
+            char *tmp_p = p;
+            ch = next_utf2unicode(&tmp_p, &valid);
+            if (valid == 0)
+              return 0;
+            p = tmp_p;
+            if (isJvmIdentifier(ch)) {
+                        continue;
+            }
+        }
+
+        if (slash_okay && ch == '/' && last_ch) {
+            if (last_ch == '/') {
+                return 0;       /* Don't permit consecutive slashes */
+            }
+        } else if (ch == '_' || ch == '$') {
+        } else {
+            return last_ch ? old_p : 0;
+        }
+    }
+    return last_ch ? p : 0;
+}
+
+/* Take pointer to a string.  Skip over the longest part of the string that
+ * could be taken as a field signature.  Allow "void" if void_okay.
+ *
+ * Return a pointer to just past the signature.  Return NULL if no legal
+ * signature is found.
+ */
+
+static char *
+skip_over_field_signature(char *name, jboolean void_okay,
+                          unsigned int length)
+{
+    unsigned int array_dim = 0;
+    for (;length > 0;) {
+        switch (name[0]) {
+            case JVM_SIGNATURE_VOID:
+                if (!void_okay) return 0;
+                /* FALL THROUGH */
+            case JVM_SIGNATURE_BOOLEAN:
+            case JVM_SIGNATURE_BYTE:
+            case JVM_SIGNATURE_CHAR:
+            case JVM_SIGNATURE_SHORT:
+            case JVM_SIGNATURE_INT:
+            case JVM_SIGNATURE_FLOAT:
+            case JVM_SIGNATURE_LONG:
+            case JVM_SIGNATURE_DOUBLE:
+                return name + 1;
+
+            case JVM_SIGNATURE_CLASS: {
+                /* Skip over the classname, if one is there. */
+                char *p =
+                    skip_over_fieldname(name + 1, JNI_TRUE, --length);
+                /* The next character better be a semicolon. */
+                if (p && p - name - 1 > 0 && p[0] == ';')
+                    return p + 1;
+                return 0;
+            }
+
+            case JVM_SIGNATURE_ARRAY:
+                array_dim++;
+                /* JVMS 2nd ed. 4.10 */
+                /*   The number of dimensions in an array is limited to 255 ... */
+                if (array_dim > 255) {
+                    return 0;
+                }
+                /* The rest of what's there better be a legal signature.  */
+                name++;
+                length--;
+                void_okay = JNI_FALSE;
+                break;
+
+            default:
+                return 0;
+        }
+    }
+    return 0;
+}
+
+/* Determine if the specified name is legal
+ * UTF name for a classname.
+ *
+ * Note that this routine expects the internal form of qualified classes:
+ * the dots should have been replaced by slashes.
+ */
+jboolean verifyClassname(char *name, jboolean allowArrayClass)
+{
+    size_t s = strlen(name);
+    assert(s <= UINT_MAX);
+    unsigned int length = (unsigned int)s;
+    char *p;
+
+    if (length > 0 && name[0] == JVM_SIGNATURE_ARRAY) {
+        if (!allowArrayClass) {
+            return JNI_FALSE;
+        } else {
+            /* Everything that's left better be a field signature */
+            p = skip_over_field_signature(name, JNI_FALSE, length);
+        }
+    } else {
+        /* skip over the fieldname.  Slashes are okay */
+        p = skip_over_fieldname(name, JNI_TRUE, length);
+    }
+    return (p != 0 && p - name == (ptrdiff_t)length);
+}
+
+/*
+ * Translates '.' to '/'.  Returns JNI_TRUE if any / were present.
+ */
+jboolean verifyFixClassname(char *name)
+{
+    char *p = name;
+    jboolean slashesFound = JNI_FALSE;
+    int valid = 1;
+
+    while (valid != 0 && *p != '\0') {
+        if (*p == '/') {
+            slashesFound = JNI_TRUE;
+            p++;
+        } else if (*p == '.') {
+            *p++ = '/';
+        } else {
+            next_utf2unicode(&p, &valid);
+        }
+    }
+
+    return slashesFound && valid != 0;
+}
+
+/*
+ * Translates '.' to '/'.
+ */
+void fixClassname(char *name)
+{
+    char *p = name;
+    int valid = 1;
+
+    while (valid != 0 && *p != '\0') {
+        if (*p == '.') {
+            *p++ = '/';
+        } else {
+            next_utf2unicode(&p, &valid);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/native/libjava/check_classname.h	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+
+/*
+ * Class name checking methods
+ */
+
+jboolean verifyClassname(char *name, jboolean allowArrayClass);
+jboolean verifyFixClassname(char *name);
+void fixClassname(char *name);
--- a/src/java.base/share/native/libjava/jdk_util.h	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/native/libjava/jdk_util.h	Thu Oct 10 10:57:42 2019 -0400
@@ -45,20 +45,6 @@
 JNIEXPORT void
 JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size);
 
-
-/*-------------------------------------------------------
- * Internal interface for JDK to use
- *-------------------------------------------------------
- */
-
-/* Init JVM handle for symbol lookup;
- * Return 0 if JVM handle not found.
- */
-int JDK_InitJvmHandle();
-
-/* Find the named JVM entry; returns NULL if not found. */
-void* JDK_FindJvmEntry(const char* name);
-
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* __cplusplus */
--- a/src/java.base/share/native/libjava/jni_util.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/native/libjava/jni_util.c	Thu Oct 10 10:57:42 2019 -0400
@@ -77,77 +77,23 @@
 }
 
 JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/IllegalAccessError", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/IllegalAccessException", msg);
-}
-
-JNIEXPORT void JNICALL
 JNU_ThrowInternalError(JNIEnv *env, const char *msg)
 {
     JNU_ThrowByName(env, "java/lang/InternalError", msg);
 }
 
 JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/NoSuchFieldException", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/NoSuchMethodException", msg);
-}
-
-JNIEXPORT void JNICALL
 JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg)
 {
     JNU_ThrowByName(env, "java/lang/ClassNotFoundException", msg);
 }
 
 JNIEXPORT void JNICALL
-JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/NumberFormatException", msg);
-}
-
-JNIEXPORT void JNICALL
 JNU_ThrowIOException(JNIEnv *env, const char *msg)
 {
     JNU_ThrowByName(env, "java/io/IOException", msg);
 }
 
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/NoSuchFieldError", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/NoSuchMethodError", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/StringIndexOutOfBoundsException", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowInstantiationException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/InstantiationException", msg);
-}
-
 /*
  * Throw an exception by name, using the string returned by
  * getLastErrorString for the detail string. If the last-error
@@ -845,12 +791,6 @@
     CHECK_NULL(String_value_ID);
 }
 
-JNIEXPORT jstring
-NewStringPlatform(JNIEnv *env, const char *str)
-{
-    return JNU_NewStringPlatform(env, str);
-}
-
 JNIEXPORT jstring JNICALL
 JNU_NewStringPlatform(JNIEnv *env, const char *str)
 {
@@ -1024,54 +964,6 @@
     return cls;
 }
 
-JNIEXPORT jclass JNICALL
-JNU_ClassClass(JNIEnv *env)
-{
-    static jclass cls = 0;
-    if (cls == 0) {
-        jclass c;
-        if ((*env)->EnsureLocalCapacity(env, 1) < 0)
-            return 0;
-        c = (*env)->FindClass(env, "java/lang/Class");
-        CHECK_NULL_RETURN(c, NULL);
-        cls = (*env)->NewGlobalRef(env, c);
-        (*env)->DeleteLocalRef(env, c);
-    }
-    return cls;
-}
-
-JNIEXPORT jclass JNICALL
-JNU_ClassObject(JNIEnv *env)
-{
-    static jclass cls = 0;
-    if (cls == 0) {
-        jclass c;
-        if ((*env)->EnsureLocalCapacity(env, 1) < 0)
-            return 0;
-        c = (*env)->FindClass(env, "java/lang/Object");
-        CHECK_NULL_RETURN(c, NULL);
-        cls = (*env)->NewGlobalRef(env, c);
-        (*env)->DeleteLocalRef(env, c);
-    }
-    return cls;
-}
-
-JNIEXPORT jclass JNICALL
-JNU_ClassThrowable(JNIEnv *env)
-{
-    static jclass cls = 0;
-    if (cls == 0) {
-        jclass c;
-        if ((*env)->EnsureLocalCapacity(env, 1) < 0)
-            return 0;
-        c = (*env)->FindClass(env, "java/lang/Throwable");
-        CHECK_NULL_RETURN(c, NULL);
-        cls = (*env)->NewGlobalRef(env, c);
-        (*env)->DeleteLocalRef(env, c);
-    }
-    return cls;
-}
-
 JNIEXPORT jint JNICALL
 JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
                          jint count)
@@ -1110,125 +1002,10 @@
     return JNI_ERR;
 }
 
-JNIEXPORT jboolean JNICALL
-JNU_Equals(JNIEnv *env, jobject object1, jobject object2)
-{
-    static jmethodID mid = NULL;
-    if (mid == NULL) {
-        jclass objClazz = JNU_ClassObject(env);
-        CHECK_NULL_RETURN(objClazz, JNI_FALSE);
-        mid = (*env)->GetMethodID(env, objClazz, "equals",
-                                  "(Ljava/lang/Object;)Z");
-        CHECK_NULL_RETURN(mid, JNI_FALSE);
-    }
-    return (*env)->CallBooleanMethod(env, object1, mid, object2);
-}
-
-
-/************************************************************************
- * Thread calls
- */
-
-static jmethodID Object_waitMID;
-static jmethodID Object_notifyMID;
-static jmethodID Object_notifyAllMID;
-
-JNIEXPORT void JNICALL
-JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout)
-{
-    if (object == NULL) {
-        JNU_ThrowNullPointerException(env, "JNU_MonitorWait argument");
-        return;
-    }
-    if (Object_waitMID == NULL) {
-        jclass cls = JNU_ClassObject(env);
-        if (cls == NULL) {
-            return;
-        }
-        Object_waitMID = (*env)->GetMethodID(env, cls, "wait", "(J)V");
-        if (Object_waitMID == NULL) {
-            return;
-        }
-    }
-    (*env)->CallVoidMethod(env, object, Object_waitMID, timeout);
-}
-
-JNIEXPORT void JNICALL
-JNU_Notify(JNIEnv *env, jobject object)
-{
-    if (object == NULL) {
-        JNU_ThrowNullPointerException(env, "JNU_Notify argument");
-        return;
-    }
-    if (Object_notifyMID == NULL) {
-        jclass cls = JNU_ClassObject(env);
-        if (cls == NULL) {
-            return;
-        }
-        Object_notifyMID = (*env)->GetMethodID(env, cls, "notify", "()V");
-        if (Object_notifyMID == NULL) {
-            return;
-        }
-    }
-    (*env)->CallVoidMethod(env, object, Object_notifyMID);
-}
-
-JNIEXPORT void JNICALL
-JNU_NotifyAll(JNIEnv *env, jobject object)
-{
-    if (object == NULL) {
-        JNU_ThrowNullPointerException(env, "JNU_NotifyAll argument");
-        return;
-    }
-    if (Object_notifyAllMID == NULL) {
-        jclass cls = JNU_ClassObject(env);
-        if (cls == NULL) {
-            return;
-        }
-        Object_notifyAllMID = (*env)->GetMethodID(env, cls,"notifyAll", "()V");
-        if (Object_notifyAllMID == NULL) {
-            return;
-        }
-    }
-    (*env)->CallVoidMethod(env, object, Object_notifyAllMID);
-}
-
-
 /************************************************************************
  * Debugging utilities
  */
 
-JNIEXPORT void JNICALL
-JNU_PrintString(JNIEnv *env, char *hdr, jstring string)
-{
-    if (string == NULL) {
-        fprintf(stderr, "%s: is NULL\n", hdr);
-    } else {
-        const char *stringPtr = JNU_GetStringPlatformChars(env, string, 0);
-        if (stringPtr == 0)
-            return;
-        fprintf(stderr, "%s: %s\n", hdr, stringPtr);
-        JNU_ReleaseStringPlatformChars(env, string, stringPtr);
-    }
-}
-
-JNIEXPORT void JNICALL
-JNU_PrintClass(JNIEnv *env, char* hdr, jobject object)
-{
-    if (object == NULL) {
-        fprintf(stderr, "%s: object is NULL\n", hdr);
-        return;
-    } else {
-        jclass cls = (*env)->GetObjectClass(env, object);
-        jstring clsName = JNU_ToString(env, cls);
-        if (clsName == NULL) {
-            JNU_PrintString(env, hdr, clsName);
-        }
-        (*env)->DeleteLocalRef(env, cls);
-        (*env)->DeleteLocalRef(env, clsName);
-    }
-}
-
 JNIEXPORT jstring JNICALL
 JNU_ToString(JNIEnv *env, jobject object)
 {
@@ -1437,70 +1214,3 @@
     }
     return result;
 }
-
-JNIEXPORT void JNICALL
-JNU_SetStaticFieldByName(JNIEnv *env,
-                         jboolean *hasException,
-                         const char *classname,
-                         const char *name,
-                         const char *signature,
-                         ...)
-{
-    jclass cls;
-    jfieldID fid;
-    va_list args;
-
-    if ((*env)->EnsureLocalCapacity(env, 3) < 0)
-        goto done2;
-
-    cls = (*env)->FindClass(env, classname);
-    if (cls == 0)
-        goto done2;
-
-    fid = (*env)->GetStaticFieldID(env, cls, name, signature);
-    if (fid == 0)
-        goto done1;
-
-    va_start(args, signature);
-    switch (*signature) {
-    case '[':
-    case 'L':
-        (*env)->SetStaticObjectField(env, cls, fid, va_arg(args, jobject));
-        break;
-    case 'Z':
-        (*env)->SetStaticBooleanField(env, cls, fid, (jboolean)va_arg(args, int));
-        break;
-    case 'B':
-        (*env)->SetStaticByteField(env, cls, fid, (jbyte)va_arg(args, int));
-        break;
-    case 'C':
-        (*env)->SetStaticCharField(env, cls, fid, (jchar)va_arg(args, int));
-        break;
-    case 'S':
-        (*env)->SetStaticShortField(env, cls, fid, (jshort)va_arg(args, int));
-        break;
-    case 'I':
-        (*env)->SetStaticIntField(env, cls, fid, va_arg(args, jint));
-        break;
-    case 'J':
-        (*env)->SetStaticLongField(env, cls, fid, va_arg(args, jlong));
-        break;
-    case 'F':
-        (*env)->SetStaticFloatField(env, cls, fid, (jfloat)va_arg(args, jdouble));
-        break;
-    case 'D':
-        (*env)->SetStaticDoubleField(env, cls, fid, va_arg(args, jdouble));
-        break;
-
-    default:
-        (*env)->FatalError(env, "JNU_SetStaticFieldByName: illegal signature");
-    }
-    va_end(args);
-
- done1:
-    (*env)->DeleteLocalRef(env, cls);
- done2:
-    if (hasException) {
-        *hasException = (*env)->ExceptionCheck(env);
-    }
-}
--- a/src/java.base/share/native/libjava/jni_util.h	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/native/libjava/jni_util.h	Thu Oct 10 10:57:42 2019 -0400
@@ -62,41 +62,14 @@
 JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg);
 
 JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
 JNU_ThrowInternalError(JNIEnv *env, const char *msg);
 
 JNIEXPORT void JNICALL
 JNU_ThrowIOException(JNIEnv *env, const char *msg);
 
 JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
 JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg);
 
-JNIEXPORT void JNICALL
-JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowInstantiationException(JNIEnv *env, const char *msg);
-
 /* Throw an exception by name, using the string returned by
  * getLastErrorString for the detail string. If the last-error
  * string is NULL, use the given default detail string.
@@ -120,9 +93,6 @@
 JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail);
 
 /* Convert between Java strings and i18n C strings */
-JNIEXPORT jstring
-NewStringPlatform(JNIEnv *env, const char *str);
-
 JNIEXPORT const char *
 GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
 
@@ -139,15 +109,6 @@
 JNIEXPORT jclass JNICALL
 JNU_ClassString(JNIEnv *env);
 
-JNIEXPORT jclass JNICALL
-JNU_ClassClass(JNIEnv *env);
-
-JNIEXPORT jclass JNICALL
-JNU_ClassObject(JNIEnv *env);
-
-JNIEXPORT jclass JNICALL
-JNU_ClassThrowable(JNIEnv *env);
-
 /* Copy count number of arguments from src to dst. Array bounds
  * and ArrayStoreException are checked.
  */
@@ -246,36 +207,6 @@
                          const char *classname,
                          const char *name,
                          const char *sig);
-JNIEXPORT void JNICALL
-JNU_SetStaticFieldByName(JNIEnv *env,
-                         jboolean *hasException,
-                         const char *classname,
-                         const char *name,
-                         const char *sig,
-                         ...);
-
-
-/*
- * Calls the .equals method.
- */
-JNIEXPORT jboolean JNICALL
-JNU_Equals(JNIEnv *env, jobject object1, jobject object2);
-
-
-/************************************************************************
- * Thread calls
- *
- * Convenience thread-related calls on the java.lang.Object class.
- */
-
-JNIEXPORT void JNICALL
-JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout);
-
-JNIEXPORT void JNICALL
-JNU_Notify(JNIEnv *env, jobject object);
-
-JNIEXPORT void JNICALL
-JNU_NotifyAll(JNIEnv *env, jobject object);
 
 
 /************************************************************************
@@ -349,19 +280,15 @@
         }                                       \
     } while (0)
 #endif /* __cplusplus */
+
 /************************************************************************
  * Debugging utilities
  */
 
-JNIEXPORT void JNICALL
-JNU_PrintString(JNIEnv *env, char *hdr, jstring string);
-
-JNIEXPORT void JNICALL
-JNU_PrintClass(JNIEnv *env, char *hdr, jobject object);
-
 JNIEXPORT jstring JNICALL
 JNU_ToString(JNIEnv *env, jobject object);
 
+
 /*
  * Package shorthand for use by native libraries
  */
@@ -402,8 +329,6 @@
     FAST_UTF_8
 };
 
-int getFastEncoding();
-
 JNIEXPORT void InitializeEncoding(JNIEnv *env, const char *name);
 
 void* getProcessHandle();
--- a/src/java.base/share/native/libjava/verify_stub.c	Wed Oct 09 10:58:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * The real verifier now lives in libverifier.so/verifier.dll.
- *
- * This dummy exists so that HotSpot will run with the new
- * libjava.so/java.dll which is where is it accustomed to finding the
- * verifier.
- */
-
-#include "jni.h"
-
-struct struct_class_size_info;
-typedef struct struct_class_size_info class_size_info;
-
-
-JNIIMPORT jboolean
-VerifyClass(JNIEnv *env, jclass cb, char *buffer, jint len);
-
-JNIIMPORT jboolean
-VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *buffer, jint len,
-                           jint major_version);
-
-JNIEXPORT jboolean
-VerifyClassCodes(JNIEnv *env, jclass cb, char *buffer, jint len)
-{
-    return VerifyClass(env, cb, buffer, len);
-}
-
-JNIEXPORT jboolean
-VerifyClassCodesForMajorVersion(JNIEnv *env, jclass cb, char *buffer,
-                                jint len, jint major_version)
-{
-    return VerifyClassForMajorVersion(env, cb, buffer, len, major_version);
-}
--- a/src/java.base/share/native/libverify/check_code.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/native/libverify/check_code.c	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,9 +31,6 @@
    Exported function:
 
    jboolean
-   VerifyClass(JNIEnv *env, jclass cb, char *message_buffer,
-               jint buffer_length)
-   jboolean
    VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *message_buffer,
                               jint buffer_length, jint major_version)
 
@@ -910,20 +907,6 @@
     return result;
 }
 
-#define OLD_FORMAT_MAX_MAJOR_VERSION 48
-
-JNIEXPORT jboolean
-VerifyClass(JNIEnv *env, jclass cb, char *buffer, jint len)
-{
-    static int warned = 0;
-    if (!warned) {
-      jio_fprintf(stdout, "Warning! An old version of jvm is used. This is not supported.\n");
-      warned = 1;
-    }
-    return VerifyClassForMajorVersion(env, cb, buffer, len,
-                                      OLD_FORMAT_MAX_MAJOR_VERSION);
-}
-
 static void
 verify_field(context_type *context, jclass cb, int field_index)
 {
--- a/src/java.base/share/native/libverify/check_format.c	Wed Oct 09 10:58:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <assert.h>
-#include <limits.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "jni.h"
-#include "jvm.h"
-
-typedef unsigned short unicode;
-
-static char *
-skip_over_fieldname(char *name, jboolean slash_okay,
-                    unsigned int len);
-static char *
-skip_over_field_signature(char *name, jboolean void_okay,
-                          unsigned int len);
-
-/*
- * Return non-zero if the character is a valid in JVM class name, zero
- * otherwise.  The only characters currently disallowed from JVM class
- * names are given in the table below:
- *
- * Character    Hex     Decimal
- * '.'          0x2e    46
- * '/'          0x2f    47
- * ';'          0x3b    59
- * '['          0x5b    91
- *
- * (Method names have further restrictions dealing with the '<' and
- * '>' characters.)
- */
-static int isJvmIdentifier(unicode ch) {
-  if( ch > 91 || ch < 46 )
-    return 1;   /* Lowercase ASCII letters are > 91 */
-  else { /* 46 <= ch <= 91 */
-    if (ch <= 90 && ch >= 60) {
-      return 1; /* Uppercase ASCII recognized here */
-    } else { /* ch == 91 || 46 <= ch <= 59 */
-      if (ch == 91 || ch == 59 || ch <= 47)
-        return 0;
-      else
-        return 1;
-    }
-  }
-}
-
-static unicode
-next_utf2unicode(char **utfstring_ptr, int * valid)
-{
-    unsigned char *ptr = (unsigned char *)(*utfstring_ptr);
-    unsigned char ch, ch2, ch3;
-    int length = 1;             /* default length */
-    unicode result = 0x80;      /* default bad result; */
-    *valid = 1;
-    switch ((ch = ptr[0]) >> 4) {
-        default:
-            result = ch;
-            break;
-
-        case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
-            /* Shouldn't happen. */
-            *valid = 0;
-            break;
-
-        case 0xC: case 0xD:
-            /* 110xxxxx  10xxxxxx */
-            if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
-                unsigned char high_five = ch & 0x1F;
-                unsigned char low_six = ch2 & 0x3F;
-                result = (high_five << 6) + low_six;
-                length = 2;
-            }
-            break;
-
-        case 0xE:
-            /* 1110xxxx 10xxxxxx 10xxxxxx */
-            if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
-                if (((ch3 = ptr[2]) & 0xC0) == 0x80) {
-                    unsigned char high_four = ch & 0x0f;
-                    unsigned char mid_six = ch2 & 0x3f;
-                    unsigned char low_six = ch3 & 0x3f;
-                    result = (((high_four << 6) + mid_six) << 6) + low_six;
-                    length = 3;
-                } else {
-                    length = 2;
-                }
-            }
-            break;
-        } /* end of switch */
-
-    *utfstring_ptr = (char *)(ptr + length);
-    return result;
-}
-
-/* Take pointer to a string.  Skip over the longest part of the string that
- * could be taken as a fieldname.  Allow '/' if slash_okay is JNI_TRUE.
- *
- * Return a pointer to just past the fieldname.  Return NULL if no fieldname
- * at all was found, or in the case of slash_okay being true, we saw
- * consecutive slashes (meaning we were looking for a qualified path but
- * found something that was badly-formed).
- */
-static char *
-skip_over_fieldname(char *name, jboolean slash_okay,
-                    unsigned int length)
-{
-    char *p;
-    unicode ch;
-    unicode last_ch = 0;
-    int valid = 1;
-    /* last_ch == 0 implies we are looking at the first char. */
-    for (p = name; p != name + length; last_ch = ch) {
-        char *old_p = p;
-        ch = *p;
-        if (ch < 128) {
-            p++;
-            if (isJvmIdentifier(ch)) {
-                continue;
-            }
-        } else {
-            char *tmp_p = p;
-            ch = next_utf2unicode(&tmp_p, &valid);
-            if (valid == 0)
-              return 0;
-            p = tmp_p;
-            if (isJvmIdentifier(ch)) {
-                        continue;
-            }
-        }
-
-        if (slash_okay && ch == '/' && last_ch) {
-            if (last_ch == '/') {
-                return 0;       /* Don't permit consecutive slashes */
-            }
-        } else if (ch == '_' || ch == '$') {
-        } else {
-            return last_ch ? old_p : 0;
-        }
-    }
-    return last_ch ? p : 0;
-}
-
-/* Take pointer to a string.  Skip over the longest part of the string that
- * could be taken as a field signature.  Allow "void" if void_okay.
- *
- * Return a pointer to just past the signature.  Return NULL if no legal
- * signature is found.
- */
-
-static char *
-skip_over_field_signature(char *name, jboolean void_okay,
-                          unsigned int length)
-{
-    unsigned int array_dim = 0;
-    for (;length > 0;) {
-        switch (name[0]) {
-            case JVM_SIGNATURE_VOID:
-                if (!void_okay) return 0;
-                /* FALL THROUGH */
-            case JVM_SIGNATURE_BOOLEAN:
-            case JVM_SIGNATURE_BYTE:
-            case JVM_SIGNATURE_CHAR:
-            case JVM_SIGNATURE_SHORT:
-            case JVM_SIGNATURE_INT:
-            case JVM_SIGNATURE_FLOAT:
-            case JVM_SIGNATURE_LONG:
-            case JVM_SIGNATURE_DOUBLE:
-                return name + 1;
-
-            case JVM_SIGNATURE_CLASS: {
-                /* Skip over the classname, if one is there. */
-                char *p =
-                    skip_over_fieldname(name + 1, JNI_TRUE, --length);
-                /* The next character better be a semicolon. */
-                if (p && p - name - 1 > 0 && p[0] == ';')
-                    return p + 1;
-                return 0;
-            }
-
-            case JVM_SIGNATURE_ARRAY:
-                array_dim++;
-                /* JVMS 2nd ed. 4.10 */
-                /*   The number of dimensions in an array is limited to 255 ... */
-                if (array_dim > 255) {
-                    return 0;
-                }
-                /* The rest of what's there better be a legal signature.  */
-                name++;
-                length--;
-                void_okay = JNI_FALSE;
-                break;
-
-            default:
-                return 0;
-        }
-    }
-    return 0;
-}
-
-
-/* Used in java/lang/Class.c */
-/* Determine if the specified name is legal
- * UTF name for a classname.
- *
- * Note that this routine expects the internal form of qualified classes:
- * the dots should have been replaced by slashes.
- */
-JNIEXPORT jboolean
-VerifyClassname(char *name, jboolean allowArrayClass)
-{
-    size_t s = strlen(name);
-    assert(s <= UINT_MAX);
-    unsigned int length = (unsigned int)s;
-    char *p;
-
-    if (length > 0 && name[0] == JVM_SIGNATURE_ARRAY) {
-        if (!allowArrayClass) {
-            return JNI_FALSE;
-        } else {
-            /* Everything that's left better be a field signature */
-            p = skip_over_field_signature(name, JNI_FALSE, length);
-        }
-    } else {
-        /* skip over the fieldname.  Slashes are okay */
-        p = skip_over_fieldname(name, JNI_TRUE, length);
-    }
-    return (p != 0 && p - name == (ptrdiff_t)length);
-}
-
-/*
- * Translates '.' to '/'.  Returns JNI_TRUE is any / were present.
- */
-JNIEXPORT jboolean
-VerifyFixClassname(char *name)
-{
-    char *p = name;
-    jboolean slashesFound = JNI_FALSE;
-    int valid = 1;
-
-    while (valid != 0 && *p != '\0') {
-        if (*p == '/') {
-            slashesFound = JNI_TRUE;
-            p++;
-        } else if (*p == '.') {
-            *p++ = '/';
-        } else {
-            next_utf2unicode(&p, &valid);
-        }
-    }
-
-    return slashesFound && valid != 0;
-}
--- a/src/java.base/share/native/libzip/Deflater.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/share/native/libzip/Deflater.c	Thu Oct 10 10:57:42 2019 -0400
@@ -257,7 +257,7 @@
 
     res = doDeflate(env, addr, input, inputLen, output + outputOff, outputLen,
                     flush, params);
-    (*env)->ReleasePrimitiveArrayCritical(env, outputArray, input, 0);
+    (*env)->ReleasePrimitiveArrayCritical(env, outputArray, output, 0);
 
     retVal = checkDeflateStatus(env, addr, inputLen, outputLen, params, res);
     return retVal;
--- a/src/java.base/unix/native/libjava/jdk_util_md.c	Wed Oct 09 10:58:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <dlfcn.h>
-#include "jdk_util.h"
-
-int JDK_InitJvmHandle() {
-    /* nop */
-    return 1;
-}
-
-void* JDK_FindJvmEntry(const char* name) {
-    return dlsym(RTLD_DEFAULT, name);
-}
--- a/src/java.base/unix/native/libnio/ch/Net.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/unix/native/libnio/ch/Net.c	Thu Oct 10 10:57:42 2019 -0400
@@ -66,34 +66,6 @@
   #endif
 #endif
 
-#if defined(_AIX)
-  #ifndef IP_BLOCK_SOURCE
-    #define IP_BLOCK_SOURCE                 58   /* Block data from a given source to a given group */
-    #define IP_UNBLOCK_SOURCE               59   /* Unblock data from a given source to a given group */
-    #define IP_ADD_SOURCE_MEMBERSHIP        60   /* Join a source-specific group */
-    #define IP_DROP_SOURCE_MEMBERSHIP       61   /* Leave a source-specific group */
-  #endif
-
-  #ifndef MCAST_BLOCK_SOURCE
-    #define MCAST_BLOCK_SOURCE              64
-    #define MCAST_UNBLOCK_SOURCE            65
-    #define MCAST_JOIN_SOURCE_GROUP         66
-    #define MCAST_LEAVE_SOURCE_GROUP        67
-
-    /* This means we're on AIX 5.3 and 'group_source_req' and 'ip_mreq_source' aren't defined as well */
-    struct group_source_req {
-        uint32_t gsr_interface;
-        struct sockaddr_storage gsr_group;
-        struct sockaddr_storage gsr_source;
-    };
-    struct ip_mreq_source {
-        struct in_addr  imr_multiaddr;  /* IP multicast address of group */
-        struct in_addr  imr_sourceaddr; /* IP address of source */
-        struct in_addr  imr_interface;  /* local IP address of interface */
-    };
-  #endif
-#endif /* _AIX */
-
 #define COPY_INET6_ADDRESS(env, source, target) \
     (*env)->GetByteArrayRegion(env, source, 0, 16, target)
 
--- a/src/java.base/windows/native/libjava/jdk_util_md.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.base/windows/native/libjava/jdk_util_md.c	Thu Oct 10 10:57:42 2019 -0400
@@ -28,17 +28,6 @@
 
 #define JVM_DLL "jvm.dll"
 
-static HMODULE jvm_handle = NULL;
-
-int JDK_InitJvmHandle() {
-    jvm_handle = GetModuleHandle(JVM_DLL);
-    return (jvm_handle != NULL);
-}
-
-void* JDK_FindJvmEntry(const char* name) {
-    return (void*) GetProcAddress(jvm_handle, name);
-}
-
 JNIEXPORT HMODULE JDK_LoadSystemLibrary(const char* name) {
     HMODULE handle = NULL;
     char path[MAX_PATH];
--- a/src/java.datatransfer/share/classes/java/awt/datatransfer/MimeType.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.datatransfer/share/classes/java/awt/datatransfer/MimeType.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, 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
@@ -346,9 +346,9 @@
         return newObj;
     }
 
-    private String    primaryType;
-    private String    subType;
-    private MimeTypeParameterList parameters;
+    private transient String    primaryType;
+    private transient String    subType;
+    private transient MimeTypeParameterList parameters;
 
     //    below here be scary parsing related things
 
--- a/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.naming/share/classes/com/sun/jndi/toolkit/ctx/Continuation.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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,6 +51,7 @@
     /**
      * Whether links were encountered.
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     protected Object followingLink = null;
 
     /**
@@ -71,6 +72,7 @@
      * The last resolved context. Used to set the "AltNameCtx" in a
      * CannotProceedException.
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     protected Context resolvedContext = null;
 
     /**
--- a/src/java.naming/share/classes/javax/naming/Binding.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.naming/share/classes/javax/naming/Binding.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -54,6 +54,7 @@
      * @see #getObject
      * @see #setObject
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private Object boundObj;
 
     /**
--- a/src/java.naming/share/classes/javax/naming/CannotProceedException.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.naming/share/classes/javax/naming/CannotProceedException.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -127,6 +127,7 @@
      * @see #altName
      * @see javax.naming.spi.ObjectFactory#getObjectInstance
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     protected Context altNameCtx = null;
 
     /**
--- a/src/java.naming/share/classes/javax/naming/LinkException.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.naming/share/classes/javax/naming/LinkException.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -85,6 +85,7 @@
       * @see #getLinkResolvedObj
       * @see #setLinkResolvedObj
       */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     protected Object linkResolvedObj;
 
     /**
--- a/src/java.naming/share/classes/javax/naming/NamingException.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.naming/share/classes/javax/naming/NamingException.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -79,6 +79,7 @@
       * @see #getResolvedObj
       * @see #setResolvedObj
       */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     protected Object resolvedObj;
     /**
      * Contains the remaining name that has not been resolved yet.
--- a/src/java.naming/share/classes/javax/naming/event/NamingEvent.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.naming/share/classes/javax/naming/event/NamingEvent.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 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
@@ -122,6 +122,7 @@
      * Contains information about the change that generated this event.
      * @serial
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     protected Object changeInfo;
 
     /**
--- a/src/java.naming/share/classes/javax/naming/spi/ResolveResult.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.naming/share/classes/javax/naming/spi/ResolveResult.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,6 +50,7 @@
      * Constructors should always initialize this.
      * @serial
      */
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     protected Object resolvedObj;
     /**
      * Field containing the remaining name yet to be resolved.
--- a/src/java.prefs/share/classes/java/util/prefs/NodeChangeEvent.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.prefs/share/classes/java/util/prefs/NodeChangeEvent.java	Thu Oct 10 10:57:42 2019 -0400
@@ -46,8 +46,6 @@
 public class NodeChangeEvent extends java.util.EventObject {
     /**
      * The node that was added or removed.
-     *
-     * @serial
      */
     private transient Preferences child;
 
--- a/src/java.rmi/share/classes/java/rmi/activation/package-info.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.rmi/share/classes/java/rmi/activation/package-info.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * <p>
+ *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this
  * particular file as subject to the "Classpath" exception as provided
  * by Oracle in the LICENSE file that accompanied this code.
- * <p>
+ *
  * 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).
- * <p>
+ *
  * 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.
- * <p>
+ *
  * 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.
--- a/src/java.rmi/share/classes/java/rmi/dgc/package-info.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.rmi/share/classes/java/rmi/dgc/package-info.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * <p>
+ *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this
  * particular file as subject to the "Classpath" exception as provided
  * by Oracle in the LICENSE file that accompanied this code.
- * <p>
+ *
  * 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).
- * <p>
+ *
  * 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.
- * <p>
+ *
  * 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.
--- a/src/java.rmi/share/classes/java/rmi/package-info.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.rmi/share/classes/java/rmi/package-info.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * <p>
+ *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this
  * particular file as subject to the "Classpath" exception as provided
  * by Oracle in the LICENSE file that accompanied this code.
- * <p>
+ *
  * 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).
- * <p>
+ *
  * 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.
- * <p>
+ *
  * 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.
--- a/src/java.rmi/share/classes/java/rmi/registry/package-info.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.rmi/share/classes/java/rmi/registry/package-info.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * <p>
+ *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this
  * particular file as subject to the "Classpath" exception as provided
  * by Oracle in the LICENSE file that accompanied this code.
- * <p>
+ *
  * 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).
- * <p>
+ *
  * 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.
- * <p>
+ *
  * 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.
--- a/src/java.rmi/share/classes/java/rmi/server/package-info.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.rmi/share/classes/java/rmi/server/package-info.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,23 +1,23 @@
 /*
  * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * <p>
+ *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this
  * particular file as subject to the "Classpath" exception as provided
  * by Oracle in the LICENSE file that accompanied this code.
- * <p>
+ *
  * 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).
- * <p>
+ *
  * 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.
- * <p>
+ *
  * 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.
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1391,6 +1391,7 @@
     static class KerberosSessionKey implements Key {
         private static final long serialVersionUID = 699307378954123869L;
 
+        @SuppressWarnings("serial") // Not statically typed as Serializable
         private final EncryptionKey key;
 
         KerberosSessionKey(EncryptionKey key) {
--- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java	Thu Oct 10 10:57:42 2019 -0400
@@ -53,7 +53,9 @@
 
     private static final long serialVersionUID = 7723415700837898232L;
 
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private Krb5NameElement name;
+    @SuppressWarnings("serial") // Not statically typed as Serializable
     private Credentials krb5Credentials;
 
     private Krb5InitCredential(Krb5NameElement name,
--- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/KRBError.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/KRBError.java	Thu Oct 10 10:57:42 2019 -0400
@@ -79,7 +79,9 @@
  * <a href="http://www.ietf.org/rfc/rfc4120.txt">
  * http://www.ietf.org/rfc/rfc4120.txt</a>.
  */
-
+// The instance fields not statically typed as Serializable are ASN.1
+// encoded and written by the writeObject method.
+@SuppressWarnings("serial")
 public class KRBError implements java.io.Serializable {
     static final long serialVersionUID = 3643809337475284503L;
 
--- a/src/java.sql/share/classes/javax/sql/package-info.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/java.sql/share/classes/javax/sql/package-info.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,23 +1,23 @@
 /**
  * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- * <p>
+ *
  * This code is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License version 2 only, as
  * published by the Free Software Foundation.  Oracle designates this
  * particular file as subject to the "Classpath" exception as provided
  * by Oracle in the LICENSE file that accompanied this code.
- * <p>
+ *
  * 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).
- * <p>
+ *
  * 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.
- * <p>
+ *
  * 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.
--- a/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.aot/share/classes/jdk.tools.jaotc/src/jdk/tools/jaotc/collect/FileSupport.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java	Thu Oct 10 10:57:42 2019 -0400
@@ -389,7 +389,7 @@
                 Entry e = table[hash];
                 Assert.check(e == elems, elems.sym);
                 table[hash] = elems.shadowed;
-                elems = elems.sibling;
+                elems = elems.nextSibling;
             }
             Assert.check(next.shared > 0);
             next.shared--;
@@ -466,15 +466,15 @@
             }
 
             // remove e from elems and sibling list
-            te = elems;
-            if (te == e)
-                elems = e.sibling;
-            else while (true) {
-                if (te.sibling == e) {
-                    te.sibling = e.sibling;
-                    break;
-                }
-                te = te.sibling;
+            if (elems == e) {
+                elems = e.nextSibling;
+                if (elems != null)
+                    elems.prevSibling = null;
+            } else {
+                Assert.check(e.prevSibling != null, e.sym);
+                e.prevSibling.nextSibling = e.nextSibling;
+                if (e.nextSibling != null)
+                    e.nextSibling.prevSibling = e.prevSibling;
             }
 
             removeCount++;
@@ -597,7 +597,7 @@
                 private Symbol doNext() {
                     Symbol sym = (currEntry == null ? null : currEntry.sym);
                     if (currEntry != null) {
-                        currEntry = currEntry.sibling;
+                        currEntry = currEntry.nextSibling;
                     }
                     update();
                     return sym;
@@ -617,7 +617,7 @@
 
                 void skipToNextMatchingEntry() {
                     while (currEntry != null && sf != null && !sf.accepts(currEntry.sym)) {
-                        currEntry = currEntry.sibling;
+                        currEntry = currEntry.nextSibling;
                     }
                 }
             };
@@ -677,7 +677,7 @@
             result.append("Scope[");
             for (ScopeImpl s = this; s != null ; s = s.next) {
                 if (s != this) result.append(" | ");
-                for (Entry e = s.elems; e != null; e = e.sibling) {
+                for (Entry e = s.elems; e != null; e = e.nextSibling) {
                     if (e != s.elems) result.append(", ");
                     result.append(e.sym);
                 }
@@ -702,18 +702,24 @@
 
         /** Next entry in same scope.
          */
-        public Entry sibling;
+        public Entry nextSibling;
+
+        /** Prev entry in same scope.
+         */
+        public Entry prevSibling;
 
         /** The entry's scope.
          *  scope == null   iff   this == sentinel
          */
         public ScopeImpl scope;
 
-        public Entry(Symbol sym, Entry shadowed, Entry sibling, ScopeImpl scope) {
+        public Entry(Symbol sym, Entry shadowed, Entry nextSibling, ScopeImpl scope) {
             this.sym = sym;
             this.shadowed = shadowed;
-            this.sibling = sibling;
+            this.nextSibling = nextSibling;
             this.scope = scope;
+            if (nextSibling != null)
+                nextSibling.prevSibling = this;
         }
 
         /** Return next entry with the same name as this entry, proceeding
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Thu Oct 10 10:57:42 2019 -0400
@@ -3745,12 +3745,9 @@
             return cl1;
         } else if (shouldSkip.test(cl1.head, cl2.head)) {
             return union(cl1.tail, cl2.tail, shouldSkip).prepend(cl1.head);
-        } else if (cl1.head.tsym.precedes(cl2.head.tsym, this)) {
-            return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head);
         } else if (cl2.head.tsym.precedes(cl1.head.tsym, this)) {
             return union(cl1, cl2.tail, shouldSkip).prepend(cl2.head);
         } else {
-            // unrelated types
             return union(cl1.tail, cl2, shouldSkip).prepend(cl1.head);
         }
     }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java	Thu Oct 10 10:57:42 2019 -0400
@@ -233,7 +233,7 @@
     }
 
     public void setMultiReleaseValue(String multiReleaseValue) {
-        fsEnv = Collections.singletonMap("multi-release", multiReleaseValue);
+        fsEnv = Collections.singletonMap("releaseVersion", multiReleaseValue);
     }
 
     private boolean contains(Collection<Path> searchPath, Path file) throws IOException {
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java	Thu Oct 10 10:57:42 2019 -0400
@@ -378,9 +378,6 @@
 
         long p11KeyID = p11Key.getKeyID();
         try {
-            if (session == null) {
-                session = token.getOpSession();
-            }
             CK_MECHANISM mechWithParams;
             switch (blockMode) {
                 case MODE_GCM:
@@ -390,6 +387,9 @@
                 default:
                     throw new ProviderException("Unsupported mode: " + blockMode);
             }
+            if (session == null) {
+                session = token.getOpSession();
+            }
             if (encrypt) {
                 token.p11.C_EncryptInit(session.id(), mechWithParams,
                     p11KeyID);
@@ -398,7 +398,6 @@
                     p11KeyID);
             }
         } catch (PKCS11Exception e) {
-            //e.printStackTrace();
             p11Key.releaseKeyID();
             session = token.releaseSession(session);
             throw e;
@@ -718,7 +717,9 @@
                    errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
             throw (IllegalBlockSizeException)
                     (new IllegalBlockSizeException(e.toString()).initCause(e));
-        } else if (errorCode == CKR_ENCRYPTED_DATA_INVALID) {
+        } else if (errorCode == CKR_ENCRYPTED_DATA_INVALID ||
+                // Solaris-specific
+                errorCode == CKR_GENERAL_ERROR) {
             throw (BadPaddingException)
                     (new BadPaddingException(e.toString()).initCause(e));
         }
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -103,9 +103,11 @@
             digestLength = 20;
             break;
         case (int)CKM_SHA224:
+        case (int)CKM_SHA512_224:
             digestLength = 28;
             break;
         case (int)CKM_SHA256:
+        case (int)CKM_SHA512_256:
             digestLength = 32;
             break;
         case (int)CKM_SHA384:
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -91,9 +91,11 @@
             macLength = 20;
             break;
         case (int)CKM_SHA224_HMAC:
+        case (int)CKM_SHA512_224_HMAC:
             macLength = 28;
             break;
         case (int)CKM_SHA256_HMAC:
+        case (int)CKM_SHA512_256_HMAC:
             macLength = 32;
             break;
         case (int)CKM_SHA384_HMAC:
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c	Thu Oct 10 10:57:42 2019 -0400
@@ -721,7 +721,7 @@
     }
 
     // populate using java values
-    ckParamPtr->prfMechanism = jLongToCKULong(jPrfMechanism);
+    ckParamPtr->prfHashMechanism = jLongToCKULong(jPrfMechanism);
     ckParamPtr->ulMacLength = jLongToCKULong(jUlMacLength);
     ckParamPtr->ulServerOrClient = jLongToCKULong(jUlServerOrClient);
 
@@ -1014,17 +1014,18 @@
 }
 
 /*
- * converts the Java CK_GCM_PARAMS object to a CK_GCM_PARAMS pointer
+ * converts the Java CK_GCM_PARAMS object to a CK_GCM_PARAMS_NO_IVBITS pointer
+ * Note: Need to try NSS definition first to avoid SIGSEGV.
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_GCM_PARAMS object to convert
  * @param pLength - length of the allocated memory of the returned pointer
- * @return pointer to the new CK_GCM_PARAMS structure
+ * @return pointer to the new CK_GCM_PARAMS_NO_IVBITS structure
  */
-CK_GCM_PARAMS_PTR
+CK_GCM_PARAMS_NO_IVBITS_PTR
 jGCMParamsToCKGCMParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
-    CK_GCM_PARAMS_PTR ckParamPtr;
+    CK_GCM_PARAMS_NO_IVBITS_PTR ckParamPtr;
     jclass jGcmParamsClass;
     jfieldID fieldID;
     jobject jIv, jAad;
@@ -1052,8 +1053,8 @@
     if (fieldID == NULL) { return NULL; }
     jTagLen = (*env)->GetLongField(env, jParam, fieldID);
 
-    // allocate memory for CK_GCM_PARAMS pointer
-    ckParamPtr = calloc(1, sizeof(CK_GCM_PARAMS));
+    // allocate memory for CK_GCM_PARAMS_NO_IVBITS pointer
+    ckParamPtr = calloc(1, sizeof(CK_GCM_PARAMS_NO_IVBITS));
     if (ckParamPtr == NULL) {
         throwOutOfMemoryError(env, 0);
         return NULL;
@@ -1073,16 +1074,15 @@
     ckParamPtr->ulTagBits = jLongToCKULong(jTagLen);
 
     if (pLength != NULL) {
-        *pLength = sizeof(CK_GCM_PARAMS);
+        *pLength = sizeof(CK_GCM_PARAMS_NO_IVBITS);
     }
-    TRACE1("Created inner GCM_PARAMS PTR %lX\n", ptr_to_jlong(ckParamPtr));
+    TRACE1("Created inner GCM_PARAMS PTR w/o ulIvBits %p\n", ckParamPtr);
     return ckParamPtr;
 cleanup:
     free(ckParamPtr->pIv);
     free(ckParamPtr->pAAD);
     free(ckParamPtr);
     return NULL;
-
 }
 
 /*
@@ -1179,7 +1179,7 @@
         throwOutOfMemoryError(env, 0);
         return NULL;
     }
-    TRACE1("DEBUG jMechanismToCKMechanismPtr: allocated mech %p \n", ckpMech);
+    TRACE1("DEBUG jMechanismToCKMechanismPtr: allocated mech %p\n", ckpMech);
 
     ckpMech->mechanism = jLongToCKULong(jMechType);
 
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c	Thu Oct 10 10:57:42 2019 -0400
@@ -72,6 +72,7 @@
 {
     CK_SESSION_HANDLE ckSessionHandle;
     CK_MECHANISM_PTR ckpMechanism = NULL;
+    CK_MECHANISM_PTR ckpTemp;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
@@ -81,15 +82,32 @@
     ckSessionHandle = jLongToCKULong(jSessionHandle);
     ckKeyHandle = jLongToCKULong(jKeyHandle);
     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
+    TRACE1("DEBUG C_EncryptInit: created pMech = %p\n",
+            ckpMechanism);
+
     if ((*env)->ExceptionCheck(env)) { return; }
 
     rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, ckpMechanism,
                                         ckKeyHandle);
 
-    // if OAEP, then cannot free here
+    if (ckpMechanism->mechanism == CKM_AES_GCM) {
+        if (rv == CKR_ARGUMENTS_BAD || rv == CKR_MECHANISM_PARAM_INVALID) {
+            // retry with CKM_GCM_PARAMS structure in pkcs11t.h
+            TRACE0("DEBUG C_EncryptInit: retry with CK_GCM_PARAMS\n");
+            ckpTemp = updateGCMParams(env, ckpMechanism);
+            if (ckpTemp != NULL) { // only re-call if conversion succeeds
+                ckpMechanism = ckpTemp;
+                rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, ckpMechanism,
+                        ckKeyHandle);
+            }
+        }
+    }
+
+    TRACE1("DEBUG C_EncryptInit: freed pMech = %p\n", ckpMechanism);
     freeCKMechanismPtr(ckpMechanism);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    TRACE0("FINISHED\n");
 }
 #endif
 
@@ -292,6 +310,7 @@
 {
     CK_SESSION_HANDLE ckSessionHandle;
     CK_MECHANISM_PTR ckpMechanism = NULL;
+    CK_MECHANISM_PTR ckpTemp;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
@@ -301,15 +320,32 @@
     ckSessionHandle = jLongToCKULong(jSessionHandle);
     ckKeyHandle = jLongToCKULong(jKeyHandle);
     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
+    TRACE1("DEBUG C_DecryptInit: created pMech = %p\n",
+            ckpMechanism);
+
     if ((*env)->ExceptionCheck(env)) { return; }
 
     rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, ckpMechanism,
                                         ckKeyHandle);
 
-    // if OAEP, then cannot free here
+    if (ckpMechanism->mechanism == CKM_AES_GCM) {
+        if (rv == CKR_ARGUMENTS_BAD || rv == CKR_MECHANISM_PARAM_INVALID) {
+            // retry with CKM_GCM_PARAMS structure in pkcs11t.h
+            TRACE0("DEBUG C_DecryptInit: retry with CK_GCM_PARAMS\n");
+            ckpTemp = updateGCMParams(env, ckpMechanism);
+            if (ckpTemp != NULL) { // only re-call if conversion succeeds
+                ckpMechanism = ckpTemp;
+                rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, ckpMechanism,
+                        ckKeyHandle);
+            }
+        }
+    }
+
+    TRACE1("DEBUG C_DecryptInit: freed pMech = %p\n", ckpMechanism);
     freeCKMechanismPtr(ckpMechanism);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    TRACE0("FINISHED\n");
 }
 #endif
 
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c	Thu Oct 10 10:57:42 2019 -0400
@@ -302,29 +302,30 @@
      CK_TLS12_KEY_MAT_PARAMS* tlsKmTmp;
 
      if (mechPtr != NULL) {
-         TRACE2("DEBUG: free mech %lX (mech id = 0x%lX)\n",
-                 ptr_to_jlong(mechPtr),  mechPtr->mechanism);
+         TRACE2("DEBUG freeCKMechanismPtr: free pMech %p (mech 0x%lX)\n",
+                 mechPtr,  mechPtr->mechanism);
          if (mechPtr->pParameter != NULL) {
+             tmp = mechPtr->pParameter;
              switch (mechPtr->mechanism) {
                  case CKM_AES_GCM:
-                     tmp = mechPtr->pParameter;
-                     TRACE1("\t=> free GCM_PARAMS %lX\n",
-                             ptr_to_jlong(tmp));
-                     free(((CK_GCM_PARAMS*)tmp)->pIv);
-                     free(((CK_GCM_PARAMS*)tmp)->pAAD);
+                     if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS)) {
+                         TRACE0("[ GCM_PARAMS w/o ulIvBits ]\n");
+                         free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pIv);
+                         free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pAAD);
+                     } else if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS)) {
+                         TRACE0("[ GCM_PARAMS ]\n");
+                         free(((CK_GCM_PARAMS*)tmp)->pIv);
+                         free(((CK_GCM_PARAMS*)tmp)->pAAD);
+                     }
                      break;
                  case CKM_AES_CCM:
-                     tmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_CCM_PARAMS %lX\n",
-                             ptr_to_jlong(tmp));
+                     TRACE0("[ CK_CCM_PARAMS ]\n");
                      free(((CK_CCM_PARAMS*)tmp)->pNonce);
                      free(((CK_CCM_PARAMS*)tmp)->pAAD);
                      break;
                  case CKM_TLS_PRF:
                  case CKM_NSS_TLS_PRF_GENERAL:
-                     tmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_TLS_PRF_PARAMS %lX\n",
-                         ptr_to_jlong(tmp));
+                     TRACE0("[ CK_TLS_PRF_PARAMS ]\n");
                      free(((CK_TLS_PRF_PARAMS*)tmp)->pSeed);
                      free(((CK_TLS_PRF_PARAMS*)tmp)->pLabel);
                      free(((CK_TLS_PRF_PARAMS*)tmp)->pulOutputLen);
@@ -334,18 +335,16 @@
                  case CKM_TLS_MASTER_KEY_DERIVE:
                  case CKM_SSL3_MASTER_KEY_DERIVE_DH:
                  case CKM_TLS_MASTER_KEY_DERIVE_DH:
-                     sslMkdTmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_SSL3_MASTER_KEY_DERIVE_PARAMS %lX\n",
-                         ptr_to_jlong(sslMkdTmp));
+                     sslMkdTmp = tmp;
+                     TRACE0("[ CK_SSL3_MASTER_KEY_DERIVE_PARAMS ]\n");
                      free(sslMkdTmp->RandomInfo.pClientRandom);
                      free(sslMkdTmp->RandomInfo.pServerRandom);
                      free(sslMkdTmp->pVersion);
                      break;
                  case CKM_SSL3_KEY_AND_MAC_DERIVE:
                  case CKM_TLS_KEY_AND_MAC_DERIVE:
-                     sslKmTmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_SSL3_KEY_MAT_PARAMS %lX\n",
-                         ptr_to_jlong(sslKmTmp));
+                     sslKmTmp = tmp;
+                     TRACE0("[ CK_SSL3_KEY_MAT_PARAMS ]\n");
                      free(sslKmTmp->RandomInfo.pClientRandom);
                      free(sslKmTmp->RandomInfo.pServerRandom);
                      if (sslKmTmp->pReturnedKeyMaterial != NULL) {
@@ -356,17 +355,15 @@
                      break;
                  case CKM_TLS12_MASTER_KEY_DERIVE:
                  case CKM_TLS12_MASTER_KEY_DERIVE_DH:
-                     tlsMkdTmp = mechPtr->pParameter;
-                     TRACE1("\t=> CK_TLS12_MASTER_KEY_DERIVE_PARAMS %lX\n",
-                         ptr_to_jlong(tlsMkdTmp));
+                     tlsMkdTmp = tmp;
+                     TRACE0("[ CK_TLS12_MASTER_KEY_DERIVE_PARAMS ]\n");
                      free(tlsMkdTmp->RandomInfo.pClientRandom);
                      free(tlsMkdTmp->RandomInfo.pServerRandom);
                      free(tlsMkdTmp->pVersion);
                      break;
                  case CKM_TLS12_KEY_AND_MAC_DERIVE:
-                     tlsKmTmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_TLS12_KEY_MAT_PARAMS %lX\n",
-                         ptr_to_jlong(tlsKmTmp));
+                     tlsKmTmp = tmp;
+                     TRACE0("[ CK_TLS12_KEY_MAT_PARAMS ]\n");
                      free(tlsKmTmp->RandomInfo.pClientRandom);
                      free(tlsKmTmp->RandomInfo.pServerRandom);
                      if (tlsKmTmp->pReturnedKeyMaterial != NULL) {
@@ -377,9 +374,7 @@
                      break;
                  case CKM_ECDH1_DERIVE:
                  case CKM_ECDH1_COFACTOR_DERIVE:
-                     tmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_ECDH1_DERIVE_PARAMS %lX\n",
-                         ptr_to_jlong(tmp));
+                     TRACE0("[ CK_ECDH1_DERIVE_PARAMS ]\n");
                      free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pSharedData);
                      free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pPublicData);
                      break;
@@ -387,7 +382,6 @@
                  case CKM_AES_CTR:
                  case CKM_RSA_PKCS_PSS:
                  case CKM_CAMELLIA_CTR:
-                     TRACE0("\t=> NO OP\n");
                      // params do not contain pointers
                      break;
                  default:
@@ -399,17 +393,59 @@
                      // CKM_EXTRACT_KEY_FROM_KEY, CKM_OTP, CKM_KIP,
                      // CKM_DSA_PARAMETER_GEN?, CKM_GOSTR3410_*
                      // CK_any_CBC_ENCRYPT_DATA?
-                     TRACE0("\t=> ERROR UNSUPPORTED CK PARAMS\n");
+                     TRACE0("ERROR: UNSUPPORTED CK_MECHANISM\n");
                      break;
              }
-             free(mechPtr->pParameter);
+             TRACE1("\t=> freed param %p\n", tmp);
+             free(tmp);
          } else {
-             TRACE0("DEBUG => Parameter NULL\n");
+             TRACE0("\t=> param NULL\n");
          }
          free(mechPtr);
+         TRACE0("FINISHED\n");
      }
 }
 
+/* This function replaces the CK_GCM_PARAMS_NO_IVBITS structure associated
+ * with the specified CK_MECHANISM structure with CK_GCM_PARAMS
+ * structure.
+ *
+ * @param mechPtr pointer to the CK_MECHANISM structure containing
+ * the to-be-converted CK_GCM_PARAMS_NO_IVBITS structure.
+ * @return pointer to the CK_MECHANISM structure containing the
+ * converted CK_GCM_PARAMS structure or NULL if no conversion took place.
+ */
+CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr) {
+    CK_GCM_PARAMS* pGcmParams2 = NULL;
+    CK_GCM_PARAMS_NO_IVBITS* pParams = NULL;
+    if ((mechPtr->mechanism == CKM_AES_GCM) &&
+            (mechPtr->pParameter != NULL_PTR) &&
+            (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS))) {
+        pGcmParams2 = calloc(1, sizeof(CK_GCM_PARAMS));
+        if (pGcmParams2 == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return NULL;
+        }
+        pParams = (CK_GCM_PARAMS_NO_IVBITS*) mechPtr->pParameter;
+        pGcmParams2->pIv = pParams->pIv;
+        pGcmParams2->ulIvLen = pParams->ulIvLen;
+        pGcmParams2->ulIvBits = (pGcmParams2->ulIvLen << 3);
+        pGcmParams2->pAAD = pParams->pAAD;
+        pGcmParams2->ulAADLen = pParams->ulAADLen;
+        pGcmParams2->ulTagBits = pParams->ulTagBits;
+        TRACE1("DEBUG updateGCMParams: pMech %p\n", mechPtr);
+        TRACE2("\t=> GCM param w/o ulIvBits %p => GCM param %p\n", pParams,
+                pGcmParams2);
+        free(pParams);
+        mechPtr->pParameter = pGcmParams2;
+        mechPtr->ulParameterLen = sizeof(CK_GCM_PARAMS);
+        return mechPtr;
+    } else {
+        TRACE0("DEBUG updateGCMParams: no conversion done\n");
+    }
+    return NULL;
+}
+
 /*
  * the following functions convert Java arrays to PKCS#11 array pointers and
  * their array length and vice versa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/* There is a known incompatibility for CK_GCM_PARAMS structure.
+ * PKCS#11 v2.40 standard mechanisms specification specifies
+ * CK_GCM_PARAMS as
+ *     typedef struct CK_GCM_PARAMS {
+ *         CK_BYTE_PTR       pIv;
+ *         CK_ULONG          ulIvLen;
+ *         CK_BYTE_PTR       pAAD;
+ *         CK_ULONG          ulAADLen;
+ *         CK_ULONG          ulTagBits;
+ *     } CK_GCM_PARAMS;
+ * However, the official header file of PKCS#11 v2.40 defines the
+ * CK_GCM_PARAMS with an extra "ulIvBits" field (type CK_ULONG).
+ * NSS uses the spec version while Solaris and SoftHSM2 use the header
+ * version. In order to work with both sides, SunPKCS11 provider defines
+ * the spec version of CK_GCM_PARAMS as CK_GCM_PARAMS_NO_IVBITS (as in this
+ * file) and uses it first before failing over to the header version.
+ */
+#ifndef _PKCS11GCM2_H_
+#define _PKCS11GCM2_H_ 1
+
+/* include the platform dependent part of the header */
+typedef struct CK_GCM_PARAMS_NO_IVBITS {
+    CK_BYTE_PTR       pIv;
+    CK_ULONG          ulIvLen;
+    CK_BYTE_PTR       pAAD;
+    CK_ULONG          ulAADLen;
+    CK_ULONG          ulTagBits;
+} CK_GCM_PARAMS_NO_IVBITS;
+
+typedef CK_GCM_PARAMS_NO_IVBITS CK_PTR CK_GCM_PARAMS_NO_IVBITS_PTR;
+
+#endif /* _PKCS11GCM2_H_ */
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h	Thu Oct 10 10:57:42 2019 -0400
@@ -1833,6 +1833,7 @@
 typedef struct CK_GCM_PARAMS {
     CK_BYTE_PTR       pIv;
     CK_ULONG          ulIvLen;
+    CK_ULONG          ulIvBits;
     CK_BYTE_PTR       pAAD;
     CK_ULONG          ulAADLen;
     CK_ULONG          ulTagBits;
@@ -1962,7 +1963,7 @@
 typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR;
 
 typedef struct CK_TLS_MAC_PARAMS {
-    CK_MECHANISM_TYPE         prfMechanism;
+    CK_MECHANISM_TYPE         prfHashMechanism;
     CK_ULONG                  ulMacLength;
     CK_ULONG                  ulServerOrClient;
 } CK_TLS_MAC_PARAMS;
@@ -2000,3 +2001,4 @@
 
 #endif /* _PKCS11T_H_ */
 
+
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h	Thu Oct 10 10:57:42 2019 -0400
@@ -159,7 +159,6 @@
 /* include the platform dependent part of the header */
 #include "p11_md.h"
 
-#include "pkcs11.h"
 #include <jni.h>
 #include <jni_util.h>
 #include <stdarg.h>
@@ -296,6 +295,10 @@
 #define CLASS_TLS_PRF_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS"
 #define CLASS_TLS_MAC_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_MAC_PARAMS"
 
+/* function to update the CK_NSS_GCM_PARAMS in mechanism pointer with
+ * CK_GCM_PARAMS
+ */
+CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr);
 
 /* function to convert a PKCS#11 return value other than CK_OK into a Java Exception
  * or to throw a PKCS11RuntimeException
--- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h	Thu Oct 10 10:57:42 2019 -0400
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ */
+
 /*
  * reserved comment block
  * DO NOT REMOVE OR ALTER!
@@ -69,6 +73,7 @@
 #endif
 
 #include "pkcs11.h"
+#include "pkcs11gcm2.h"
 
 #include "jni.h"
 
--- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h	Thu Oct 10 10:57:42 2019 -0400
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ */
+
 /*
  * reserved comment block
  * DO NOT REMOVE OR ALTER!
@@ -77,6 +81,7 @@
 #endif /* CreateMutex */
 
 #include "pkcs11.h"
+#include "pkcs11gcm2.h"
 
 /* statement according to PKCS11 docu */
 #pragma pack(pop, cryptoki)
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/compiler/OopMapValue.java	Thu Oct 10 10:57:42 2019 -0400
@@ -47,7 +47,6 @@
   static int REGISTER_MASK_IN_PLACE;
 
   // Types of OopValues
-  static int UNUSED_VALUE;
   static int OOP_VALUE;
   static int NARROWOOP_VALUE;
   static int CALLEE_SAVED_VALUE;
@@ -70,7 +69,6 @@
     TYPE_MASK_IN_PLACE     = db.lookupIntConstant("OopMapValue::type_mask_in_place").intValue();
     REGISTER_MASK          = db.lookupIntConstant("OopMapValue::register_mask").intValue();
     REGISTER_MASK_IN_PLACE = db.lookupIntConstant("OopMapValue::register_mask_in_place").intValue();
-    UNUSED_VALUE           = db.lookupIntConstant("OopMapValue::unused_value").intValue();
     OOP_VALUE              = db.lookupIntConstant("OopMapValue::oop_value").intValue();
     NARROWOOP_VALUE        = db.lookupIntConstant("OopMapValue::narrowoop_value").intValue();
     CALLEE_SAVED_VALUE     = db.lookupIntConstant("OopMapValue::callee_saved_value").intValue();
@@ -78,7 +76,6 @@
   }
 
   public static abstract class OopTypes {
-    public static final OopTypes UNUSED_VALUE       = new OopTypes() { int getValue() { return OopMapValue.UNUSED_VALUE;       }};
     public static final OopTypes OOP_VALUE          = new OopTypes() { int getValue() { return OopMapValue.OOP_VALUE;          }};
     public static final OopTypes NARROWOOP_VALUE    = new OopTypes() { int getValue() { return OopMapValue.NARROWOOP_VALUE;         }};
     public static final OopTypes CALLEE_SAVED_VALUE = new OopTypes() { int getValue() { return OopMapValue.CALLEE_SAVED_VALUE; }};
@@ -111,8 +108,7 @@
 
   public OopTypes getType() {
     int which = (getValue() & TYPE_MASK_IN_PLACE);
-         if (which == UNUSED_VALUE) return OopTypes.UNUSED_VALUE;
-    else if (which == OOP_VALUE)    return OopTypes.OOP_VALUE;
+         if (which == OOP_VALUE)    return OopTypes.OOP_VALUE;
     else if (which == NARROWOOP_VALUE)   return OopTypes.NARROWOOP_VALUE;
     else if (which == CALLEE_SAVED_VALUE) return OopTypes.CALLEE_SAVED_VALUE;
     else if (which == DERIVED_OOP_VALUE)  return OopTypes.DERIVED_OOP_VALUE;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/NotificationThread.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,37 @@
+/*
+ * 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 sun.jvm.hotspot.runtime;
+
+
+import sun.jvm.hotspot.debugger.Address;
+
+public class NotificationThread extends JavaThread {
+    public NotificationThread(Address addr) {
+        super(addr);
+    }
+
+    public boolean isJavaThread() { return false; }
+
+}
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java	Thu Oct 10 10:57:42 2019 -0400
@@ -158,6 +158,7 @@
         }
         virtualConstructor.addMapping("JvmtiAgentThread", JvmtiAgentThread.class);
         virtualConstructor.addMapping("ServiceThread", ServiceThread.class);
+        virtualConstructor.addMapping("NotificationThread", NotificationThread.class);
     }
 
     public Threads() {
@@ -165,14 +166,14 @@
     }
 
     /** NOTE: this returns objects of type JavaThread, CompilerThread,
-      JvmtiAgentThread, and ServiceThread.
+      JvmtiAgentThread, NotificationThread, and ServiceThread.
       The latter four are subclasses of the former. Most operations
       (fetching the top frame, etc.) are only allowed to be performed on
       a "pure" JavaThread. For this reason, {@link
       sun.jvm.hotspot.runtime.JavaThread#isJavaThread} has been
       changed from the definition in the VM (which returns true for
       all of these thread types) to return true for JavaThreads and
-      false for the three subclasses. FIXME: should reconsider the
+      false for the four subclasses. FIXME: should reconsider the
       inheritance hierarchy; see {@link
       sun.jvm.hotspot.runtime.JavaThread#isJavaThread}. */
     public JavaThread getJavaThreadAt(int i) {
--- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/spi/HttpServerProvider.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/spi/HttpServerProvider.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -133,8 +133,9 @@
      * <ol>
      *
      *   <li><p> If the system property
-     *   {@code com.sun.net.httpserver.HttpServerProvider} is defined then it
-     *   is taken to be the fully-qualified name of a concrete provider class.
+     *   {@systemProperty com.sun.net.httpserver.HttpServerProvider}
+     *   is defined then it is taken to be the fully-qualified name
+     *   of a concrete provider class.
      *   The class is loaded and instantiated; if this process fails then an
      *   unspecified unchecked error or exception is thrown.  </p></li>
      *
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalManagement.java	Thu Oct 10 10:57:42 2019 -0400
@@ -36,6 +36,7 @@
 import javax.management.ObjectName;
 
 import org.graalvm.compiler.debug.TTY;
+import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig;
 import org.graalvm.compiler.hotspot.HotSpotGraalManagementRegistration;
 import org.graalvm.compiler.hotspot.HotSpotGraalRuntime;
 import org.graalvm.compiler.serviceprovider.ServiceProvider;
@@ -56,7 +57,7 @@
     HotSpotGraalManagement nextDeferred;
 
     @Override
-    public void initialize(HotSpotGraalRuntime runtime) {
+    public void initialize(HotSpotGraalRuntime runtime, GraalHotSpotVMConfig config) {
         if (bean == null) {
             if (runtime.getManagement() != this) {
                 throw new IllegalArgumentException("Cannot initialize a second management object for runtime " + runtime.getName());
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/HotSpotGraalRuntimeMBean.java	Thu Oct 10 10:57:42 2019 -0400
@@ -57,7 +57,7 @@
 /**
  * MBean used to access properties and operations of a {@link HotSpotGraalRuntime} instance.
  */
-final class HotSpotGraalRuntimeMBean implements DynamicMBean {
+public final class HotSpotGraalRuntimeMBean implements DynamicMBean {
 
     /**
      * The runtime instance to which this bean provides a management connection.
@@ -69,16 +69,16 @@
      */
     private final ObjectName objectName;
 
-    HotSpotGraalRuntimeMBean(ObjectName objectName, HotSpotGraalRuntime runtime) {
+    public HotSpotGraalRuntimeMBean(ObjectName objectName, HotSpotGraalRuntime runtime) {
         this.objectName = objectName;
         this.runtime = runtime;
     }
 
-    ObjectName getObjectName() {
+    public ObjectName getObjectName() {
         return objectName;
     }
 
-    HotSpotGraalRuntime getRuntime() {
+    public HotSpotGraalRuntime getRuntime() {
         return runtime;
     }
 
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/JMXServiceProvider.java	Wed Oct 09 10:58:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * 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.
- */
-
-
-package org.graalvm.compiler.hotspot.management;
-
-import static java.lang.Thread.currentThread;
-
-import java.lang.management.ManagementFactory;
-import java.util.List;
-
-import org.graalvm.compiler.serviceprovider.ServiceProvider;
-import org.graalvm.compiler.serviceprovider.JMXService;
-
-import com.sun.management.ThreadMXBean;
-
-/**
- * Implementation of {@link JMXService} for JDK 13 and later.
- */
-@ServiceProvider(JMXService.class)
-public class JMXServiceProvider extends JMXService {
-    private final ThreadMXBean threadMXBean = (ThreadMXBean) ManagementFactory.getThreadMXBean();
-
-    @Override
-    protected long getThreadAllocatedBytes(long id) {
-        return threadMXBean.getThreadAllocatedBytes(id);
-    }
-
-    @Override
-    protected long getCurrentThreadCpuTime() {
-        long[] times = threadMXBean.getThreadCpuTime(new long[]{currentThread().getId()});
-        return times[0];
-    }
-
-    @Override
-    protected boolean isThreadAllocatedMemorySupported() {
-        return threadMXBean.isThreadAllocatedMemorySupported();
-    }
-
-    @Override
-    protected boolean isCurrentThreadCpuTimeSupported() {
-        return threadMXBean.isThreadCpuTimeSupported();
-    }
-
-    @Override
-    protected List<String> getInputArguments() {
-        return ManagementFactory.getRuntimeMXBean().getInputArguments();
-    }
-}
--- a/src/jdk.internal.vm.compiler.management/share/classes/org.graalvm.compiler.hotspot.management/src/org/graalvm/compiler/hotspot/management/package-info.java	Wed Oct 09 10:58:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * 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.
- */
-
-/**
- * JDK 11 and later versioned overlay for the {@code jdk.internal.vm.compiler.management} module.
- * This cannot be used in JDK 10 where {@code jdk.internal.vm.compiler.management} is a
- * non-upgradeable module.
- */
-
-
-package org.graalvm.compiler.hotspot.management;
--- a/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/OptionsEncoder.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/jdk.internal.vm.compiler.libgraal/src/jdk/internal/vm/compiler/libgraal/OptionsEncoder.java	Thu Oct 10 10:57:42 2019 -0400
@@ -29,7 +29,7 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.Map;
 
 /**
@@ -122,7 +122,7 @@
      * @throws IllegalArgumentException if {@code input} cannot be decoded
      */
     public static Map<String, Object> decode(byte[] input) {
-        Map<String, Object> res = new HashMap<>();
+        Map<String, Object> res = new LinkedHashMap<>();
         try (DataInputStream in = new DataInputStream(new ByteArrayInputStream(input))) {
             final int size = in.readInt();
             for (int i = 0; i < size; i++) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.asm.aarch64/src/org/graalvm/compiler/asm/aarch64/AArch64MacroAssembler.java	Thu Oct 10 10:57:42 2019 -0400
@@ -25,6 +25,11 @@
 
 package org.graalvm.compiler.asm.aarch64;
 
+import static jdk.vm.ci.aarch64.AArch64.CPU;
+import static jdk.vm.ci.aarch64.AArch64.rscratch1;
+import static jdk.vm.ci.aarch64.AArch64.rscratch2;
+import static jdk.vm.ci.aarch64.AArch64.sp;
+import static jdk.vm.ci.aarch64.AArch64.zr;
 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.BASE_REGISTER_ONLY;
 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.EXTENDED_REGISTER_OFFSET;
 import static org.graalvm.compiler.asm.aarch64.AArch64Address.AddressingMode.IMMEDIATE_SCALED;
@@ -35,13 +40,6 @@
 import static org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler.AddressGenerationPlan.WorkPlan.NO_WORK;
 
 import org.graalvm.compiler.asm.BranchTargetOutOfBoundsException;
-
-import static jdk.vm.ci.aarch64.AArch64.CPU;
-import static jdk.vm.ci.aarch64.AArch64.r8;
-import static jdk.vm.ci.aarch64.AArch64.r9;
-import static jdk.vm.ci.aarch64.AArch64.sp;
-import static jdk.vm.ci.aarch64.AArch64.zr;
-
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.core.common.NumUtil;
 import org.graalvm.compiler.debug.GraalError;
@@ -52,7 +50,7 @@
 
 public class AArch64MacroAssembler extends AArch64Assembler {
 
-    private final ScratchRegister[] scratchRegister = new ScratchRegister[]{new ScratchRegister(r8), new ScratchRegister(r9)};
+    private final ScratchRegister[] scratchRegister = new ScratchRegister[]{new ScratchRegister(rscratch1), new ScratchRegister(rscratch2)};
 
     // Points to the next free scratch register
     private int nextFreeScratchRegister = 0;
@@ -1310,6 +1308,20 @@
         super.fmsub(size, dst, dst, d, n);
     }
 
+    /**
+     * dst = src1 * src2 + src3.
+     *
+     * @param size register size.
+     * @param dst floating point register. May not be null.
+     * @param src1 floating point register. May not be null.
+     * @param src2 floating point register. May not be null.
+     * @param src3 floating point register. May not be null.
+     */
+    @Override
+    public void fmadd(int size, Register dst, Register src1, Register src2, Register src3) {
+        super.fmadd(size, dst, src1, src2, src3);
+    }
+
     /* Branches */
 
     /**
@@ -1367,32 +1379,32 @@
                 case 64: {
                     // Be careful with registers: it's possible that x, y, and dst are the same
                     // register.
-                    Register rscratch1 = sc1.getRegister();
-                    Register rscratch2 = sc2.getRegister();
-                    mul(64, rscratch1, x, y);     // Result bits 0..63
-                    smulh(64, rscratch2, x, y);  // Result bits 64..127
+                    Register temp1 = sc1.getRegister();
+                    Register temp2 = sc2.getRegister();
+                    mul(64, temp1, x, y);     // Result bits 0..63
+                    smulh(64, temp2, x, y);  // Result bits 64..127
                     // Top is pure sign ext
-                    subs(64, zr, rscratch2, rscratch1, ShiftType.ASR, 63);
+                    subs(64, zr, temp2, temp1, ShiftType.ASR, 63);
                     // Copy all 64 bits of the result into dst
-                    mov(64, dst, rscratch1);
-                    mov(rscratch1, 0x80000000);
+                    mov(64, dst, temp1);
+                    mov(temp1, 0x80000000);
                     // Develop 0 (EQ), or 0x80000000 (NE)
-                    cmov(32, rscratch1, rscratch1, zr, ConditionFlag.NE);
-                    cmp(32, rscratch1, 1);
+                    cmov(32, temp1, temp1, zr, ConditionFlag.NE);
+                    cmp(32, temp1, 1);
                     // 0x80000000 - 1 => VS
                     break;
                 }
                 case 32: {
-                    Register rscratch1 = sc1.getRegister();
-                    smaddl(rscratch1, x, y, zr);
+                    Register temp1 = sc1.getRegister();
+                    smaddl(temp1, x, y, zr);
                     // Copy the low 32 bits of the result into dst
-                    mov(32, dst, rscratch1);
-                    subs(64, zr, rscratch1, rscratch1, ExtendType.SXTW, 0);
+                    mov(32, dst, temp1);
+                    subs(64, zr, temp1, temp1, ExtendType.SXTW, 0);
                     // NE => overflow
-                    mov(rscratch1, 0x80000000);
+                    mov(temp1, 0x80000000);
                     // Develop 0 (EQ), or 0x80000000 (NE)
-                    cmov(32, rscratch1, rscratch1, zr, ConditionFlag.NE);
-                    cmp(32, rscratch1, 1);
+                    cmov(32, temp1, temp1, zr, ConditionFlag.NE);
+                    cmp(32, temp1, 1);
                     // 0x80000000 - 1 => VS
                     break;
                 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64ArithmeticLIRGenerator.java	Thu Oct 10 10:57:42 2019 -0400
@@ -229,9 +229,12 @@
     }
 
     private Value emitMultiplyAddSub(AArch64ArithmeticOp op, Value a, Value b, Value c) {
-        assert isNumericInteger(a.getPlatformKind());
-        assert isNumericInteger(b.getPlatformKind());
-        assert isNumericInteger(c.getPlatformKind());
+        assert a.getPlatformKind() == b.getPlatformKind() && b.getPlatformKind() == c.getPlatformKind();
+        if (op == AArch64ArithmeticOp.ADD || op == AArch64ArithmeticOp.SUB) {
+            assert isNumericInteger(a.getPlatformKind());
+        } else if (op == AArch64ArithmeticOp.FADD) {
+            assert a.getPlatformKind() == AArch64Kind.SINGLE || a.getPlatformKind() == AArch64Kind.DOUBLE;
+        }
 
         Variable result = getLIRGen().newVariable(LIRKind.combine(a, b, c));
         AllocatableValue x = moveSp(asAllocatable(a));
@@ -447,6 +450,11 @@
     }
 
     @Override
+    public Value emitFusedMultiplyAdd(Value a, Value b, Value c) {
+        return emitMultiplyAddSub(AArch64ArithmeticOp.FADD, a, b, c);
+    }
+
+    @Override
     public Value emitCountLeadingZeros(Value value) {
         Variable result = getLIRGen().newVariable(LIRKind.combine(value).changeType(AArch64Kind.DWORD));
         getLIRGen().append(new AArch64BitManipulationOp(getLIRGen(), CLZ, result, asAllocatable(value)));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LIRGenerator.java	Thu Oct 10 10:57:42 2019 -0400
@@ -48,6 +48,10 @@
 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp;
 import org.graalvm.compiler.lir.aarch64.AArch64ArrayCompareToOp;
 import org.graalvm.compiler.lir.aarch64.AArch64ArrayEqualsOp;
+import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddLSEOp;
+import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddOp;
+import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndWriteOp;
+import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.CompareAndSwapOp;
 import org.graalvm.compiler.lir.aarch64.AArch64ByteSwapOp;
 import org.graalvm.compiler.lir.aarch64.AArch64Compare;
 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow;
@@ -59,10 +63,6 @@
 import org.graalvm.compiler.lir.aarch64.AArch64ControlFlow.TableSwitchOp;
 import org.graalvm.compiler.lir.aarch64.AArch64LIRFlagsVersioned;
 import org.graalvm.compiler.lir.aarch64.AArch64Move;
-import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddOp;
-import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndAddLSEOp;
-import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.CompareAndSwapOp;
-import org.graalvm.compiler.lir.aarch64.AArch64AtomicMove.AtomicReadAndWriteOp;
 import org.graalvm.compiler.lir.aarch64.AArch64Move.MembarOp;
 import org.graalvm.compiler.lir.aarch64.AArch64PauseOp;
 import org.graalvm.compiler.lir.aarch64.AArch64SpeculativeBarrier;
@@ -586,8 +586,15 @@
     }
 
     @Override
-    public void emitZeroMemory(Value address, Value length) {
-        // Value address is 8-byte aligned; Value length is multiple of 8.
-        append(new AArch64ZeroMemoryOp(asAllocatable(address), asAllocatable(length), false, -1));
+    public void emitZeroMemory(Value address, Value length, boolean isAligned) {
+        emitZeroMemory(address, length, isAligned, false, -1);
+    }
+
+    protected final void emitZeroMemory(Value address, Value length, boolean isAligned, boolean useDcZva, int zvaLength) {
+        RegisterValue regAddress = AArch64.r0.asValue(address.getValueKind());
+        RegisterValue regLength = AArch64.r1.asValue(length.getValueKind());
+        emitMove(regAddress, address);
+        emitMove(regLength, length);
+        append(new AArch64ZeroMemoryOp(regAddress, regLength, isAligned, useDcZva, zvaLength));
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LoweringProviderMixin.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.aarch64/src/org/graalvm/compiler/core/aarch64/AArch64LoweringProviderMixin.java	Thu Oct 10 10:57:42 2019 -0400
@@ -35,7 +35,7 @@
     }
 
     @Override
-    default int bulkZeroingStride() {
-        return 8;
+    default boolean supportsBulkZeroing() {
+        return true;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LIRGenerator.java	Thu Oct 10 10:57:42 2019 -0400
@@ -687,7 +687,7 @@
     }
 
     @Override
-    public void emitZeroMemory(Value address, Value length) {
+    public void emitZeroMemory(Value address, Value length, boolean isAligned) {
         RegisterValue lengthReg = AMD64.rcx.asValue(length.getValueKind());
         emitMove(lengthReg, length);
         append(new AMD64ZeroMemoryOp(asAddressValue(address), lengthReg));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LoweringProviderMixin.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.amd64/src/org/graalvm/compiler/core/amd64/AMD64LoweringProviderMixin.java	Thu Oct 10 10:57:42 2019 -0400
@@ -35,7 +35,7 @@
     }
 
     @Override
-    default int bulkZeroingStride() {
-        return 1;
+    default boolean supportsBulkZeroing() {
+        return true;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SparcLoweringProviderMixin.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.sparc/src/org/graalvm/compiler/core/sparc/SparcLoweringProviderMixin.java	Thu Oct 10 10:57:42 2019 -0400
@@ -35,7 +35,7 @@
     }
 
     @Override
-    default int bulkZeroingStride() {
-        return 0;
+    default boolean supportsBulkZeroing() {
+        return false;
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/CheckGraalInvariants.java	Thu Oct 10 10:57:42 2019 -0400
@@ -432,6 +432,16 @@
             try {
                 Class<?> c = Class.forName(className, true, CheckGraalInvariants.class.getClassLoader());
                 classes.add(c);
+            } catch (UnsupportedClassVersionError e) {
+                // graal-test.jar can contain classes compiled for different Java versions
+            } catch (NoClassDefFoundError e) {
+                if (!e.getMessage().contains("Could not initialize class")) {
+                    throw e;
+                } else {
+                    // A second or later attempt to initialize a class
+                    // results in this confusing error where the
+                    // original cause of initialization failure is lost
+                }
             } catch (Throwable t) {
                 tool.handleClassLoadingException(t);
             }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/GraphUtilOriginalValueTests.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,176 @@
+/*
+ * 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.core.test;
+
+import java.lang.invoke.ConstantCallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+
+import org.graalvm.compiler.nodes.util.GraphUtil;
+import org.junit.Assert;
+import org.junit.Test;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+
+import jdk.vm.ci.code.BailoutException;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+
+/**
+ * Unit tests derived from https://github.com/oracle/graal/pull/1690.
+ */
+public class GraphUtilOriginalValueTests extends CustomizedBytecodePatternTest {
+
+    static class LinkedNode {
+        LinkedNode next;
+    }
+
+    static class A extends LinkedNode {
+    }
+
+    static class B extends LinkedNode {
+    }
+
+    static class C extends LinkedNode {
+    }
+
+    public static Class<?> getLastClass(A a) {
+        LinkedNode current = a;
+        Class<?> currentKlass = null;
+        while (current != null) {
+            // This must not be folded to A.class
+            currentKlass = current.getClass();
+
+            current = current.next;
+        }
+        return currentKlass;
+    }
+
+    @Test
+    public void testGetClass() {
+        A a = new A();
+        a.next = new B();
+
+        test("getLastClass", a);
+    }
+
+    static final ConstantCallSite cs1 = init(A.class);
+    static final ConstantCallSite cs2 = init(B.class);
+    static final ConstantCallSite cs3 = init(C.class);
+
+    static ConstantCallSite init(Class<?> c) {
+        try {
+            return new ConstantCallSite(MethodHandles.lookup().unreflectConstructor(c.getDeclaredConstructor()));
+        } catch (Exception e) {
+            throw new InternalError(e);
+        }
+    }
+
+    public static boolean findTarget(MethodHandle key) {
+        ConstantCallSite cs = cs1;
+        while (cs != null) {
+            if (cs.getTarget() == key) {
+                return true;
+            }
+            if (cs == cs1) {
+                cs = cs2;
+            } else if (cs == cs2) {
+                cs = cs3;
+            } else {
+                cs = null;
+            }
+        }
+        return false;
+    }
+
+    @Test
+    public void testGetTarget() {
+        cs1.getTarget();
+        cs2.getTarget();
+        test("findTarget", cs3.getTarget());
+    }
+
+    @Override
+    protected byte[] generateClass(String internalClassName) {
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
+        cw.visit(52, ACC_SUPER | ACC_PUBLIC, internalClassName, null, "java/lang/Object", null);
+
+        String getDescriptor = "(Ljava/lang/Object;)V";
+        MethodVisitor m = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "unbalancedMonitors", getDescriptor, null, null);
+        Label loopHead = new Label();
+        Label end = new Label();
+        m.visitCode();
+
+        // @formatter:off
+        /*
+         * void unbalancedMonitors(Object o) {
+         *     monitorenter(o);
+         *     while (o.toString() != o) {
+         *         monitorexit(o);
+         *         o = o.toString();
+         *     }
+         * }
+         */
+        // @formatter:on
+
+        m.visitVarInsn(ALOAD, 0);
+        m.visitInsn(MONITORENTER);
+        m.visitLabel(loopHead);
+        m.visitVarInsn(ALOAD, 0);
+        m.visitInsn(MONITOREXIT);
+        m.visitVarInsn(ALOAD, 0);
+        m.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false);
+        m.visitVarInsn(ALOAD, 0);
+        m.visitJumpInsn(IF_ACMPEQ, end);
+        m.visitVarInsn(ALOAD, 0);
+        m.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false);
+        m.visitVarInsn(ASTORE, 0);
+        m.visitJumpInsn(GOTO, loopHead);
+        m.visitLabel(end);
+        m.visitInsn(RETURN);
+        m.visitMaxs(2, 2);
+        m.visitEnd();
+
+        cw.visitEnd();
+        return cw.toByteArray();
+    }
+
+    /**
+     * Tests that the use of {@link GraphUtil#originalValue} in parsing MONITOREXIT correctly
+     * detects unbalanced monitors.
+     */
+    @Test
+    public void testUnbalancedMonitors() throws ClassNotFoundException {
+        Class<?> testClass = getClass("UnbalancedMonitors");
+        ResolvedJavaMethod t1 = getResolvedJavaMethod(testClass, "unbalancedMonitors");
+        try {
+            parseForCompile(t1);
+            Assert.fail("expected a " + BailoutException.class.getName());
+        } catch (BailoutException e) {
+            String msg = e.getMessage();
+            Assert.assertTrue(msg, msg.contains("unbalanced monitors"));
+        }
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifySystemPropertyUsage.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.test/src/org/graalvm/compiler/core/test/VerifySystemPropertyUsage.java	Thu Oct 10 10:57:42 2019 -0400
@@ -87,8 +87,8 @@
         } else if (holderQualified.equals("org.graalvm.compiler.hotspot.JVMCIVersionCheck") && caller.getName().equals("main")) {
             // The main method in JVMCIVersionCheck is only called from the shell
             return;
-        } else if (packageName.startsWith("com.oracle.truffle") || packageName.startsWith("org.graalvm.polyglot")) {
-            // Truffle and Polyglot do not depend on JVMCI so cannot use
+        } else if (packageName.startsWith("com.oracle.truffle") || packageName.startsWith("org.graalvm.polyglot") || packageName.startsWith("org.graalvm.home")) {
+            // Truffle and SDK do not depend on JVMCI so they cannot use
             // Services.getSavedProperties()
             return;
         } else if (packageName.startsWith("com.oracle.svm")) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphOutputTest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph.test/src/org/graalvm/compiler/graph/test/graphio/GraphOutputTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -40,7 +40,10 @@
 import java.util.Objects;
 import org.graalvm.graphio.GraphOutput;
 import org.graalvm.graphio.GraphStructure;
+import org.graalvm.graphio.GraphTypes;
+import static org.junit.Assert.assertSame;
 import org.junit.Test;
+import java.lang.reflect.Field;
 
 public final class GraphOutputTest {
 
@@ -116,6 +119,18 @@
         assertArrayEquals(expected.toByteArray(), embedded.toByteArray());
     }
 
+    @Test
+    @SuppressWarnings({"static-method", "unchecked"})
+    public void testClassOfEnumValueWithImplementation() throws ClassNotFoundException, ReflectiveOperationException {
+        Class<? extends GraphTypes> defaultTypesClass = (Class<? extends GraphTypes>) Class.forName("org.graalvm.graphio.DefaultGraphTypes");
+        Field f = defaultTypesClass.getDeclaredField("DEFAULT");
+        f.setAccessible(true);
+        GraphTypes types = (GraphTypes) f.get(null);
+
+        Object clazz = types.enumClass(CustomEnum.ONE);
+        assertSame(CustomEnum.class, clazz);
+    }
+
     private static ByteBuffer generateData(int size) {
         ByteBuffer buffer = ByteBuffer.allocate(size);
         for (int i = 0; i < size; i++) {
@@ -281,4 +296,20 @@
 
     private static final class MockGraph {
     }
+
+    private enum CustomEnum {
+        ONE() {
+            @Override
+            public String toString() {
+                return "one";
+            }
+        },
+
+        TWO() {
+            @Override
+            public String toString() {
+                return "two";
+            }
+        }
+    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeClass.java	Thu Oct 10 10:57:42 2019 -0400
@@ -741,6 +741,7 @@
             } else {
                 Object objectA = data.getObject(a, i);
                 Object objectB = data.getObject(b, i);
+                assert !isLambda(objectA) || !isLambda(objectB) : "lambdas are not permitted in fields of " + this.toString();
                 if (objectA != objectB) {
                     if (objectA != null && objectB != null) {
                         if (!deepEquals0(objectA, objectB)) {
@@ -755,6 +756,11 @@
         return true;
     }
 
+    private static boolean isLambda(Object obj) {
+        // This needs to be consistent with InnerClassLambdaMetafactory constructor.
+        return obj != null && obj.getClass().getSimpleName().contains("$$Lambda$");
+    }
+
     public boolean isValid(Position pos, NodeClass<?> from, Edges fromEdges) {
         if (this == from) {
             return true;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeList.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeList.java	Thu Oct 10 10:57:42 2019 -0400
@@ -122,10 +122,6 @@
         size = newSize;
     }
 
-    public boolean isList() {
-        return true;
-    }
-
     protected abstract void update(T oldNode, T newNode);
 
     public abstract Edges.Type getEdgesType();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.graph/src/org/graalvm/compiler/graph/NodeMap.java	Thu Oct 10 10:57:42 2019 -0400
@@ -95,6 +95,9 @@
 
     public void set(Node node, T value) {
         assert check(node);
+        if (!node.isAlive()) {
+            throw new VerificationError("this node is not alive: " + node);
+        }
         values[getNodeId(node)] = value;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotBackendFactory.java	Thu Oct 10 10:57:42 2019 -0400
@@ -192,7 +192,7 @@
                         replacements,
                         options);
         AArch64GraphBuilderPlugins.register(plugins, replacements.getDefaultReplacementBytecodeProvider(), false,
-                        /* registerMathPlugins */true);
+                        /* registerMathPlugins */true, /* emitJDK9StringSubstitutions */true, config.useFMAIntrinsics);
         return plugins;
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotLIRGenerator.java	Thu Oct 10 10:57:42 2019 -0400
@@ -84,7 +84,6 @@
 import org.graalvm.compiler.lir.aarch64.AArch64PrefetchOp;
 import org.graalvm.compiler.lir.aarch64.AArch64RestoreRegistersOp;
 import org.graalvm.compiler.lir.aarch64.AArch64SaveRegistersOp;
-import org.graalvm.compiler.lir.aarch64.AArch64ZeroMemoryOp;
 import org.graalvm.compiler.lir.gen.LIRGenerationResult;
 import org.graalvm.compiler.options.OptionValues;
 
@@ -544,7 +543,7 @@
     }
 
     @Override
-    public void emitZeroMemory(Value address, Value length) {
+    public void emitZeroMemory(Value address, Value length, boolean isAligned) {
         int dczidValue = config.psrInfoDczidValue;
         EnumSet<AArch64.Flag> flags = ((AArch64) target().arch).getFlags();
 
@@ -563,7 +562,6 @@
             useDcZva = false;
         }
 
-        // Value address is 8-byte aligned; Value length is multiple of 8.
-        append(new AArch64ZeroMemoryOp(asAllocatable(address), asAllocatable(length), useDcZva, zvaLength));
+        emitZeroMemory(address, length, isAligned, useDcZva, zvaLength);
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotRegisterAllocationConfig.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.aarch64/src/org/graalvm/compiler/hotspot/aarch64/AArch64HotSpotRegisterAllocationConfig.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -45,7 +45,10 @@
 import static jdk.vm.ci.aarch64.AArch64.r25;
 import static jdk.vm.ci.aarch64.AArch64.r26;
 import static jdk.vm.ci.aarch64.AArch64.r28;
+import static jdk.vm.ci.aarch64.AArch64.r29;
 import static jdk.vm.ci.aarch64.AArch64.r3;
+import static jdk.vm.ci.aarch64.AArch64.r30;
+import static jdk.vm.ci.aarch64.AArch64.r31;
 import static jdk.vm.ci.aarch64.AArch64.r4;
 import static jdk.vm.ci.aarch64.AArch64.r5;
 import static jdk.vm.ci.aarch64.AArch64.r6;
@@ -96,12 +99,22 @@
 
 public class AArch64HotSpotRegisterAllocationConfig extends RegisterAllocationConfig {
 
+    /**
+     * Excluding r27 is a temporary solution until we exclude r27 unconditionally at
+     * {@link jdk.vm.ci.hotspot.aarch64.AArch64HotSpotRegisterConfig}.
+     *
+     * The underlying reason is that HotSpot does not intend to support r27 as an allocatable
+     * register. This register is excluded from callee-saved register at
+     * cpu/aarch64/sharedRuntime_aarch64.cpp:RegisterSaver::save_live_registers, and may lead to
+     * dereferencing unknown value from the stack at
+     * share/runtime/stackValue.cpp:StackValue::create_stack_value during deoptimization.
+     */
     // @formatter:off
     static final Register[] registerAllocationOrder = {
         r0,  r1,  r2,  r3,  r4,  r5,  r6,  r7,
         r8,  r9,  r10, r11, r12, r13, r14, r15,
         r16, r17, r18, r19, r20, r21, r22, r23,
-        r24, r25, r26, /* r27, */ r28, /* r29, r30, r31 */
+        r24, r25, r26, /* r27, */ r28, r29, r30, r31,
 
         v0,  v1,  v2,  v3,  v4,  v5,  v6,  v7,
         v8,  v9,  v10, v11, v12, v13, v14, v15,
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/MitigateExceedingMaxOopMapStackOffsetTest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.lir.test/src/org/graalvm/compiler/hotspot/lir/test/MitigateExceedingMaxOopMapStackOffsetTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -76,23 +76,22 @@
             // Place reference slots at top and bottom of virtual frame
             // with primitive slots in the middle. This tests that slot
             // partitioning works.
+            AllocatableValue srcObject = gen.emitLoadConstant(objectLirKind, objectConstant);
             for (int i = 0; i < numReferenceSlots / 2; i++) {
-                AllocatableValue src = gen.emitLoadConstant(objectLirKind, objectConstant);
                 VirtualStackSlot slot = frameMapBuilder.allocateSpillSlot(objectLirKind);
                 slotList.add(slot);
-                gen.emitMove(slot, src);
+                gen.emitMove(slot, srcObject);
             }
+            AllocatableValue srcPrimitive = gen.emitLoadConstant(objectLirKind, primitiveConstant);
             for (int i = 0; i < numPrimitiveSlots; i++) {
-                AllocatableValue src = gen.emitLoadConstant(objectLirKind, primitiveConstant);
                 VirtualStackSlot slot = frameMapBuilder.allocateSpillSlot(primitiveLirKind);
                 slotList.add(slot);
-                gen.emitMove(slot, src);
+                gen.emitMove(slot, srcPrimitive);
             }
             for (int i = numReferenceSlots / 2; i < numReferenceSlots; i++) {
-                AllocatableValue src = gen.emitLoadConstant(objectLirKind, objectConstant);
                 VirtualStackSlot slot = frameMapBuilder.allocateSpillSlot(objectLirKind);
                 slotList.add(slot);
-                gen.emitMove(slot, src);
+                gen.emitMove(slot, srcObject);
             }
             slots = slotList.toArray(new AllocatableValue[slotList.size()]);
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Thu Oct 10 10:57:42 2019 -0400
@@ -64,6 +64,7 @@
 import jdk.vm.ci.meta.MetaUtil;
 import jdk.vm.ci.meta.MethodHandleAccessProvider.IntrinsicMethod;
 import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.sparc.SPARC;
 
 /**
  * Checks the intrinsics implemented by Graal against the set of intrinsics declared by HotSpot. The
@@ -375,7 +376,7 @@
                 add(ignore,
                                 "java/lang/Math.fma(DDD)D",
                                 "java/lang/Math.fma(FFF)F");
-            } else if (!(arch instanceof AMD64)) {
+            } else if (arch instanceof SPARC) {
                 add(toBeInvestigated,
                                 "java/lang/Math.fma(DDD)D",
                                 "java/lang/Math.fma(FFF)F");
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/ConstantPoolSubstitutionsTests.java	Thu Oct 10 10:57:42 2019 -0400
@@ -25,8 +25,6 @@
 
 package org.graalvm.compiler.hotspot.test;
 
-import static org.graalvm.compiler.serviceprovider.JavaVersionUtil.JAVA_SPEC;
-
 import java.lang.reflect.Method;
 
 import org.graalvm.compiler.core.test.GraalCompilerTest;
@@ -75,9 +73,27 @@
         return graph;
     }
 
+    private static String getMiscPackage() {
+        if (JavaVersionUtil.JAVA_SPEC <= 8) {
+            return "sun.misc";
+        }
+        try {
+            String miscPackage = "jdk.internal.access";
+            Class.forName(miscPackage + ".SharedSecrets");
+            return miscPackage;
+        } catch (ClassNotFoundException e) {
+            try {
+                String miscPackage = "jdk.internal.misc";
+                Class.forName(miscPackage + ".SharedSecrets");
+                return miscPackage;
+            } catch (ClassNotFoundException ex) {
+            }
+            throw new AssertionError(e);
+        }
+    }
+
     private static Object getConstantPoolForObject() {
-        String miscPackage = JavaVersionUtil.JAVA_SPEC <= 8 ? "sun.misc"
-                        : (JavaVersionUtil.JAVA_SPEC <= 11 ? "jdk.internal.misc" : "jdk.internal.access");
+        String miscPackage = getMiscPackage();
         try {
             Class<?> sharedSecretsClass = Class.forName(miscPackage + ".SharedSecrets");
             Class<?> javaLangAccessClass = Class.forName(miscPackage + ".JavaLangAccess");
@@ -112,8 +128,7 @@
      * This test uses some non-public API.
      */
     private static void addExports(Class<?> c) {
-        String packageName = JAVA_SPEC <= 11 ? "jdk.internal.misc" : "jdk.internal.access";
-        ModuleSupport.exportPackageTo(String.class, packageName, c);
+        ModuleSupport.exportPackageTo(String.class, getMiscPackage(), c);
         ModuleSupport.exportPackageTo(String.class, "jdk.internal.reflect", c);
     }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/GraalHotSpotVMConfig.java	Thu Oct 10 10:57:42 2019 -0400
@@ -321,6 +321,7 @@
     public final int jvmciCountersThreadOffset = getFieldOffset("JavaThread::_jvmci_counters", Integer.class, "jlong*");
     public final int doingUnsafeAccessOffset = getFieldOffset("JavaThread::_doing_unsafe_access", Integer.class, "bool", Integer.MAX_VALUE);
     public final int javaThreadReservedStackActivationOffset = versioned.javaThreadReservedStackActivationOffset;
+    public final int jniEnvironmentOffset = getFieldOffset("JavaThread::_jni_environment", Integer.class, "JNIEnv", Integer.MIN_VALUE);
 
     public boolean requiresReservedStackCheck(List<ResolvedJavaMethod> methods) {
         if (enableStackReservedZoneAddress != 0 && methods != null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalManagementRegistration.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalManagementRegistration.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -35,7 +35,7 @@
      * Completes the initialization of this registration by recording the
      * {@link HotSpotGraalRuntime} the MBean will provide an JMX interface to.
      */
-    void initialize(HotSpotGraalRuntime runtime);
+    void initialize(HotSpotGraalRuntime runtime, GraalHotSpotVMConfig config);
 
     /**
      * Polls this registration to see if the MBean is registered in a MBean server.
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/HotSpotGraalRuntime.java	Thu Oct 10 10:57:42 2019 -0400
@@ -35,6 +35,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Supplier;
 
 import jdk.internal.vm.compiler.collections.EconomicMap;
 import jdk.internal.vm.compiler.collections.EconomicSet;
@@ -97,6 +98,10 @@
 public final class HotSpotGraalRuntime implements HotSpotGraalRuntimeProvider {
 
     private static final boolean IS_AOT = Boolean.parseBoolean(Services.getSavedProperties().get("com.oracle.graalvm.isaot"));
+    /**
+     * A factory for {@link HotSpotGraalManagementRegistration} injected by {@code LibGraalFeature}.
+     */
+    private static final Supplier<HotSpotGraalManagementRegistration> AOT_INJECTED_MANAGEMENT = null;
 
     private static boolean checkArrayIndexScaleInvariants(MetaAccessProvider metaAccess) {
         assert metaAccess.getArrayIndexScale(JavaKind.Byte) == 1;
@@ -165,12 +170,12 @@
         compilerConfigurationName = compilerConfigurationFactory.getName();
 
         if (IS_AOT) {
-            management = null;
+            management = AOT_INJECTED_MANAGEMENT == null ? null : AOT_INJECTED_MANAGEMENT.get();
         } else {
             management = GraalServices.loadSingle(HotSpotGraalManagementRegistration.class, false);
-            if (management != null) {
-                management.initialize(this);
-            }
+        }
+        if (management != null) {
+            management.initialize(this, config);
         }
 
         BackendMap backendMap = compilerConfigurationFactory.createBackendMap();
@@ -292,13 +297,15 @@
                 HotSpotResolvedObjectType type = ((HotSpotResolvedJavaMethod) compilable).getDeclaringClass();
                 if (type instanceof HotSpotResolvedJavaType) {
                     Class<?> clazz = runtime().getMirror(type);
-                    try {
-                        ClassLoader cl = clazz.getClassLoader();
-                        if (cl != null) {
-                            loaders.add(cl);
+                    if (clazz != null) {
+                        try {
+                            ClassLoader cl = clazz.getClassLoader();
+                            if (cl != null) {
+                                loaders.add(cl);
+                            }
+                        } catch (SecurityException e) {
+                            // This loader can obviously not be used for resolving class names
                         }
-                    } catch (SecurityException e) {
-                        // This loader can obviously not be used for resolving class names
                     }
                 }
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/JVMCIVersionCheck.java	Thu Oct 10 10:57:42 2019 -0400
@@ -43,7 +43,7 @@
  */
 public final class JVMCIVersionCheck {
 
-    private static final Version JVMCI8_MIN_VERSION = new Version3(19, 2, 1);
+    private static final Version JVMCI8_MIN_VERSION = new Version3(19, 3, 2);
 
     public interface Version {
         boolean isLessThan(Version other);
@@ -230,6 +230,17 @@
                     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-")) {
+                // 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);
+                    }
+                    return;
+                }
+                failVersionCheck(props, 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 Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/meta/HotSpotGraphBuilderPlugins.java	Thu Oct 10 10:57:42 2019 -0400
@@ -254,7 +254,7 @@
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
                 ValueNode callSite = receiver.get();
-                ValueNode folded = CallSiteTargetNode.tryFold(GraphUtil.originalValue(callSite), b.getMetaAccess(), b.getAssumptions());
+                ValueNode folded = CallSiteTargetNode.tryFold(GraphUtil.originalValue(callSite, true), b.getMetaAccess(), b.getAssumptions());
                 if (folded != null) {
                     b.addPush(JavaKind.Object, folded);
                 } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/NewObjectSnippets.java	Thu Oct 10 10:57:42 2019 -0400
@@ -359,12 +359,12 @@
                     @ConstantParameter Register threadRegister,
                     @ConstantParameter boolean maybeUnroll,
                     @ConstantParameter String typeContext,
-                    @ConstantParameter int bulkZeroingStride,
+                    @ConstantParameter boolean supportsBulkZeroing,
                     @ConstantParameter Counters counters) {
         // Primitive array types are eagerly pre-resolved. We can use a floating load.
         KlassPointer picHub = LoadConstantIndirectlyNode.loadKlass(hub);
         return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
-                        emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, bulkZeroingStride, counters);
+                        emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, supportsBulkZeroing, counters);
     }
 
     @Snippet
@@ -378,12 +378,12 @@
                     @ConstantParameter Register threadRegister,
                     @ConstantParameter boolean maybeUnroll,
                     @ConstantParameter String typeContext,
-                    @ConstantParameter int bulkZeroingStride,
+                    @ConstantParameter boolean supportsBulkZeroing,
                     @ConstantParameter Counters counters) {
         // Array type would be resolved by dominating resolution.
         KlassPointer picHub = LoadConstantIndirectlyFixedNode.loadKlass(hub);
         return allocateArrayImpl(picHub, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
-                        emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, bulkZeroingStride, counters);
+                        emitMemoryBarrier, threadRegister, maybeUnroll, typeContext, supportsBulkZeroing, counters);
     }
 
     @Snippet
@@ -397,7 +397,7 @@
                     @ConstantParameter Register threadRegister,
                     @ConstantParameter boolean maybeUnroll,
                     @ConstantParameter String typeContext,
-                    @ConstantParameter int bulkZeroingStride,
+                    @ConstantParameter boolean supportsBulkZeroing,
                     @ConstantParameter Counters counters) {
         Object result = allocateArrayImpl(hub,
                         length,
@@ -408,7 +408,7 @@
                         emitMemoryBarrier, threadRegister,
                         maybeUnroll,
                         typeContext,
-                        bulkZeroingStride,
+                        supportsBulkZeroing,
                         counters);
         return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length);
     }
@@ -432,7 +432,7 @@
                     Register threadRegister,
                     boolean maybeUnroll,
                     String typeContext,
-                    int bulkZeroingStride,
+                    boolean supportsBulkZeroing,
                     Counters counters) {
         Object result;
         long allocationSize = arrayAllocationSize(length, headerSize, log2ElementSize);
@@ -448,7 +448,7 @@
             if (theCounters != null && theCounters.arrayLoopInit != null) {
                 theCounters.arrayLoopInit.inc();
             }
-            result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, emitMemoryBarrier, maybeUnroll, bulkZeroingStride, counters);
+            result = formatArray(hub, allocationSize, length, headerSize, top, prototypeMarkWord, fillContents, emitMemoryBarrier, maybeUnroll, supportsBulkZeroing, counters);
         } else {
             result = newArrayStub(hub, length);
         }
@@ -513,11 +513,11 @@
                     @ConstantParameter Register threadRegister,
                     @ConstantParameter JavaKind knownElementKind,
                     @ConstantParameter int knownLayoutHelper,
-                    @ConstantParameter int bulkZeroingStride,
+                    @ConstantParameter boolean supportsBulkZeroing,
                     Word prototypeMarkWord,
                     @ConstantParameter Counters counters) {
         Object result = allocateArrayDynamicImpl(elementType, voidClass, length, fillContents, emitMemoryBarrier, threadRegister, knownElementKind,
-                        knownLayoutHelper, bulkZeroingStride, prototypeMarkWord, counters);
+                        knownLayoutHelper, supportsBulkZeroing, prototypeMarkWord, counters);
         return result;
     }
 
@@ -529,7 +529,7 @@
                     Register threadRegister,
                     JavaKind knownElementKind,
                     int knownLayoutHelper,
-                    int bulkZeroingStride,
+                    boolean supportsBulkZeroing,
                     Word prototypeMarkWord,
                     Counters counters) {
         /*
@@ -574,7 +574,7 @@
         int log2ElementSize = (layoutHelper >> layoutHelperLog2ElementSizeShift(INJECTED_VMCONFIG)) & layoutHelperLog2ElementSizeMask(INJECTED_VMCONFIG);
 
         Object result = allocateArrayImpl(nonNullKlass, length, prototypeMarkWord, headerSize, log2ElementSize, fillContents,
-                        emitMemoryBarrier, threadRegister, false, "dynamic type", bulkZeroingStride, counters);
+                        emitMemoryBarrier, threadRegister, false, "dynamic type", supportsBulkZeroing, counters);
         return piArrayCastToSnippetReplaceeStamp(verifyOop(result), length);
     }
 
@@ -627,16 +627,16 @@
      * @param endOffset offset to stop zeroing (exclusive). May not be word aligned.
      * @param isEndOffsetConstant is {@code endOffset} known to be constant in the snippet
      * @param manualUnroll maximally unroll zeroing
-     * @param bulkZeroingStride stride of bulk zeroing supported by the backend
+     * @param supportsBulkZeroing whether bulk zeroing is supported by the backend
      */
     private static void zeroMemory(Word memory, int startOffset, long endOffset, boolean isEndOffsetConstant, boolean manualUnroll,
-                    int bulkZeroingStride, Counters counters) {
-        fillMemory(0, memory, startOffset, endOffset, isEndOffsetConstant, manualUnroll, bulkZeroingStride, counters);
+                    boolean supportsBulkZeroing, Counters counters) {
+        fillMemory(0, memory, startOffset, endOffset, isEndOffsetConstant, manualUnroll, supportsBulkZeroing, counters);
     }
 
-    private static void fillMemory(long value, Word memory, int startOffset, long offsetLimit, boolean constantOffsetLimit, boolean manualUnroll,
-                    int bulkZeroingStride, Counters counters) {
-        ReplacementsUtil.runtimeAssert((offsetLimit & 0x7) == 0, "unaligned object size");
+    private static void fillMemory(long value, Word memory, int startOffset, long endOffset, boolean constantOffsetLimit, boolean manualUnroll,
+                    boolean supportsBulkZeroing, Counters counters) {
+        ReplacementsUtil.runtimeAssert((endOffset & 0x7) == 0, "unaligned object size");
         int offset = startOffset;
         if ((offset & 0x7) != 0) {
             memory.writeInt(offset, (int) value, LocationIdentity.init());
@@ -644,7 +644,7 @@
         }
         ReplacementsUtil.runtimeAssert((offset & 0x7) == 0, "unaligned offset");
         Counters theCounters = counters;
-        if (manualUnroll && ((offsetLimit - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
+        if (manualUnroll && ((endOffset - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
             ReplacementsUtil.staticAssert(!constantOffsetLimit, "size shouldn't be constant at instantiation time");
             // This case handles arrays of constant length. Instead of having a snippet variant for
             // each length, generate a chain of stores of maximum length. Once it's inlined the
@@ -655,7 +655,7 @@
 
             explodeLoop();
             for (int i = 0; i < MAX_UNROLLED_OBJECT_ZEROING_STORES; i++, offset += 8) {
-                if (offset == offsetLimit) {
+                if (offset == endOffset) {
                     break;
                 }
                 memory.initializeLong(offset, value, LocationIdentity.init());
@@ -663,13 +663,13 @@
         } else {
             // Use Word instead of int to avoid extension to long in generated code
             Word off = WordFactory.signed(offset);
-            if (bulkZeroingStride > 0 && value == 0 && probability(SLOW_PATH_PROBABILITY, (offsetLimit - offset) >= getMinimalBulkZeroingSize(INJECTED_OPTIONVALUES))) {
+            if (supportsBulkZeroing && value == 0 && probability(SLOW_PATH_PROBABILITY, (endOffset - offset) >= getMinimalBulkZeroingSize(INJECTED_OPTIONVALUES))) {
                 if (theCounters != null && theCounters.instanceBulkInit != null) {
                     theCounters.instanceBulkInit.inc();
                 }
-                ZeroMemoryNode.zero(memory.add(off), offsetLimit - offset, LocationIdentity.init());
+                ZeroMemoryNode.zero(memory.add(off), endOffset - offset, true, LocationIdentity.init());
             } else {
-                if (constantOffsetLimit && ((offsetLimit - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
+                if (constantOffsetLimit && ((endOffset - offset) / 8) <= MAX_UNROLLED_OBJECT_ZEROING_STORES) {
                     if (theCounters != null && theCounters.instanceSeqInit != null) {
                         theCounters.instanceSeqInit.inc();
                     }
@@ -679,7 +679,7 @@
                         theCounters.instanceLoopInit.inc();
                     }
                 }
-                for (; off.rawValue() < offsetLimit; off = off.add(8)) {
+                for (; off.rawValue() < endOffset; off = off.add(8)) {
                     memory.initializeLong(off, value, LocationIdentity.init());
                 }
             }
@@ -703,7 +703,7 @@
      * @param manualUnroll maximally unroll zeroing
      */
     private static void fillWithGarbage(Word memory, int startOffset, long endOffset, boolean isEndOffsetConstant, boolean manualUnroll, Counters counters) {
-        fillMemory(0xfefefefefefefefeL, memory, startOffset, endOffset, isEndOffsetConstant, manualUnroll, 0, counters);
+        fillMemory(0xfefefefefefefefeL, memory, startOffset, endOffset, isEndOffsetConstant, manualUnroll, false, counters);
     }
 
     /**
@@ -720,7 +720,7 @@
         Word prototypeMarkWord = useBiasedLocking(INJECTED_VMCONFIG) ? hub.readWord(prototypeMarkWordOffset(INJECTED_VMCONFIG), PROTOTYPE_MARK_WORD_LOCATION) : compileTimePrototypeMarkWord;
         initializeObjectHeader(memory, prototypeMarkWord, hub);
         if (fillContents) {
-            zeroMemory(memory, instanceHeaderSize(INJECTED_VMCONFIG), size, constantSize, false, 0, counters);
+            zeroMemory(memory, instanceHeaderSize(INJECTED_VMCONFIG), size, constantSize, false, false, counters);
         } else if (REPLACEMENTS_ASSERTIONS_ENABLED) {
             fillWithGarbage(memory, instanceHeaderSize(INJECTED_VMCONFIG), size, constantSize, false, counters);
         }
@@ -767,7 +767,7 @@
                     boolean fillContents,
                     boolean emitMemoryBarrier,
                     boolean maybeUnroll,
-                    int bulkZeroingStride,
+                    boolean supportsBulkZeroing,
                     Counters counters) {
         memory.writeInt(arrayLengthOffset(INJECTED_VMCONFIG), length, LocationIdentity.init());
         /*
@@ -776,7 +776,7 @@
          */
         initializeObjectHeader(memory, prototypeMarkWord, hub);
         if (fillContents) {
-            zeroMemory(memory, headerSize, allocationSize, false, maybeUnroll, bulkZeroingStride, counters);
+            zeroMemory(memory, headerSize, allocationSize, false, maybeUnroll, supportsBulkZeroing, counters);
         } else if (REPLACEMENTS_ASSERTIONS_ENABLED) {
             fillWithGarbage(memory, headerSize, allocationSize, false, maybeUnroll, counters);
         }
@@ -897,7 +897,7 @@
             args.addConst("threadRegister", registers.getThreadRegister());
             args.addConst("maybeUnroll", length.isConstant());
             args.addConst("typeContext", ProfileAllocations.getValue(localOptions) ? arrayType.toJavaName(false) : "");
-            args.addConst("bulkZeroingStride", tool.getLowerer().bulkZeroingStride());
+            args.addConst("supportsBulkZeroing", tool.getLowerer().supportsBulkZeroing());
             args.addConst("counters", counters);
             SnippetTemplate template = template(newArrayNode, args);
             graph.getDebug().log("Lowering allocateArray in %s: node=%s, template=%s, arguments=%s", graph, newArrayNode, template, args);
@@ -941,7 +941,7 @@
             } else {
                 args.addConst("knownLayoutHelper", 0);
             }
-            args.addConst("bulkZeroingStride", tool.getLowerer().bulkZeroingStride());
+            args.addConst("supportsBulkZeroing", tool.getLowerer().supportsBulkZeroing());
             args.add("prototypeMarkWord", lookupArrayClass(tool, JavaKind.Object).prototypeMarkWord());
             args.addConst("counters", counters);
             SnippetTemplate template = template(newArrayNode, args);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BciBlockMapping.java	Thu Oct 10 10:57:42 2019 -0400
@@ -26,27 +26,108 @@
 
 import static org.graalvm.compiler.bytecode.Bytecodes.AALOAD;
 import static org.graalvm.compiler.bytecode.Bytecodes.AASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.ACONST_NULL;
+import static org.graalvm.compiler.bytecode.Bytecodes.ALOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.ALOAD_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.ALOAD_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.ALOAD_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.ALOAD_3;
 import static org.graalvm.compiler.bytecode.Bytecodes.ANEWARRAY;
 import static org.graalvm.compiler.bytecode.Bytecodes.ARETURN;
 import static org.graalvm.compiler.bytecode.Bytecodes.ARRAYLENGTH;
+import static org.graalvm.compiler.bytecode.Bytecodes.ASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.ASTORE_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.ASTORE_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.ASTORE_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.ASTORE_3;
 import static org.graalvm.compiler.bytecode.Bytecodes.ATHROW;
 import static org.graalvm.compiler.bytecode.Bytecodes.BALOAD;
 import static org.graalvm.compiler.bytecode.Bytecodes.BASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.BIPUSH;
+import static org.graalvm.compiler.bytecode.Bytecodes.BREAKPOINT;
 import static org.graalvm.compiler.bytecode.Bytecodes.CALOAD;
 import static org.graalvm.compiler.bytecode.Bytecodes.CASTORE;
 import static org.graalvm.compiler.bytecode.Bytecodes.CHECKCAST;
+import static org.graalvm.compiler.bytecode.Bytecodes.D2F;
+import static org.graalvm.compiler.bytecode.Bytecodes.D2I;
+import static org.graalvm.compiler.bytecode.Bytecodes.D2L;
+import static org.graalvm.compiler.bytecode.Bytecodes.DADD;
 import static org.graalvm.compiler.bytecode.Bytecodes.DALOAD;
 import static org.graalvm.compiler.bytecode.Bytecodes.DASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.DCMPG;
+import static org.graalvm.compiler.bytecode.Bytecodes.DCMPL;
+import static org.graalvm.compiler.bytecode.Bytecodes.DCONST_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.DCONST_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.DDIV;
+import static org.graalvm.compiler.bytecode.Bytecodes.DLOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.DLOAD_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.DLOAD_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.DLOAD_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.DLOAD_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.DMUL;
+import static org.graalvm.compiler.bytecode.Bytecodes.DNEG;
+import static org.graalvm.compiler.bytecode.Bytecodes.DREM;
 import static org.graalvm.compiler.bytecode.Bytecodes.DRETURN;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSTORE_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSTORE_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSTORE_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSTORE_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.DSUB;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP2;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP2_X1;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP2_X2;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP_X1;
+import static org.graalvm.compiler.bytecode.Bytecodes.DUP_X2;
+import static org.graalvm.compiler.bytecode.Bytecodes.F2D;
+import static org.graalvm.compiler.bytecode.Bytecodes.F2I;
+import static org.graalvm.compiler.bytecode.Bytecodes.F2L;
+import static org.graalvm.compiler.bytecode.Bytecodes.FADD;
 import static org.graalvm.compiler.bytecode.Bytecodes.FALOAD;
 import static org.graalvm.compiler.bytecode.Bytecodes.FASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.FCMPG;
+import static org.graalvm.compiler.bytecode.Bytecodes.FCMPL;
+import static org.graalvm.compiler.bytecode.Bytecodes.FCONST_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.FCONST_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.FCONST_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.FDIV;
+import static org.graalvm.compiler.bytecode.Bytecodes.FLOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.FLOAD_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.FLOAD_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.FLOAD_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.FLOAD_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.FMUL;
+import static org.graalvm.compiler.bytecode.Bytecodes.FNEG;
+import static org.graalvm.compiler.bytecode.Bytecodes.FREM;
 import static org.graalvm.compiler.bytecode.Bytecodes.FRETURN;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSTORE_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSTORE_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSTORE_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSTORE_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.FSUB;
 import static org.graalvm.compiler.bytecode.Bytecodes.GETFIELD;
 import static org.graalvm.compiler.bytecode.Bytecodes.GETSTATIC;
 import static org.graalvm.compiler.bytecode.Bytecodes.GOTO;
 import static org.graalvm.compiler.bytecode.Bytecodes.GOTO_W;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2B;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2C;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2D;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2F;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2L;
+import static org.graalvm.compiler.bytecode.Bytecodes.I2S;
+import static org.graalvm.compiler.bytecode.Bytecodes.IADD;
 import static org.graalvm.compiler.bytecode.Bytecodes.IALOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.IAND;
 import static org.graalvm.compiler.bytecode.Bytecodes.IASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_4;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_5;
+import static org.graalvm.compiler.bytecode.Bytecodes.ICONST_M1;
 import static org.graalvm.compiler.bytecode.Bytecodes.IDIV;
 import static org.graalvm.compiler.bytecode.Bytecodes.IFEQ;
 import static org.graalvm.compiler.bytecode.Bytecodes.IFGE;
@@ -64,33 +145,88 @@
 import static org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPLE;
 import static org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPLT;
 import static org.graalvm.compiler.bytecode.Bytecodes.IF_ICMPNE;
+import static org.graalvm.compiler.bytecode.Bytecodes.IINC;
+import static org.graalvm.compiler.bytecode.Bytecodes.ILOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.ILOAD_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.ILOAD_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.ILOAD_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.ILOAD_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.IMUL;
+import static org.graalvm.compiler.bytecode.Bytecodes.INEG;
+import static org.graalvm.compiler.bytecode.Bytecodes.INSTANCEOF;
 import static org.graalvm.compiler.bytecode.Bytecodes.INVOKEDYNAMIC;
 import static org.graalvm.compiler.bytecode.Bytecodes.INVOKEINTERFACE;
 import static org.graalvm.compiler.bytecode.Bytecodes.INVOKESPECIAL;
 import static org.graalvm.compiler.bytecode.Bytecodes.INVOKESTATIC;
 import static org.graalvm.compiler.bytecode.Bytecodes.INVOKEVIRTUAL;
+import static org.graalvm.compiler.bytecode.Bytecodes.IOR;
 import static org.graalvm.compiler.bytecode.Bytecodes.IREM;
 import static org.graalvm.compiler.bytecode.Bytecodes.IRETURN;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISHL;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISHR;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISTORE_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISTORE_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISTORE_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISTORE_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.ISUB;
+import static org.graalvm.compiler.bytecode.Bytecodes.IUSHR;
+import static org.graalvm.compiler.bytecode.Bytecodes.IXOR;
 import static org.graalvm.compiler.bytecode.Bytecodes.JSR;
 import static org.graalvm.compiler.bytecode.Bytecodes.JSR_W;
+import static org.graalvm.compiler.bytecode.Bytecodes.L2D;
+import static org.graalvm.compiler.bytecode.Bytecodes.L2F;
+import static org.graalvm.compiler.bytecode.Bytecodes.L2I;
+import static org.graalvm.compiler.bytecode.Bytecodes.LADD;
 import static org.graalvm.compiler.bytecode.Bytecodes.LALOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.LAND;
 import static org.graalvm.compiler.bytecode.Bytecodes.LASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.LCMP;
+import static org.graalvm.compiler.bytecode.Bytecodes.LCONST_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.LCONST_1;
 import static org.graalvm.compiler.bytecode.Bytecodes.LDC;
 import static org.graalvm.compiler.bytecode.Bytecodes.LDC2_W;
 import static org.graalvm.compiler.bytecode.Bytecodes.LDC_W;
 import static org.graalvm.compiler.bytecode.Bytecodes.LDIV;
+import static org.graalvm.compiler.bytecode.Bytecodes.LLOAD;
+import static org.graalvm.compiler.bytecode.Bytecodes.LLOAD_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.LLOAD_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.LLOAD_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.LLOAD_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.LMUL;
+import static org.graalvm.compiler.bytecode.Bytecodes.LNEG;
 import static org.graalvm.compiler.bytecode.Bytecodes.LOOKUPSWITCH;
+import static org.graalvm.compiler.bytecode.Bytecodes.LOR;
 import static org.graalvm.compiler.bytecode.Bytecodes.LREM;
 import static org.graalvm.compiler.bytecode.Bytecodes.LRETURN;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSHL;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSHR;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSTORE_0;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSTORE_1;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSTORE_2;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSTORE_3;
+import static org.graalvm.compiler.bytecode.Bytecodes.LSUB;
+import static org.graalvm.compiler.bytecode.Bytecodes.LUSHR;
+import static org.graalvm.compiler.bytecode.Bytecodes.LXOR;
+import static org.graalvm.compiler.bytecode.Bytecodes.MONITORENTER;
+import static org.graalvm.compiler.bytecode.Bytecodes.MONITOREXIT;
 import static org.graalvm.compiler.bytecode.Bytecodes.MULTIANEWARRAY;
 import static org.graalvm.compiler.bytecode.Bytecodes.NEW;
+import static org.graalvm.compiler.bytecode.Bytecodes.NEWARRAY;
+import static org.graalvm.compiler.bytecode.Bytecodes.NOP;
+import static org.graalvm.compiler.bytecode.Bytecodes.POP;
+import static org.graalvm.compiler.bytecode.Bytecodes.POP2;
 import static org.graalvm.compiler.bytecode.Bytecodes.PUTFIELD;
 import static org.graalvm.compiler.bytecode.Bytecodes.PUTSTATIC;
 import static org.graalvm.compiler.bytecode.Bytecodes.RET;
 import static org.graalvm.compiler.bytecode.Bytecodes.RETURN;
 import static org.graalvm.compiler.bytecode.Bytecodes.SALOAD;
 import static org.graalvm.compiler.bytecode.Bytecodes.SASTORE;
+import static org.graalvm.compiler.bytecode.Bytecodes.SIPUSH;
+import static org.graalvm.compiler.bytecode.Bytecodes.SWAP;
 import static org.graalvm.compiler.bytecode.Bytecodes.TABLESWITCH;
+import static org.graalvm.compiler.bytecode.Bytecodes.WIDE;
 import static org.graalvm.compiler.core.common.GraalOptions.SupportJsrBytecodes;
 
 import java.util.ArrayDeque;
@@ -111,6 +247,7 @@
 import org.graalvm.compiler.bytecode.Bytecodes;
 import org.graalvm.compiler.core.common.PermanentBailoutException;
 import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.GraalError;
 import org.graalvm.compiler.options.OptionValues;
 
 import jdk.vm.ci.code.BytecodeFrame;
@@ -159,7 +296,7 @@
 
         int id;
         final int startBci;
-        int endBci;
+        int endBci; // The bci of the last bytecode in the block
         private boolean isExceptionEntry;
         private boolean isLoopHeader;
         int loopId;
@@ -698,7 +835,9 @@
                 case SALOAD:
                 case ARRAYLENGTH:
                 case CHECKCAST:
+                case INSTANCEOF:
                 case NEW:
+                case NEWARRAY:
                 case ANEWARRAY:
                 case MULTIANEWARRAY:
                 case PUTSTATIC:
@@ -707,7 +846,8 @@
                 case GETFIELD:
                 case LDC:
                 case LDC_W:
-                case LDC2_W: {
+                case LDC2_W:
+                case MONITORENTER: {
                     /*
                      * All bytecodes that can trigger lazy class initialization via a
                      * ClassInitializationPlugin (allocations, static field access) must be listed
@@ -720,7 +860,150 @@
                         addSuccessor(blockMap, bci, makeBlock(blockMap, stream.nextBCI()));
                         addSuccessor(blockMap, bci, handler);
                     }
+                    break;
                 }
+
+                case NOP:
+                case ACONST_NULL:
+                case ICONST_M1:
+                case ICONST_0:
+                case ICONST_1:
+                case ICONST_2:
+                case ICONST_3:
+                case ICONST_4:
+                case ICONST_5:
+                case LCONST_0:
+                case LCONST_1:
+                case FCONST_0:
+                case FCONST_1:
+                case FCONST_2:
+                case DCONST_0:
+                case DCONST_1:
+                case BIPUSH:
+                case SIPUSH:
+                case ILOAD:
+                case LLOAD:
+                case FLOAD:
+                case DLOAD:
+                case ALOAD:
+                case ILOAD_0:
+                case ILOAD_1:
+                case ILOAD_2:
+                case ILOAD_3:
+                case LLOAD_0:
+                case LLOAD_1:
+                case LLOAD_2:
+                case LLOAD_3:
+                case FLOAD_0:
+                case FLOAD_1:
+                case FLOAD_2:
+                case FLOAD_3:
+                case DLOAD_0:
+                case DLOAD_1:
+                case DLOAD_2:
+                case DLOAD_3:
+                case ALOAD_0:
+                case ALOAD_1:
+                case ALOAD_2:
+                case ALOAD_3:
+                case ISTORE:
+                case LSTORE:
+                case FSTORE:
+                case DSTORE:
+                case ASTORE:
+                case ISTORE_0:
+                case ISTORE_1:
+                case ISTORE_2:
+                case ISTORE_3:
+                case LSTORE_0:
+                case LSTORE_1:
+                case LSTORE_2:
+                case LSTORE_3:
+                case FSTORE_0:
+                case FSTORE_1:
+                case FSTORE_2:
+                case FSTORE_3:
+                case DSTORE_0:
+                case DSTORE_1:
+                case DSTORE_2:
+                case DSTORE_3:
+                case ASTORE_0:
+                case ASTORE_1:
+                case ASTORE_2:
+                case ASTORE_3:
+                case POP:
+                case POP2:
+                case DUP:
+                case DUP_X1:
+                case DUP_X2:
+                case DUP2:
+                case DUP2_X1:
+                case DUP2_X2:
+                case SWAP:
+                case IADD:
+                case LADD:
+                case FADD:
+                case DADD:
+                case ISUB:
+                case LSUB:
+                case FSUB:
+                case DSUB:
+                case IMUL:
+                case LMUL:
+                case FMUL:
+                case DMUL:
+                case FDIV:
+                case DDIV:
+                case FREM:
+                case DREM:
+                case INEG:
+                case LNEG:
+                case FNEG:
+                case DNEG:
+                case ISHL:
+                case LSHL:
+                case ISHR:
+                case LSHR:
+                case IUSHR:
+                case LUSHR:
+                case IAND:
+                case LAND:
+                case IOR:
+                case LOR:
+                case IXOR:
+                case LXOR:
+                case IINC:
+                case I2L:
+                case I2F:
+                case I2D:
+                case L2I:
+                case L2F:
+                case L2D:
+                case F2I:
+                case F2L:
+                case F2D:
+                case D2I:
+                case D2L:
+                case D2F:
+                case I2B:
+                case I2C:
+                case I2S:
+                case LCMP:
+                case FCMPL:
+                case FCMPG:
+                case DCMPL:
+                case DCMPG:
+                case MONITOREXIT:
+                    // All stack manipulation, comparison, conversion and arithmetic operators
+                    // except for idiv and irem can't throw exceptions so the don't need to connect
+                    // exception edges. MONITOREXIT can't throw exceptions in the context of
+                    // compiled code because of the structured locking requirement in the parser.
+                    break;
+
+                case WIDE:
+                case BREAKPOINT:
+                default:
+                    throw new GraalError("Unhandled bytecode");
             }
             stream.next();
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/BytecodeParser.java	Thu Oct 10 10:57:42 2019 -0400
@@ -361,6 +361,7 @@
 import org.graalvm.compiler.nodes.calc.ConditionalNode;
 import org.graalvm.compiler.nodes.calc.FloatConvertNode;
 import org.graalvm.compiler.nodes.calc.FloatDivNode;
+import org.graalvm.compiler.nodes.calc.FloatNormalizeCompareNode;
 import org.graalvm.compiler.nodes.calc.IntegerBelowNode;
 import org.graalvm.compiler.nodes.calc.IntegerEqualsNode;
 import org.graalvm.compiler.nodes.calc.IntegerLessThanNode;
@@ -370,7 +371,6 @@
 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.FloatNormalizeCompareNode;
 import org.graalvm.compiler.nodes.calc.ObjectEqualsNode;
 import org.graalvm.compiler.nodes.calc.OrNode;
 import org.graalvm.compiler.nodes.calc.RemNode;
@@ -2706,8 +2706,10 @@
         }
         MonitorIdNode monitorId = frameState.peekMonitorId();
         ValueNode lockedObject = frameState.popLock();
-        if (GraphUtil.originalValue(lockedObject) != GraphUtil.originalValue(x)) {
-            throw bailout(String.format("unbalanced monitors: mismatch at monitorexit, %s != %s", GraphUtil.originalValue(x), GraphUtil.originalValue(lockedObject)));
+        ValueNode originalLockedObject = GraphUtil.originalValue(lockedObject, false);
+        ValueNode originalX = GraphUtil.originalValue(x, false);
+        if (originalLockedObject != originalX) {
+            throw bailout(String.format("unbalanced monitors: mismatch at monitorexit, %s != %s", originalLockedObject, originalX));
         }
         MonitorExitNode monitorExit = append(new MonitorExitNode(lockedObject, monitorId, escapedValue));
         monitorExit.setStateAfter(createFrameState(bci, monitorExit));
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.java/src/org/graalvm/compiler/java/FrameStateBuilder.java	Thu Oct 10 10:57:42 2019 -0400
@@ -35,6 +35,7 @@
 import static org.graalvm.compiler.bytecode.Bytecodes.SWAP;
 import static org.graalvm.compiler.debug.GraalError.shouldNotReachHere;
 import static org.graalvm.compiler.nodes.FrameState.TWO_SLOT_MARKER;
+import static org.graalvm.compiler.nodes.util.GraphUtil.originalValue;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -70,7 +71,6 @@
 import org.graalvm.compiler.nodes.graphbuilderconf.IntrinsicContext.SideEffectsState;
 import org.graalvm.compiler.nodes.graphbuilderconf.ParameterPlugin;
 import org.graalvm.compiler.nodes.java.MonitorIdNode;
-import org.graalvm.compiler.nodes.util.GraphUtil;
 
 import jdk.vm.ci.code.BytecodeFrame;
 import jdk.vm.ci.meta.Assumptions;
@@ -384,38 +384,54 @@
         return new FrameStateBuilder(this);
     }
 
-    public boolean isCompatibleWith(FrameStateBuilder other) {
+    private String incompatibilityErrorMessage(String reason, FrameStateBuilder other) {
+        return String.format("Frame states being merged are incompatible: %s%n This frame state: %s%nOther frame state: %s%nParser context: %s", reason, this, other, parser);
+    }
+
+    /**
+     * Checks invariants that must hold when merging {@code other} into this frame state.
+     *
+     * @param other
+     * @throws PermanentBailoutException if the frame states are incompatible with respect to their
+     *             locked objects. This indicates bytecode that has unstructured or unbalanced
+     *             locks.
+     * @throws GraalError if the frame states are incompatible in terms of {@link #rethrowException}
+     *             or stack slots
+     */
+    public void checkCompatibleWith(FrameStateBuilder other) {
         assert code.equals(other.code) && graph == other.graph && localsSize() == other.localsSize() : "Can only compare frame states of the same method";
         assert lockedObjects.length == monitorIds.length && other.lockedObjects.length == other.monitorIds.length : "mismatch between lockedObjects and monitorIds";
 
         if (rethrowException != other.rethrowException) {
-            return false;
+            throw new GraalError(incompatibilityErrorMessage("mismatch in rethrowException flag", other));
         }
 
         if (stackSize() != other.stackSize()) {
-            return false;
+            throw new GraalError(incompatibilityErrorMessage("mismatch in stack sizes", other));
         }
         for (int i = 0; i < stackSize(); i++) {
             ValueNode x = stack[i];
             ValueNode y = other.stack[i];
             assert x != null && y != null;
             if (x != y && (x == TWO_SLOT_MARKER || x.isDeleted() || y == TWO_SLOT_MARKER || y.isDeleted() || x.getStackKind() != y.getStackKind())) {
-                return false;
+                throw new GraalError(incompatibilityErrorMessage("mismatch in stack types", other));
             }
         }
         if (lockedObjects.length != other.lockedObjects.length) {
-            return false;
+            throw new PermanentBailoutException(incompatibilityErrorMessage("unbalanced monitors - locked objects do not match", other));
         }
         for (int i = 0; i < lockedObjects.length; i++) {
-            if (GraphUtil.originalValue(lockedObjects[i]) != GraphUtil.originalValue(other.lockedObjects[i]) || monitorIds[i] != other.monitorIds[i]) {
-                throw new PermanentBailoutException("unbalanced monitors");
+            if (originalValue(lockedObjects[i], false) != originalValue(other.lockedObjects[i], false)) {
+                throw new PermanentBailoutException(incompatibilityErrorMessage("unbalanced monitors - locked objects do not match", other));
+            }
+            if (monitorIds[i] != other.monitorIds[i]) {
+                throw new PermanentBailoutException(incompatibilityErrorMessage("unbalanced monitors - monitors do not match", other));
             }
         }
-        return true;
     }
 
     public void merge(AbstractMergeNode block, FrameStateBuilder other) {
-        GraalError.guarantee(isCompatibleWith(other), "stacks do not match on merge; bytecodes would not verify:%nexpect: %s%nactual: %s", block, other);
+        checkCompatibleWith(other);
 
         for (int i = 0; i < localsSize(); i++) {
             locals[i] = merge(locals[i], other.locals[i], block);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Field_set02.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.jtt/src/org/graalvm/compiler/jtt/reflect/Field_set02.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,10 +24,11 @@
 
 package org.graalvm.compiler.jtt.reflect;
 
+import org.graalvm.compiler.debug.DebugOptions;
+import org.graalvm.compiler.jtt.JTTTest;
+import org.graalvm.compiler.options.OptionValues;
 import org.junit.Test;
 
-import org.graalvm.compiler.jtt.JTTTest;
-
 /*
  */
 public class Field_set02 extends JTTTest {
@@ -76,7 +77,13 @@
 
     @Test
     public void run0() throws Throwable {
-        runTest("test", 0);
+        try {
+            runTest("test", 0);
+        } catch (AssertionError e) {
+            System.err.println(e);
+            System.err.println("object.byteField == " + object.byteField);
+            runTest(new OptionValues(getInitialOptions(), DebugOptions.Dump, ":2"), "test", 0);
+        }
     }
 
     @Test
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArithmeticOp.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ArithmeticOp.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -481,7 +481,7 @@
          */
         public MultiplyAddSubOp(AArch64ArithmeticOp op, AllocatableValue result, AllocatableValue src1, AllocatableValue src2, AllocatableValue src3) {
             super(TYPE);
-            assert op == ADD || op == SUB;
+            assert op == ADD || op == SUB || op == FADD;
             this.op = op;
             this.result = result;
             this.src1 = src1;
@@ -499,6 +499,9 @@
                 case SUB:
                     masm.msub(size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(src3));
                     break;
+                case FADD:
+                    masm.fmadd(size, asRegister(result), asRegister(src1), asRegister(src2), asRegister(src3));
+                    break;
                 default:
                     throw GraalError.shouldNotReachHere();
             }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ZeroMemoryOp.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.aarch64/src/org/graalvm/compiler/lir/aarch64/AArch64ZeroMemoryOp.java	Thu Oct 10 10:57:42 2019 -0400
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.asm.Label;
 import org.graalvm.compiler.asm.aarch64.AArch64Address;
 import org.graalvm.compiler.asm.aarch64.AArch64Assembler;
+import org.graalvm.compiler.asm.aarch64.AArch64Assembler.ConditionFlag;
 import org.graalvm.compiler.asm.aarch64.AArch64MacroAssembler;
 import org.graalvm.compiler.lir.LIRInstructionClass;
 import org.graalvm.compiler.lir.Opcode;
@@ -39,7 +40,7 @@
 
 import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.code.Register;
-import jdk.vm.ci.meta.AllocatableValue;
+import jdk.vm.ci.meta.Value;
 
 /**
  * Zero a chunk of memory on AArch64.
@@ -48,136 +49,186 @@
 public final class AArch64ZeroMemoryOp extends AArch64LIRInstruction {
     public static final LIRInstructionClass<AArch64ZeroMemoryOp> TYPE = LIRInstructionClass.create(AArch64ZeroMemoryOp.class);
 
-    @Use({REG}) protected AllocatableValue addressValue;
-    @Use({REG}) protected AllocatableValue lengthValue;
+    @Use({REG}) protected Value addressValue;
+    @Use({REG}) protected Value lengthValue;
 
+    @Temp({REG}) protected Value addressValueTemp;
+    @Temp({REG}) protected Value lengthValueTemp;
+
+    private final boolean isAligned;
     private final boolean useDcZva;
     private final int zvaLength;
 
     /**
      * Constructor of AArch64ZeroMemoryOp.
      *
-     * @param address allocatable 8-byte aligned base address of the memory chunk.
-     * @param length allocatable length of the memory chunk, the value must be multiple of 8.
+     * @param address starting address of the memory chunk to be zeroed.
+     * @param length size of the memory chunk to be zeroed, in bytes.
+     * @param isAligned whether both address and size are aligned to 8 bytes.
      * @param useDcZva is DC ZVA instruction is able to use.
      * @param zvaLength the ZVA length info of current AArch64 CPU, negative value indicates length
      *            is unknown at compile time.
      */
-    public AArch64ZeroMemoryOp(AllocatableValue address, AllocatableValue length, boolean useDcZva, int zvaLength) {
+    public AArch64ZeroMemoryOp(Value address, Value length, boolean isAligned, boolean useDcZva, int zvaLength) {
         super(TYPE);
         this.addressValue = address;
         this.lengthValue = length;
+        this.addressValueTemp = address;
+        this.lengthValueTemp = length;
         this.useDcZva = useDcZva;
         this.zvaLength = zvaLength;
+        this.isAligned = isAligned;
     }
 
     @Override
     protected void emitCode(CompilationResultBuilder crb, AArch64MacroAssembler masm) {
         Register base = asRegister(addressValue);
         Register size = asRegister(lengthValue);
-        if (useDcZva && zvaLength > 0) {
-            // From ARMv8-A architecture reference manual D12.2.35 Data Cache Zero ID register:
-            // A valid ZVA length should be a power-of-2 value in [4, 2048]
-            assert (CodeUtil.isPowerOf2(zvaLength) && 4 <= zvaLength && zvaLength <= 2048);
-            emitZeroMemoryWithDc(masm, base, size, zvaLength);
-        } else {
-            // Use store pair instructions (STP) to zero memory as a fallback.
-            emitZeroMemoryWithStp(masm, base, size);
-        }
-    }
+
+        try (AArch64MacroAssembler.ScratchRegister scratchRegister = masm.getScratchRegister()) {
+            Register alignmentBits = scratchRegister.getRegister();
+
+            Label tail = new Label();
+            Label done = new Label();
+
+            // Jump to DONE if size is zero.
+            masm.cbz(64, size, done);
+
+            if (!isAligned) {
+                Label baseAlignedTo2Bytes = new Label();
+                Label baseAlignedTo4Bytes = new Label();
+                Label baseAlignedTo8Bytes = new Label();
+
+                // Jump to per-byte zeroing loop if the zeroing size is less than 8
+                masm.cmp(64, size, 8);
+                masm.branchConditionally(ConditionFlag.LT, tail);
+
+                // Make base 8-byte aligned
+                masm.neg(64, alignmentBits, base);
+                masm.and(64, alignmentBits, alignmentBits, 7);
+
+                masm.tbz(alignmentBits, 0, baseAlignedTo2Bytes);
+                masm.sub(64, size, size, 1);
+                masm.str(8, zr, AArch64Address.createPostIndexedImmediateAddress(base, 1));
+                masm.bind(baseAlignedTo2Bytes);
+
+                masm.tbz(alignmentBits, 1, baseAlignedTo4Bytes);
+                masm.sub(64, size, size, 2);
+                masm.str(16, zr, AArch64Address.createPostIndexedImmediateAddress(base, 2));
+                masm.bind(baseAlignedTo4Bytes);
 
-    /**
-     * Zero a chunk of memory with DC ZVA instructions.
-     *
-     * @param masm the AArch64 macro assembler.
-     * @param base base an 8-byte aligned address of the memory chunk to be zeroed.
-     * @param size size of the memory chunk to be zeroed, in bytes, must be multiple of 8.
-     * @param zvaLength the ZVA length info of current AArch64 CPU.
-     */
-    private static void emitZeroMemoryWithDc(AArch64MacroAssembler masm, Register base, Register size, int zvaLength) {
-        Label preLoop = new Label();
-        Label zvaLoop = new Label();
-        Label postLoop = new Label();
-        Label tail = new Label();
-        Label done = new Label();
+                masm.tbz(alignmentBits, 2, baseAlignedTo8Bytes);
+                masm.sub(64, size, size, 4);
+                masm.str(32, zr, AArch64Address.createPostIndexedImmediateAddress(base, 4));
+                masm.bind(baseAlignedTo8Bytes);
+                // At this point base is 8-byte aligned.
+            }
+
+            if (useDcZva && zvaLength > 0) {
+                // From ARMv8-A architecture reference manual D12.2.35 Data Cache Zero ID register:
+                // A valid ZVA length should be a power-of-2 value in [4, 2048]
+                assert (CodeUtil.isPowerOf2(zvaLength) && 4 <= zvaLength && zvaLength <= 2048);
 
-        try (AArch64MacroAssembler.ScratchRegister sc1 = masm.getScratchRegister()) {
-            Register rscratch1 = sc1.getRegister();
+                Label preCheck = new Label();
+                Label preLoop = new Label();
+                Label mainCheck = new Label();
+                Label mainLoop = new Label();
+                Label postCheck = new Label();
+                Label postLoop = new Label();
+
+                masm.neg(64, alignmentBits, base);
+                masm.and(64, alignmentBits, alignmentBits, zvaLength - 1);
 
-            // Count number of bytes to be pre-zeroed to align base address with ZVA length.
-            masm.neg(64, rscratch1, base);
-            masm.and(64, rscratch1, rscratch1, zvaLength - 1);
+                // Is size less than number of bytes to be pre-zeroed? Jump to post check if so.
+                masm.cmp(64, size, alignmentBits);
+                masm.branchConditionally(AArch64Assembler.ConditionFlag.LE, postCheck);
+                masm.sub(64, size, size, alignmentBits);
+
+                // Pre loop: align base according to the supported bulk zeroing stride.
+                masm.jmp(preCheck);
+
+                masm.align(crb.target.wordSize * 2);
+                masm.bind(preLoop);
+                masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
+                masm.bind(preCheck);
+                masm.subs(64, alignmentBits, alignmentBits, 8);
+                masm.branchConditionally(AArch64Assembler.ConditionFlag.GE, preLoop);
 
-            // Is size less than number of bytes to be pre-zeroed? Jump to POST_LOOP if so.
-            masm.cmp(64, size, rscratch1);
-            masm.branchConditionally(AArch64Assembler.ConditionFlag.LE, postLoop);
-            masm.sub(64, size, size, rscratch1);
+                // Main loop: bulk zeroing
+                masm.jmp(mainCheck);
+
+                masm.align(crb.target.wordSize * 2);
+                masm.bind(mainLoop);
+                masm.dc(AArch64Assembler.DataCacheOperationType.ZVA, base);
+                masm.add(64, base, base, zvaLength);
+                masm.bind(mainCheck);
+                masm.subs(64, size, size, zvaLength);
+                masm.branchConditionally(AArch64Assembler.ConditionFlag.GE, mainLoop);
+
+                masm.add(64, size, size, zvaLength);
+
+                // Post loop: handle bytes after the main loop
+                masm.jmp(postCheck);
 
-            // Pre-ZVA loop.
-            masm.bind(preLoop);
-            masm.subs(64, rscratch1, rscratch1, 8);
-            masm.branchConditionally(AArch64Assembler.ConditionFlag.LT, zvaLoop);
-            masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
-            masm.jmp(preLoop);
+                masm.align(crb.target.wordSize * 2);
+                masm.bind(postLoop);
+                masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
+                masm.bind(postCheck);
+                masm.subs(64, size, size, 8);
+                masm.branchConditionally(AArch64Assembler.ConditionFlag.GE, postLoop);
+
+                if (!isAligned) {
+                    // Restore size for tail zeroing
+                    masm.add(64, size, size, 8);
+                }
+            } else {
+                Label mainCheck = new Label();
+                Label mainLoop = new Label();
+
+                if (!isAligned) {
+                    // After aligning base, we may have size less than 8. Need to check again.
+                    masm.cmp(64, size, 8);
+                    masm.branchConditionally(ConditionFlag.LT, tail);
+                }
 
-            // ZVA loop.
-            masm.bind(zvaLoop);
-            masm.subs(64, size, size, zvaLength);
-            masm.branchConditionally(AArch64Assembler.ConditionFlag.LT, tail);
-            masm.dc(AArch64Assembler.DataCacheOperationType.ZVA, base);
-            masm.add(64, base, base, zvaLength);
-            masm.jmp(zvaLoop);
+                masm.tbz(base, 3, mainCheck);
+                masm.sub(64, size, size, 8);
+                masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
+                masm.jmp(mainCheck);
 
-            // Handle bytes after ZVA loop.
+                // The STP loop that zeros 16 bytes in each iteration.
+                masm.align(crb.target.wordSize * 2);
+                masm.bind(mainLoop);
+                masm.stp(64, zr, zr, AArch64Address.createPostIndexedImmediateAddress(base, 2));
+                masm.bind(mainCheck);
+                masm.subs(64, size, size, 16);
+                masm.branchConditionally(AArch64Assembler.ConditionFlag.GE, mainLoop);
+
+                // We may need to zero the tail 8 bytes of the memory chunk.
+                masm.add(64, size, size, 16);
+                masm.tbz(size, 3, tail);
+                masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
+
+                if (!isAligned) {
+                    // Adjust size for tail zeroing
+                    masm.sub(64, size, size, 8);
+                }
+            }
+
             masm.bind(tail);
-            masm.add(64, size, size, zvaLength);
+            if (!isAligned) {
+                Label perByteZeroingLoop = new Label();
 
-            // Post-ZVA loop.
-            masm.bind(postLoop);
-            masm.subs(64, size, size, 8);
-            masm.branchConditionally(AArch64Assembler.ConditionFlag.LT, done);
-            masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
-            masm.jmp(postLoop);
-
-            // Done.
+                masm.cbz(64, size, done);
+                // We have to ensure size > 0 when entering the following loop
+                masm.align(crb.target.wordSize * 2);
+                masm.bind(perByteZeroingLoop);
+                masm.str(8, zr, AArch64Address.createPostIndexedImmediateAddress(base, 1));
+                masm.subs(64, size, size, 1);
+                masm.branchConditionally(AArch64Assembler.ConditionFlag.NE, perByteZeroingLoop);
+            }
             masm.bind(done);
         }
     }
 
-    /**
-     * Zero a chunk of memory with STP instructions.
-     *
-     * @param masm the AArch64 macro assembler.
-     * @param base base an 8-byte aligned address of the memory chunk to be zeroed.
-     * @param size size of the memory chunk to be zeroed, in bytes, must be multiple of 8.
-     */
-    private static void emitZeroMemoryWithStp(AArch64MacroAssembler masm, Register base, Register size) {
-        Label loop = new Label();
-        Label tail = new Label();
-        Label done = new Label();
-
-        // Jump to DONE if size is zero.
-        masm.cbz(64, size, done);
-
-        // Is base address already 16-byte aligned? Jump to LDP loop if so.
-        masm.tbz(base, 3, loop);
-        masm.sub(64, size, size, 8);
-        masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
-
-        // The STP loop that zeros 16 bytes in each iteration.
-        masm.bind(loop);
-        masm.subs(64, size, size, 16);
-        masm.branchConditionally(AArch64Assembler.ConditionFlag.LT, tail);
-        masm.stp(64, zr, zr, AArch64Address.createPostIndexedImmediateAddress(base, 2));
-        masm.jmp(loop);
-
-        // We may need to zero the tail 8 bytes of the memory chunk.
-        masm.bind(tail);
-        masm.adds(64, size, size, 16);
-        masm.branchConditionally(AArch64Assembler.ConditionFlag.EQ, done);
-        masm.str(64, zr, AArch64Address.createPostIndexedImmediateAddress(base, 8));
-
-        // Done.
-        masm.bind(done);
-    }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCControlFlow.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.sparc/src/org/graalvm/compiler/lir/sparc/SPARCControlFlow.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -115,7 +115,7 @@
 public class SPARCControlFlow {
     // This describes the maximum offset between the first emitted (load constant in to scratch,
     // if does not fit into simm5 of cbcond) instruction and the final branch instruction
-    private static final int maximumSelfOffsetInstructions = 2;
+    private static final int maximumSelfOffsetInstructions = 10;
 
     public static final class ReturnOp extends SPARCBlockEndOp {
         public static final LIRInstructionClass<ReturnOp> TYPE = LIRInstructionClass.create(ReturnOp.class);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/gen/LIRGeneratorTool.java	Thu Oct 10 10:57:42 2019 -0400
@@ -355,7 +355,7 @@
     }
 
     @SuppressWarnings("unused")
-    default void emitZeroMemory(Value address, Value length) {
+    default void emitZeroMemory(Value address, Value length, boolean isAligned) {
         throw GraalError.unimplemented("Bulk zeroing is not implemented on this architecture");
     }
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.loop/src/org/graalvm/compiler/loop/LoopFragmentInside.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -245,60 +245,40 @@
         // Discard the segment entry and its flow, after if merging it into the loop
         StructuredGraph graph = mainLoopBegin.graph();
         IfNode loopTest = mainCounted.getLimitTest();
-        IfNode newSegmentTest = getDuplicatedNode(loopTest);
-        AbstractBeginNode trueSuccessor = loopTest.trueSuccessor();
-        AbstractBeginNode falseSuccessor = loopTest.falseSuccessor();
-        FixedNode firstNode;
-        boolean codeInTrueSide = false;
-        if (trueSuccessor == mainCounted.getBody()) {
-            firstNode = trueSuccessor.next();
-            codeInTrueSide = true;
-        } else {
-            assert (falseSuccessor == mainCounted.getBody());
-            firstNode = falseSuccessor.next();
-        }
-        trueSuccessor = newSegmentTest.trueSuccessor();
-        falseSuccessor = newSegmentTest.falseSuccessor();
+        IfNode newSegmentLoopTest = getDuplicatedNode(loopTest);
+
+        // Redirect anchors
+        AbstractBeginNode falseSuccessor = newSegmentLoopTest.falseSuccessor();
         for (Node usage : falseSuccessor.anchored().snapshot()) {
             usage.replaceFirstInput(falseSuccessor, loopTest.falseSuccessor());
         }
+        AbstractBeginNode trueSuccessor = newSegmentLoopTest.trueSuccessor();
         for (Node usage : trueSuccessor.anchored().snapshot()) {
             usage.replaceFirstInput(trueSuccessor, loopTest.trueSuccessor());
         }
-        AbstractBeginNode startBlockNode;
-        if (codeInTrueSide) {
-            startBlockNode = trueSuccessor;
-        } else {
-            graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, mainLoopBegin.graph(), "before");
-            startBlockNode = falseSuccessor;
-        }
-        FixedNode lastNode = getBlockEnd(startBlockNode);
-        LoopEndNode loopEndNode = mainLoopBegin.getSingleLoopEnd();
-        FixedWithNextNode lastCodeNode = (FixedWithNextNode) loopEndNode.predecessor();
-        FixedNode newSegmentFirstNode = getDuplicatedNode(firstNode);
-        FixedWithNextNode newSegmentLastNode = getDuplicatedNode(lastCodeNode);
-        graph.getDebug().dump(DebugContext.DETAILED_LEVEL, loopEndNode.graph(), "Before placing segment");
-        if (firstNode instanceof LoopEndNode) {
+
+        // remove if test
+        graph.removeSplitPropagate(newSegmentLoopTest, loopTest.trueSuccessor() == mainCounted.getBody() ? trueSuccessor : falseSuccessor);
+
+        graph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph, "Before placing segment");
+        if (mainCounted.getBody().next() instanceof LoopEndNode) {
             GraphUtil.killCFG(getDuplicatedNode(mainLoopBegin));
         } else {
-            newSegmentLastNode.clearSuccessors();
-            startBlockNode.setNext(lastNode);
+            AbstractBeginNode newSegmentBegin = getDuplicatedNode(mainLoopBegin);
+            FixedNode newSegmentFirstNode = newSegmentBegin.next();
+            EndNode newSegmentEnd = getBlockEnd(newSegmentBegin);
+            FixedWithNextNode newSegmentLastNode = (FixedWithNextNode) newSegmentEnd.predecessor();
+            LoopEndNode loopEndNode = mainLoopBegin.getSingleLoopEnd();
+            FixedWithNextNode lastCodeNode = (FixedWithNextNode) loopEndNode.predecessor();
+
+            newSegmentBegin.clearSuccessors();
             lastCodeNode.replaceFirstSuccessor(loopEndNode, newSegmentFirstNode);
-            newSegmentLastNode.replaceFirstSuccessor(lastNode, loopEndNode);
-            lastCodeNode.setNext(newSegmentFirstNode);
-            newSegmentLastNode.setNext(loopEndNode);
-            startBlockNode.clearSuccessors();
-            lastNode.safeDelete();
-            Node newSegmentTestStart = newSegmentTest.predecessor();
-            LogicNode newSegmentIfTest = newSegmentTest.condition();
-            newSegmentTestStart.clearSuccessors();
-            newSegmentTest.safeDelete();
-            newSegmentIfTest.safeDelete();
-            trueSuccessor.safeDelete();
-            falseSuccessor.safeDelete();
-            newSegmentTestStart.safeDelete();
+            newSegmentLastNode.replaceFirstSuccessor(newSegmentEnd, loopEndNode);
+
+            newSegmentBegin.safeDelete();
+            newSegmentEnd.safeDelete();
         }
-        graph.getDebug().dump(DebugContext.DETAILED_LEVEL, loopEndNode.graph(), "After placing segment");
+        graph.getDebug().dump(DebugContext.DETAILED_LEVEL, graph, "After placing segment");
     }
 
     private static EndNode getBlockEnd(FixedNode node) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes.test/src/org/graalvm/compiler/nodes/test/ExceptionLivenessTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,55 @@
+/*
+ * 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.nodes.test;
+
+import static org.graalvm.compiler.java.BytecodeParserOptions.InlineDuringParsing;
+
+import org.graalvm.compiler.core.phases.HighTier;
+import org.graalvm.compiler.core.test.GraalCompilerTest;
+import org.graalvm.compiler.options.OptionValues;
+import org.junit.Test;
+
+public class ExceptionLivenessTest extends GraalCompilerTest {
+    @Test
+    public void testNewarray() {
+        OptionValues options = new OptionValues(getInitialOptions(), HighTier.Options.Inline, false, InlineDuringParsing, false);
+        test(options, "newarraySnippet");
+    }
+
+    public static int[] newarraySnippet() {
+        int[] array = new int[4];
+
+        dummy();
+        try {
+            array = new int[-10];
+        } catch (NegativeArraySizeException exc3) {
+        }
+        return array;
+    }
+
+    @BytecodeParserNeverInline
+    static void dummy() {
+    }
+}
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/AbstractBeginNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/AbstractBeginNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -32,6 +32,7 @@
 import org.graalvm.compiler.graph.IterableNodeType;
 import org.graalvm.compiler.graph.Node;
 import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.Position;
 import org.graalvm.compiler.graph.iterators.NodeIterable;
 import org.graalvm.compiler.nodeinfo.InputType;
 import org.graalvm.compiler.nodeinfo.NodeInfo;
@@ -97,6 +98,19 @@
         }
     }
 
+    public boolean isUsedAsGuardInput() {
+        if (this.hasUsages()) {
+            for (Node n : usages()) {
+                for (Position inputPosition : n.inputPositions()) {
+                    if (inputPosition.getInputType() == InputType.Guard && inputPosition.get(n) == this) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
     public NodeIterable<GuardNode> guards() {
         return usages().filter(GuardNode.class);
     }
@@ -105,6 +119,10 @@
         return usages();
     }
 
+    public boolean hasAnchored() {
+        return this.hasUsages();
+    }
+
     public NodeIterable<FixedNode> getBlockNodes() {
         return new NodeIterable<FixedNode>() {
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/IfNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -548,7 +548,7 @@
                 return false;
             }
 
-            if (trueSuccessor().anchored().isNotEmpty() || falseSuccessor().anchored().isNotEmpty()) {
+            if (trueSuccessor().hasAnchored() || falseSuccessor().hasAnchored()) {
                 return false;
             }
 
@@ -1216,6 +1216,10 @@
             return false;
         }
 
+        if (trueSuccessor().isUsedAsGuardInput() || falseSuccessor().isUsedAsGuardInput()) {
+            return false;
+        }
+
         ValuePhiNode phi = (ValuePhiNode) generalPhi;
 
         EconomicMap<Node, NodeColor> coloredNodes = EconomicMap.create(Equivalence.IDENTITY, 8);
@@ -1645,6 +1649,10 @@
             return false;
         }
 
+        if (trueSuccessor().isUsedAsGuardInput() || falseSuccessor().isUsedAsGuardInput()) {
+            return false;
+        }
+
         // Ensure phi is used by at most the comparison and the merge's frame state (if any)
         ValuePhiNode phi = (ValuePhiNode) singleUsage;
         NodeIterable<Node> phiUsages = phi.usages();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AbsNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -26,8 +26,10 @@
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Abs;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
@@ -46,7 +48,7 @@
     public static final NodeClass<AbsNode> TYPE = NodeClass.create(AbsNode.class);
 
     public AbsNode(ValueNode x) {
-        super(TYPE, ArithmeticOpTable::getAbs, x);
+        super(TYPE, getArithmeticOpTable(x).getAbs(), x);
     }
 
     public static ValueNode create(ValueNode value, NodeView view) {
@@ -67,6 +69,11 @@
     }
 
     @Override
+    protected UnaryOp<Abs> getOp(ArithmeticOpTable table) {
+        return table.getAbs();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AddNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AddNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -54,7 +54,7 @@
     }
 
     protected AddNode(NodeClass<? extends AddNode> c, ValueNode x, ValueNode y) {
-        super(c, ArithmeticOpTable::getAdd, x, y);
+        super(c, getArithmeticOpTable(x).getAdd(), x, y);
     }
 
     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -71,6 +71,11 @@
         }
     }
 
+    @Override
+    protected BinaryOp<Add> getOp(ArithmeticOpTable table) {
+        return table.getAdd();
+    }
+
     private static ValueNode canonical(AddNode addNode, BinaryOp<Add> op, ValueNode forX, ValueNode forY, NodeView view) {
         AddNode self = addNode;
         boolean associative = op.isAssociative();
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/AndNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -51,7 +51,7 @@
     public static final NodeClass<AndNode> TYPE = NodeClass.create(AndNode.class);
 
     public AndNode(ValueNode x, ValueNode y) {
-        super(TYPE, ArithmeticOpTable::getAnd, x, y);
+        super(TYPE, getArithmeticOpTable(x).getAnd(), x, y);
     }
 
     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -65,6 +65,11 @@
     }
 
     @Override
+    protected BinaryOp<And> getOp(ArithmeticOpTable table) {
+        return table.getAnd();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/BinaryArithmeticNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -27,9 +27,6 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
 
-import java.io.Serializable;
-import java.util.function.Function;
-
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
@@ -58,20 +55,20 @@
 
     @SuppressWarnings("rawtypes") public static final NodeClass<BinaryArithmeticNode> TYPE = NodeClass.create(BinaryArithmeticNode.class);
 
-    protected interface SerializableBinaryFunction<T> extends Function<ArithmeticOpTable, BinaryOp<T>>, Serializable {
+    protected BinaryArithmeticNode(NodeClass<? extends BinaryArithmeticNode<OP>> c, BinaryOp<OP> opForStampComputation, ValueNode x, ValueNode y) {
+        super(c, opForStampComputation.foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), x, y);
     }
 
-    protected final SerializableBinaryFunction<OP> getOp;
-
-    protected BinaryArithmeticNode(NodeClass<? extends BinaryArithmeticNode<OP>> c, SerializableBinaryFunction<OP> getOp, ValueNode x, ValueNode y) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT))).foldStamp(x.stamp(NodeView.DEFAULT), y.stamp(NodeView.DEFAULT)), x, y);
-        this.getOp = getOp;
+    public static ArithmeticOpTable getArithmeticOpTable(ValueNode forValue) {
+        return ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT));
     }
 
+    protected abstract BinaryOp<OP> getOp(ArithmeticOpTable table);
+
     protected final BinaryOp<OP> getOp(ValueNode forX, ValueNode forY) {
-        ArithmeticOpTable table = ArithmeticOpTable.forStamp(forX.stamp(NodeView.DEFAULT));
-        assert table.equals(ArithmeticOpTable.forStamp(forY.stamp(NodeView.DEFAULT)));
-        return getOp.apply(table);
+        ArithmeticOpTable table = getArithmeticOpTable(forX);
+        assert table.equals(getArithmeticOpTable(forY));
+        return getOp(table);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatConvertNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,12 @@
 package org.graalvm.compiler.nodes.calc;
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
-
-import java.util.EnumMap;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
 import org.graalvm.compiler.core.common.calc.FloatConvert;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.FloatConvertOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
@@ -55,16 +55,8 @@
 
     protected final FloatConvert op;
 
-    private static final EnumMap<FloatConvert, SerializableUnaryFunction<FloatConvertOp>> getOps;
-    static {
-        getOps = new EnumMap<>(FloatConvert.class);
-        for (FloatConvert op : FloatConvert.values()) {
-            getOps.put(op, table -> table.getFloatConvert(op));
-        }
-    }
-
     public FloatConvertNode(FloatConvert op, ValueNode input) {
-        super(TYPE, getOps.get(op), input);
+        super(TYPE, getArithmeticOpTable(input).getFloatConvert(op), input);
         this.op = op;
     }
 
@@ -76,6 +68,11 @@
         return new FloatConvertNode(op, input);
     }
 
+    @Override
+    protected UnaryOp<FloatConvertOp> getOp(ArithmeticOpTable table) {
+        return table.getFloatConvert(op);
+    }
+
     public FloatConvert getFloatConvert() {
         return op;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/FloatDivNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -52,7 +52,7 @@
     }
 
     protected FloatDivNode(NodeClass<? extends FloatDivNode> c, ValueNode x, ValueNode y) {
-        super(c, ArithmeticOpTable::getDiv, x, y);
+        super(c, getArithmeticOpTable(x).getDiv(), x, y);
         assert stamp instanceof FloatStamp;
     }
 
@@ -67,6 +67,11 @@
     }
 
     @Override
+    protected BinaryOp<Div> getOp(ArithmeticOpTable table) {
+        return table.getDiv();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerConvertNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -24,8 +24,7 @@
 
 package org.graalvm.compiler.nodes.calc;
 
-import java.io.Serializable;
-import java.util.function.Function;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
@@ -53,20 +52,11 @@
 public abstract class IntegerConvertNode<OP, REV> extends UnaryNode implements ArithmeticOperation, ConvertNode, ArithmeticLIRLowerable, StampInverter {
     @SuppressWarnings("rawtypes") public static final NodeClass<IntegerConvertNode> TYPE = NodeClass.create(IntegerConvertNode.class);
 
-    protected final SerializableIntegerConvertFunction<OP> getOp;
-    protected final SerializableIntegerConvertFunction<REV> getReverseOp;
-
     protected final int inputBits;
     protected final int resultBits;
 
-    protected interface SerializableIntegerConvertFunction<T> extends Function<ArithmeticOpTable, IntegerConvertOp<T>>, Serializable {
-    }
-
-    protected IntegerConvertNode(NodeClass<? extends IntegerConvertNode<OP, REV>> c, SerializableIntegerConvertFunction<OP> getOp, SerializableIntegerConvertFunction<REV> getReverseOp, int inputBits,
-                    int resultBits, ValueNode input) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(input.stamp(NodeView.DEFAULT))).foldStamp(inputBits, resultBits, input.stamp(NodeView.DEFAULT)), input);
-        this.getOp = getOp;
-        this.getReverseOp = getReverseOp;
+    protected IntegerConvertNode(NodeClass<? extends IntegerConvertNode<OP, REV>> c, IntegerConvertOp<OP> opForStampComputation, int inputBits, int resultBits, ValueNode input) {
+        super(c, opForStampComputation.foldStamp(inputBits, resultBits, input.stamp(NodeView.DEFAULT)), input);
         this.inputBits = inputBits;
         this.resultBits = resultBits;
         assert PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) == 0 || PrimitiveStamp.getBits(input.stamp(NodeView.DEFAULT)) == inputBits;
@@ -80,13 +70,13 @@
         return resultBits;
     }
 
-    protected final IntegerConvertOp<OP> getOp(ValueNode forValue) {
-        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
-    }
+    protected abstract IntegerConvertOp<OP> getOp(ArithmeticOpTable table);
+
+    protected abstract IntegerConvertOp<REV> getReverseOp(ArithmeticOpTable table);
 
     @Override
     public final IntegerConvertOp<OP> getArithmeticOp() {
-        return getOp(getValue());
+        return getOp(getArithmeticOpTable(getValue()));
     }
 
     @Override
@@ -96,7 +86,7 @@
 
     @Override
     public Constant reverse(Constant c, ConstantReflectionProvider constantReflection) {
-        IntegerConvertOp<REV> reverse = getReverseOp.apply(ArithmeticOpTable.forStamp(stamp(NodeView.DEFAULT)));
+        IntegerConvertOp<REV> reverse = getReverseOp(ArithmeticOpTable.forStamp(stamp(NodeView.DEFAULT)));
         return reverse.foldConstant(getResultBits(), getInputBits(), c);
     }
 
@@ -108,7 +98,7 @@
 
     @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
-        ValueNode synonym = findSynonym(getOp(forValue), forValue, inputBits, resultBits, stamp(NodeView.DEFAULT));
+        ValueNode synonym = findSynonym(getOp(getArithmeticOpTable(forValue)), forValue, inputBits, resultBits, stamp(NodeView.DEFAULT));
         if (synonym != null) {
             return synonym;
         }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerMulHighNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/IntegerMulHighNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -28,6 +28,7 @@
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.MulHigh;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.Canonicalizable;
@@ -48,7 +49,12 @@
     public static final NodeClass<IntegerMulHighNode> TYPE = NodeClass.create(IntegerMulHighNode.class);
 
     public IntegerMulHighNode(ValueNode x, ValueNode y) {
-        super(TYPE, ArithmeticOpTable::getMulHigh, x, y);
+        super(TYPE, getArithmeticOpTable(x).getMulHigh(), x, y);
+    }
+
+    @Override
+    protected BinaryOp<MulHigh> getOp(ArithmeticOpTable table) {
+        return table.getMulHigh();
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/LeftShiftNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/LeftShiftNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -24,7 +24,10 @@
 
 package org.graalvm.compiler.nodes.calc;
 
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
+
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp.Shl;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
@@ -45,7 +48,7 @@
     public static final NodeClass<LeftShiftNode> TYPE = NodeClass.create(LeftShiftNode.class);
 
     public LeftShiftNode(ValueNode x, ValueNode y) {
-        super(TYPE, ArithmeticOpTable::getShl, x, y);
+        super(TYPE, getArithmeticOpTable(x).getShl(), x, y);
     }
 
     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -60,6 +63,11 @@
     }
 
     @Override
+    protected ShiftOp<Shl> getOp(ArithmeticOpTable table) {
+        return table.getShl();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/MulNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -27,9 +27,9 @@
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
-import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.Mul;
+import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.Canonicalizable.BinaryCommutative;
@@ -56,7 +56,7 @@
     }
 
     protected MulNode(NodeClass<? extends MulNode> c, ValueNode x, ValueNode y) {
-        super(c, ArithmeticOpTable::getMul, x, y);
+        super(c, getArithmeticOpTable(x).getMul(), x, y);
     }
 
     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -70,6 +70,11 @@
     }
 
     @Override
+    protected BinaryOp<Mul> getOp(ArithmeticOpTable table) {
+        return table.getMul();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NarrowNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -25,6 +25,7 @@
 package org.graalvm.compiler.nodes.calc;
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
 import org.graalvm.compiler.core.common.calc.CanonicalCondition;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
@@ -58,7 +59,7 @@
     }
 
     public NarrowNode(ValueNode input, int inputBits, int resultBits) {
-        super(TYPE, ArithmeticOpTable::getNarrow, ArithmeticOpTable::getSignExtend, inputBits, resultBits, input);
+        super(TYPE, getArithmeticOpTable(input).getNarrow(), inputBits, resultBits, input);
     }
 
     public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
@@ -76,6 +77,16 @@
     }
 
     @Override
+    protected IntegerConvertOp<Narrow> getOp(ArithmeticOpTable table) {
+        return table.getNarrow();
+    }
+
+    @Override
+    protected IntegerConvertOp<SignExtend> getReverseOp(ArithmeticOpTable table) {
+        return table.getSignExtend();
+    }
+
+    @Override
     public boolean isLossless() {
         return checkLossless(this.getResultBits());
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NegateNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NegateNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -26,8 +26,10 @@
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_2;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Neg;
 import org.graalvm.compiler.core.common.type.FloatStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
@@ -49,7 +51,7 @@
     public static final NodeClass<NegateNode> TYPE = NodeClass.create(NegateNode.class);
 
     public NegateNode(ValueNode value) {
-        super(TYPE, ArithmeticOpTable::getNeg, value);
+        super(TYPE, getArithmeticOpTable(value).getNeg(), value);
     }
 
     public static ValueNode create(ValueNode value, NodeView view) {
@@ -61,6 +63,11 @@
     }
 
     @Override
+    protected UnaryOp<Neg> getOp(ArithmeticOpTable table) {
+        return table.getNeg();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         ValueNode synonym = findSynonym(forValue, getOp(forValue));
         if (synonym != null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NotNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/NotNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -26,8 +26,10 @@
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Not;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.graph.NodeClass;
@@ -48,7 +50,7 @@
     public static final NodeClass<NotNode> TYPE = NodeClass.create(NotNode.class);
 
     protected NotNode(ValueNode x) {
-        super(TYPE, ArithmeticOpTable::getNot, x);
+        super(TYPE, getArithmeticOpTable(x).getNot(), x);
     }
 
     public static ValueNode create(ValueNode x) {
@@ -56,6 +58,11 @@
     }
 
     @Override
+    protected UnaryOp<Not> getOp(ArithmeticOpTable table) {
+        return table.getNot();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         ValueNode ret = super.canonical(tool, forValue);
         if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ObjectEqualsNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -39,10 +39,13 @@
 import org.graalvm.compiler.nodes.NodeView;
 import org.graalvm.compiler.nodes.StructuredGraph;
 import org.graalvm.compiler.nodes.ValueNode;
+import org.graalvm.compiler.nodes.extended.BoxNode;
 import org.graalvm.compiler.nodes.extended.GetClassNode;
+import org.graalvm.compiler.nodes.java.AbstractNewObjectNode;
 import org.graalvm.compiler.nodes.java.InstanceOfNode;
 import org.graalvm.compiler.nodes.spi.Virtualizable;
 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
+import org.graalvm.compiler.nodes.virtual.AllocatedObjectNode;
 import org.graalvm.compiler.nodes.virtual.VirtualBoxingNode;
 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
 import org.graalvm.compiler.options.OptionValues;
@@ -112,6 +115,11 @@
                 }
                 return LogicConstantNode.forBoolean(false);
             }
+            if (nonConstant instanceof AbstractNewObjectNode || nonConstant instanceof AllocatedObjectNode) {
+                assert !(nonConstant instanceof BoxNode); // guard against class hierarchy changes
+                // a constant can never be equals to a new object
+                return LogicConstantNode.forBoolean(false);
+            }
             return super.canonicalizeSymmetricConstant(constantReflection, metaAccess, options, smallestCompareWidth, condition, constant, nonConstant, mirrored, unorderedIsTrue, view);
         }
 
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/OrNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -50,7 +50,7 @@
     public static final NodeClass<OrNode> TYPE = NodeClass.create(OrNode.class);
 
     public OrNode(ValueNode x, ValueNode y) {
-        super(TYPE, ArithmeticOpTable::getOr, x, y);
+        super(TYPE, getArithmeticOpTable(x).getOr(), x, y);
     }
 
     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -64,6 +64,11 @@
     }
 
     @Override
+    protected BinaryOp<Or> getOp(ArithmeticOpTable table) {
+        return table.getOr();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RemNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -50,7 +50,7 @@
     }
 
     protected RemNode(NodeClass<? extends RemNode> c, ValueNode x, ValueNode y) {
-        super(c, ArithmeticOpTable::getRem, x, y);
+        super(c, getArithmeticOpTable(x).getRem(), x, y);
     }
 
     public static ValueNode create(ValueNode forX, ValueNode forY, NodeView view) {
@@ -64,6 +64,11 @@
     }
 
     @Override
+    protected BinaryOp<Rem> getOp(ArithmeticOpTable table) {
+        return table.getRem();
+    }
+
+    @Override
     public void lower(LoweringTool tool) {
         tool.getLowerer().lower(this, tool);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RightShiftNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/RightShiftNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -24,7 +24,10 @@
 
 package org.graalvm.compiler.nodes.calc;
 
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
+
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp.Shr;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
@@ -45,7 +48,7 @@
     public static final NodeClass<RightShiftNode> TYPE = NodeClass.create(RightShiftNode.class);
 
     public RightShiftNode(ValueNode x, ValueNode y) {
-        super(TYPE, ArithmeticOpTable::getShr, x, y);
+        super(TYPE, getArithmeticOpTable(x).getShr(), x, y);
     }
 
     public static ValueNode create(ValueNode x, int y, NodeView view) {
@@ -67,6 +70,11 @@
     }
 
     @Override
+    protected ShiftOp<Shr> getOp(ArithmeticOpTable table) {
+        return table.getShr();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ShiftNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ShiftNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -26,9 +26,7 @@
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
-
-import java.io.Serializable;
-import java.util.function.Function;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
@@ -55,25 +53,21 @@
 
     @SuppressWarnings("rawtypes") public static final NodeClass<ShiftNode> TYPE = NodeClass.create(ShiftNode.class);
 
-    protected interface SerializableShiftFunction<T> extends Function<ArithmeticOpTable, ShiftOp<T>>, Serializable {
-    }
-
-    protected final SerializableShiftFunction<OP> getOp;
-
     /**
      * Creates a new shift operation.
      *
      * @param x the first input value
      * @param s the second input value
      */
-    protected ShiftNode(NodeClass<? extends ShiftNode<OP>> c, SerializableShiftFunction<OP> getOp, ValueNode x, ValueNode s) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(x.stamp(NodeView.DEFAULT))).foldStamp(x.stamp(NodeView.DEFAULT), (IntegerStamp) s.stamp(NodeView.DEFAULT)), x, s);
+    protected ShiftNode(NodeClass<? extends ShiftNode<OP>> c, ShiftOp<OP> opForStampComputation, ValueNode x, ValueNode s) {
+        super(c, opForStampComputation.foldStamp(x.stamp(NodeView.DEFAULT), (IntegerStamp) s.stamp(NodeView.DEFAULT)), x, s);
         assert ((IntegerStamp) s.stamp(NodeView.DEFAULT)).getBits() == 32;
-        this.getOp = getOp;
     }
 
+    protected abstract ShiftOp<OP> getOp(ArithmeticOpTable table);
+
     protected final ShiftOp<OP> getOp(ValueNode forValue) {
-        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
+        return getOp(getArithmeticOpTable(forValue));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignExtendNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SignExtendNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,8 @@
 package org.graalvm.compiler.nodes.calc;
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
-import jdk.vm.ci.code.CodeUtil;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.IntegerConvertOp.Narrow;
@@ -42,6 +42,8 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
+import jdk.vm.ci.code.CodeUtil;
+
 /**
  * The {@code SignExtendNode} converts an integer to a wider integer using sign extension.
  */
@@ -56,7 +58,7 @@
     }
 
     public SignExtendNode(ValueNode input, int inputBits, int resultBits) {
-        super(TYPE, ArithmeticOpTable::getSignExtend, ArithmeticOpTable::getNarrow, inputBits, resultBits, input);
+        super(TYPE, getArithmeticOpTable(input).getSignExtend(), inputBits, resultBits, input);
     }
 
     public static ValueNode create(ValueNode input, int resultBits, NodeView view) {
@@ -73,6 +75,16 @@
     }
 
     @Override
+    protected IntegerConvertOp<SignExtend> getOp(ArithmeticOpTable table) {
+        return table.getSignExtend();
+    }
+
+    @Override
+    protected IntegerConvertOp<Narrow> getReverseOp(ArithmeticOpTable table) {
+        return table.getNarrow();
+    }
+
+    @Override
     public boolean isLossless() {
         return true;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SqrtNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -26,8 +26,10 @@
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_16;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp.Sqrt;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.lir.gen.ArithmeticLIRGeneratorTool;
@@ -47,7 +49,7 @@
     public static final NodeClass<SqrtNode> TYPE = NodeClass.create(SqrtNode.class);
 
     protected SqrtNode(ValueNode x) {
-        super(TYPE, ArithmeticOpTable::getSqrt, x);
+        super(TYPE, getArithmeticOpTable(x).getSqrt(), x);
     }
 
     public static ValueNode create(ValueNode x, NodeView view) {
@@ -59,6 +61,11 @@
     }
 
     @Override
+    protected UnaryOp<Sqrt> getOp(ArithmeticOpTable table) {
+        return table.getSqrt();
+    }
+
+    @Override
     public void generate(NodeLIRBuilderTool nodeValueMap, ArithmeticLIRGeneratorTool gen) {
         nodeValueMap.setResult(this, gen.emitMathSqrt(nodeValueMap.operand(getValue())));
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/SubNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -53,7 +53,7 @@
     }
 
     protected SubNode(NodeClass<? extends SubNode> c, ValueNode x, ValueNode y) {
-        super(c, ArithmeticOpTable::getSub, x, y);
+        super(c, getArithmeticOpTable(x).getSub(), x, y);
     }
 
     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -66,6 +66,11 @@
         return canonical(null, op, stamp, x, y, view);
     }
 
+    @Override
+    protected BinaryOp<Sub> getOp(ArithmeticOpTable table) {
+        return table.getSub();
+    }
+
     private static ValueNode canonical(SubNode subNode, BinaryOp<Sub> op, Stamp stamp, ValueNode forX, ValueNode forY, NodeView view) {
         SubNode self = subNode;
         if (GraphUtil.unproxify(forX) == GraphUtil.unproxify(forY)) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryArithmeticNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnaryArithmeticNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,7 @@
 
 package org.graalvm.compiler.nodes.calc;
 
-import java.io.Serializable;
-import java.util.function.Function;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
@@ -44,18 +43,14 @@
 
     @SuppressWarnings("rawtypes") public static final NodeClass<UnaryArithmeticNode> TYPE = NodeClass.create(UnaryArithmeticNode.class);
 
-    protected interface SerializableUnaryFunction<T> extends Function<ArithmeticOpTable, UnaryOp<T>>, Serializable {
+    protected UnaryArithmeticNode(NodeClass<? extends UnaryArithmeticNode<OP>> c, UnaryOp<OP> opForStampComputation, ValueNode value) {
+        super(c, opForStampComputation.foldStamp(value.stamp(NodeView.DEFAULT)), value);
     }
 
-    protected final SerializableUnaryFunction<OP> getOp;
-
-    protected UnaryArithmeticNode(NodeClass<? extends UnaryArithmeticNode<OP>> c, SerializableUnaryFunction<OP> getOp, ValueNode value) {
-        super(c, getOp.apply(ArithmeticOpTable.forStamp(value.stamp(NodeView.DEFAULT))).foldStamp(value.stamp(NodeView.DEFAULT)), value);
-        this.getOp = getOp;
-    }
+    protected abstract UnaryOp<OP> getOp(ArithmeticOpTable table);
 
     protected final UnaryOp<OP> getOp(ValueNode forValue) {
-        return getOp.apply(ArithmeticOpTable.forStamp(forValue.stamp(NodeView.DEFAULT)));
+        return getOp(getArithmeticOpTable(forValue));
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/UnsignedRightShiftNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -24,8 +24,10 @@
 
 package org.graalvm.compiler.nodes.calc;
 
-import jdk.vm.ci.code.CodeUtil;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
+
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.ShiftOp.UShr;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
@@ -38,6 +40,7 @@
 import org.graalvm.compiler.nodes.ValueNode;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
+import jdk.vm.ci.code.CodeUtil;
 import jdk.vm.ci.meta.JavaKind;
 
 @NodeInfo(shortName = ">>>")
@@ -46,7 +49,7 @@
     public static final NodeClass<UnsignedRightShiftNode> TYPE = NodeClass.create(UnsignedRightShiftNode.class);
 
     public UnsignedRightShiftNode(ValueNode x, ValueNode y) {
-        super(TYPE, ArithmeticOpTable::getUShr, x, y);
+        super(TYPE, getArithmeticOpTable(x).getUShr(), x, y);
     }
 
     public static ValueNode create(ValueNode x, ValueNode y, NodeView view) {
@@ -61,6 +64,11 @@
     }
 
     @Override
+    protected ShiftOp<UShr> getOp(ArithmeticOpTable table) {
+        return table.getUShr();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         NodeView view = NodeView.from(tool);
         ValueNode ret = super.canonical(tool, forX, forY);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/XorNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -50,7 +50,7 @@
     public static final NodeClass<XorNode> TYPE = NodeClass.create(XorNode.class);
 
     public XorNode(ValueNode x, ValueNode y) {
-        super(TYPE, ArithmeticOpTable::getXor, x, y);
+        super(TYPE, getArithmeticOpTable(x).getXor(), x, y);
         assert x.stamp(NodeView.DEFAULT).isCompatible(y.stamp(NodeView.DEFAULT));
     }
 
@@ -65,6 +65,11 @@
     }
 
     @Override
+    protected BinaryOp<Xor> getOp(ArithmeticOpTable table) {
+        return table.getXor();
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forX, ValueNode forY) {
         ValueNode ret = super.canonical(tool, forX, forY);
         if (ret != this) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ZeroExtendNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/calc/ZeroExtendNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 package org.graalvm.compiler.nodes.calc;
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
 import org.graalvm.compiler.core.common.calc.CanonicalCondition;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
@@ -60,7 +61,7 @@
     }
 
     public ZeroExtendNode(ValueNode input, int inputBits, int resultBits, boolean inputAlwaysPositive) {
-        super(TYPE, ArithmeticOpTable::getZeroExtend, ArithmeticOpTable::getNarrow, inputBits, resultBits, input);
+        super(TYPE, getArithmeticOpTable(input).getZeroExtend(), inputBits, resultBits, input);
         this.inputAlwaysPositive = inputAlwaysPositive;
     }
 
@@ -82,6 +83,16 @@
     }
 
     @Override
+    protected IntegerConvertOp<ZeroExtend> getOp(ArithmeticOpTable table) {
+        return table.getZeroExtend();
+    }
+
+    @Override
+    protected IntegerConvertOp<Narrow> getReverseOp(ArithmeticOpTable table) {
+        return table.getNarrow();
+    }
+
+    @Override
     public boolean isLossless() {
         return true;
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/extended/IntegerSwitchNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -429,11 +429,14 @@
         }
 
         /*
-         * Collect dead successors. Successors have to be cleaned before adding the new node to the
-         * graph.
+         * Surviving successors have to be cleaned before adding the new node to the graph. Keep the
+         * dead ones attached to the old node for later cleanup.
          */
-        List<AbstractBeginNode> deadSuccessors = successors.filter(s -> !newSuccessors.contains(s)).snapshot();
-        successors.clear();
+        for (int i = 0; i < successors.size(); i++) {
+            if (newSuccessors.contains(successors.get(i))) {
+                successors.set(i, null);
+            }
+        }
 
         /*
          * Create the new switch node. This is done before removing dead successors as `killCFG`
@@ -443,14 +446,11 @@
         AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
         SwitchNode newSwitch = graph().add(new IntegerSwitchNode(newValue, successorsArray, newKeys, newKeyProbabilities, newKeySuccessors));
 
-        /* Remove dead successors. */
-        for (AbstractBeginNode successor : deadSuccessors) {
-            GraphUtil.killCFG(successor);
-        }
-
         /* Replace ourselves with the new switch */
         ((FixedWithNextNode) predecessor()).setNext(newSwitch);
-        GraphUtil.killWithUnusedFloatingInputs(this);
+
+        // Remove the old switch and the dead successors.
+        GraphUtil.killCFG(this);
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/spi/LoweringProvider.java	Thu Oct 10 10:57:42 2019 -0400
@@ -53,8 +53,7 @@
     Integer smallestCompareWidth();
 
     /**
-     * Returns the granularity in terms of bytes that this target platform's bulk zeroing supports.
-     * Returns 0 to indicate that this target platform does not support bulk zeroing instruction.
+     * Indicates whether this target platform supports bulk zeroing of arbitrary size.
      */
-    int bulkZeroingStride();
+    boolean supportsBulkZeroing();
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/util/GraphUtil.java	Thu Oct 10 10:57:42 2019 -0400
@@ -742,19 +742,22 @@
 
     /**
      * Tries to find an original value of the given node by traversing through proxies and
-     * unambiguous phis. Note that this method will perform an exhaustive search through phis. It is
-     * intended to be used during graph building, when phi nodes aren't yet canonicalized.
+     * unambiguous phis. Note that this method will perform an exhaustive search through phis.
      *
-     * @param value The node whose original value should be determined.
-     * @return The original value (which might be the input value itself).
+     * @param value the node whose original value should be determined
+     * @param abortOnLoopPhi specifies if the traversal through phis should stop and return
+     *            {@code value} if it hits a {@linkplain PhiNode#isLoopPhi loop phi}. This argument
+     *            must be {@code true} if used during graph building as loop phi nodes may not yet
+     *            have all their inputs computed.
+     * @return the original value (which might be {@code value} itself)
      */
-    public static ValueNode originalValue(ValueNode value) {
-        ValueNode result = originalValueSimple(value);
+    public static ValueNode originalValue(ValueNode value, boolean abortOnLoopPhi) {
+        ValueNode result = originalValueSimple(value, abortOnLoopPhi);
         assert result != null;
         return result;
     }
 
-    private static ValueNode originalValueSimple(ValueNode value) {
+    private static ValueNode originalValueSimple(ValueNode value, boolean abortOnLoopPhi) {
         /* The very simple case: look through proxies. */
         ValueNode cur = originalValueForProxy(value);
 
@@ -765,6 +768,10 @@
              */
             PhiNode phi = (PhiNode) cur;
 
+            if (abortOnLoopPhi && phi.isLoopPhi()) {
+                return value;
+            }
+
             ValueNode phiSingleValue = null;
             int count = phi.valueCount();
             for (int i = 0; i < count; ++i) {
@@ -783,7 +790,7 @@
                          * of the inputs is another phi function. We need to do a complicated
                          * exhaustive check.
                          */
-                        return originalValueForComplicatedPhi(phi, new NodeBitMap(value.graph()));
+                        return originalValueForComplicatedPhi(value, phi, new NodeBitMap(value.graph()), abortOnLoopPhi);
                     } else {
                         /*
                          * We have two different input values for the phi function, but none of them
@@ -819,8 +826,12 @@
     /**
      * Handling for complicated nestings of phi functions. We need to reduce phi functions
      * recursively, and need a temporary map of visited nodes to avoid endless recursion of cycles.
+     *
+     * @param value the node whose original value is being determined
+     * @param abortOnLoopPhi specifies if the traversal through phis should stop and return
+     *            {@code value} if it hits a {@linkplain PhiNode#isLoopPhi loop phi}
      */
-    private static ValueNode originalValueForComplicatedPhi(PhiNode phi, NodeBitMap visited) {
+    private static ValueNode originalValueForComplicatedPhi(ValueNode value, PhiNode phi, NodeBitMap visited, boolean abortOnLoopPhi) {
         if (visited.isMarked(phi)) {
             /*
              * Found a phi function that was already seen. Either a cycle, or just a second phi
@@ -836,7 +847,16 @@
             ValueNode phiCurValue = originalValueForProxy(phi.valueAt(i));
             if (phiCurValue instanceof PhiNode) {
                 /* Recursively process a phi function input. */
-                phiCurValue = originalValueForComplicatedPhi((PhiNode) phiCurValue, visited);
+                PhiNode curPhi = (PhiNode) phiCurValue;
+                if (abortOnLoopPhi && curPhi.isLoopPhi()) {
+                    return value;
+                }
+                phiCurValue = originalValueForComplicatedPhi(value, curPhi, visited, abortOnLoopPhi);
+                if (phiCurValue == value) {
+                    // Hit a loop phi
+                    assert abortOnLoopPhi;
+                    return value;
+                }
             }
 
             if (phiCurValue == null) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.aarch64/src/org/graalvm/compiler/replacements/aarch64/AArch64GraphBuilderPlugins.java	Thu Oct 10 10:57:42 2019 -0400
@@ -47,6 +47,7 @@
 import org.graalvm.compiler.nodes.memory.address.OffsetAddressNode;
 import org.graalvm.compiler.replacements.TargetGraphBuilderPlugins;
 import org.graalvm.compiler.replacements.nodes.BinaryMathIntrinsicNode;
+import org.graalvm.compiler.replacements.nodes.FusedMultiplyAddNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode;
 import org.graalvm.compiler.replacements.nodes.UnaryMathIntrinsicNode.UnaryOperation;
 import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
@@ -61,16 +62,11 @@
     @Override
     public void register(Plugins plugins, BytecodeProvider replacementsBytecodeProvider, Architecture arch, boolean explicitUnsafeNullChecks, boolean registerMathPlugins,
                     boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) {
-        register(plugins, replacementsBytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, emitJDK9StringSubstitutions);
+        register(plugins, replacementsBytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, emitJDK9StringSubstitutions, useFMAIntrinsics);
     }
 
     public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks,
-                    boolean registerMathPlugins) {
-        register(plugins, bytecodeProvider, explicitUnsafeNullChecks, registerMathPlugins, true);
-    }
-
-    public static void register(Plugins plugins, BytecodeProvider bytecodeProvider, boolean explicitUnsafeNullChecks,
-                    boolean registerMathPlugins, boolean emitJDK9StringSubstitutions) {
+                    boolean registerMathPlugins, boolean emitJDK9StringSubstitutions, boolean useFMAIntrinsics) {
         InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
         invocationPlugins.defer(new Runnable() {
             @Override
@@ -78,7 +74,7 @@
                 registerIntegerLongPlugins(invocationPlugins, JavaKind.Int, bytecodeProvider);
                 registerIntegerLongPlugins(invocationPlugins, JavaKind.Long, bytecodeProvider);
                 if (registerMathPlugins) {
-                    registerMathPlugins(invocationPlugins);
+                    registerMathPlugins(invocationPlugins, useFMAIntrinsics);
                 }
                 if (emitJDK9StringSubstitutions) {
                     registerStringLatin1Plugins(invocationPlugins, bytecodeProvider);
@@ -130,7 +126,7 @@
         });
     }
 
-    private static void registerMathPlugins(InvocationPlugins plugins) {
+    private static void registerMathPlugins(InvocationPlugins plugins, boolean useFMAIntrinsics) {
         Registration r = new Registration(plugins, Math.class);
         registerUnaryMath(r, "sin", SIN);
         registerUnaryMath(r, "cos", COS);
@@ -148,6 +144,36 @@
         registerRound(r, "rint", RoundingMode.NEAREST);
         registerRound(r, "ceil", RoundingMode.UP);
         registerRound(r, "floor", RoundingMode.DOWN);
+        if (useFMAIntrinsics && JavaVersionUtil.JAVA_SPEC > 8) {
+            registerFMA(r);
+        }
+    }
+
+    private static void registerFMA(Registration r) {
+        r.register3("fma", Double.TYPE, Double.TYPE, Double.TYPE, new InvocationPlugin() {
+            @Override
+            public boolean apply(GraphBuilderContext b,
+                            ResolvedJavaMethod targetMethod,
+                            Receiver receiver,
+                            ValueNode na,
+                            ValueNode nb,
+                            ValueNode nc) {
+                b.push(JavaKind.Double, b.append(new FusedMultiplyAddNode(na, nb, nc)));
+                return true;
+            }
+        });
+        r.register3("fma", Float.TYPE, Float.TYPE, Float.TYPE, new InvocationPlugin() {
+            @Override
+            public boolean apply(GraphBuilderContext b,
+                            ResolvedJavaMethod targetMethod,
+                            Receiver receiver,
+                            ValueNode na,
+                            ValueNode nb,
+                            ValueNode nc) {
+                b.push(JavaKind.Float, b.append(new FusedMultiplyAddNode(na, nb, nc)));
+                return true;
+            }
+        });
     }
 
     private static void registerUnaryMath(Registration r, String name, UnaryOperation operation) {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64FloatConvertNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.amd64/src/org/graalvm/compiler/replacements/amd64/AMD64FloatConvertNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -26,10 +26,12 @@
 
 import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_8;
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_1;
+import static org.graalvm.compiler.nodes.calc.BinaryArithmeticNode.getArithmeticOpTable;
 
-import jdk.vm.ci.meta.JavaConstant;
 import org.graalvm.compiler.core.common.calc.FloatConvert;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.FloatConvertOp;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.UnaryOp;
 import org.graalvm.compiler.core.common.type.IntegerStamp;
 import org.graalvm.compiler.core.common.type.Stamp;
 import org.graalvm.compiler.core.common.type.StampFactory;
@@ -43,6 +45,8 @@
 import org.graalvm.compiler.nodes.spi.ArithmeticLIRLowerable;
 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
 
+import jdk.vm.ci.meta.JavaConstant;
+
 /**
  * This node has the semantics of the AMD64 floating point conversions. It is used in the lowering
  * of the {@link FloatConvertNode} which, on AMD64 needs a {@link AMD64FloatConvertNode} plus some
@@ -58,12 +62,17 @@
     protected final FloatConvert op;
 
     public AMD64FloatConvertNode(FloatConvert op, ValueNode value) {
-        super(TYPE, table -> table.getFloatConvert(op), value);
+        super(TYPE, getArithmeticOpTable(value).getFloatConvert(op), value);
         this.op = op;
         this.stamp = this.stamp.meet(createInexactCaseStamp());
     }
 
     @Override
+    protected UnaryOp<FloatConvertOp> getOp(ArithmeticOpTable table) {
+        return table.getFloatConvert(op);
+    }
+
+    @Override
     public ValueNode canonical(CanonicalizerTool tool, ValueNode forValue) {
         // nothing to do
         return this;
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements.test/src/org/graalvm/compiler/replacements/test/classfile/ClassfileBytecodeProviderTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -87,13 +87,6 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
-import org.graalvm.compiler.test.ModuleSupport;
-import org.graalvm.compiler.test.SubprocessUtil;
-import org.junit.Assert;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.Test;
-
 import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
 import org.graalvm.compiler.api.test.Graal;
 import org.graalvm.compiler.bytecode.Bytecode;
@@ -111,6 +104,12 @@
 import org.graalvm.compiler.replacements.classfile.ClassfileBytecodeProvider;
 import org.graalvm.compiler.runtime.RuntimeProvider;
 import org.graalvm.compiler.serviceprovider.JavaVersionUtil;
+import org.graalvm.compiler.test.ModuleSupport;
+import org.graalvm.compiler.test.SubprocessUtil;
+import org.junit.Assert;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.Test;
 
 import jdk.vm.ci.meta.ConstantPool;
 import jdk.vm.ci.meta.JavaField;
@@ -209,6 +208,17 @@
                                     }
                                     try {
                                         checkClass(metaAccess, getSnippetReflection(), className);
+                                    } catch (UnsupportedClassVersionError e) {
+                                        // graal-test.jar can contain classes compiled for different
+                                        // Java versions
+                                    } catch (NoClassDefFoundError e) {
+                                        if (!e.getMessage().contains("Could not initialize class")) {
+                                            throw e;
+                                        } else {
+                                            // A second or later attempt to initialize a class
+                                            // results in this confusing error where the
+                                            // original cause of initialization failure is lost
+                                        }
                                     } catch (ClassNotFoundException e) {
                                         throw new AssertionError(e);
                                     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/StandardGraphBuilderPlugins.java	Thu Oct 10 10:57:42 2019 -0400
@@ -835,7 +835,7 @@
             @Override
             public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
                 ValueNode object = receiver.get();
-                ValueNode folded = GetClassNode.tryFold(b.getMetaAccess(), b.getConstantReflection(), NodeView.DEFAULT, GraphUtil.originalValue(object));
+                ValueNode folded = GetClassNode.tryFold(b.getMetaAccess(), b.getConstantReflection(), NodeView.DEFAULT, GraphUtil.originalValue(object, true));
                 if (folded != null) {
                     b.addPush(JavaKind.Object, folded);
                 } else {
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ZeroMemoryNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/ZeroMemoryNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -48,19 +48,21 @@
     public static final NodeClass<ZeroMemoryNode> TYPE = NodeClass.create(ZeroMemoryNode.class);
 
     @Input ValueNode length;
+    private final boolean isAligned;
 
-    public ZeroMemoryNode(ValueNode address, ValueNode length, LocationIdentity locationIdentity) {
-        this(OffsetAddressNode.create(address), length, locationIdentity, BarrierType.NONE);
+    public ZeroMemoryNode(ValueNode address, ValueNode length, boolean isAligned, LocationIdentity locationIdentity) {
+        this(OffsetAddressNode.create(address), length, isAligned, locationIdentity, BarrierType.NONE);
     }
 
-    public ZeroMemoryNode(AddressNode address, ValueNode length, LocationIdentity locationIdentity, BarrierType type) {
+    public ZeroMemoryNode(AddressNode address, ValueNode length, boolean isAligned, LocationIdentity locationIdentity, BarrierType type) {
         super(TYPE, address, locationIdentity, StampFactory.forVoid(), type);
         this.length = length;
+        this.isAligned = isAligned;
     }
 
     @Override
     public void generate(NodeLIRBuilderTool gen) {
-        gen.getLIRGeneratorTool().emitZeroMemory(gen.operand(getAddress()), gen.operand(length));
+        gen.getLIRGeneratorTool().emitZeroMemory(gen.operand(getAddress()), gen.operand(length), isAligned);
     }
 
     @Override
@@ -69,5 +71,5 @@
     }
 
     @NodeIntrinsic
-    public static native void zero(Word address, long length, @ConstantNodeParameter LocationIdentity locationIdentity);
+    public static native void zero(Word address, long length, @ConstantNodeParameter boolean isAligned, @ConstantNodeParameter LocationIdentity locationIdentity);
 }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/nodes/arithmetic/UnsignedMulHighNode.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_2;
 
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable;
+import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp;
 import org.graalvm.compiler.core.common.type.ArithmeticOpTable.BinaryOp.UMulHigh;
 import org.graalvm.compiler.graph.NodeClass;
 import org.graalvm.compiler.graph.spi.Canonicalizable;
@@ -49,7 +50,12 @@
     public static final NodeClass<UnsignedMulHighNode> TYPE = NodeClass.create(UnsignedMulHighNode.class);
 
     public UnsignedMulHighNode(ValueNode x, ValueNode y) {
-        super(TYPE, ArithmeticOpTable::getUMulHigh, x, y);
+        super(TYPE, getArithmeticOpTable(x).getUMulHigh(), x, y);
+    }
+
+    @Override
+    protected BinaryOp<UMulHigh> getOp(ArithmeticOpTable table) {
+        return table.getUMulHigh();
     }
 
     @Override
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/DefaultGraphTypes.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.graphio/src/org/graalvm/graphio/DefaultGraphTypes.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -30,10 +30,17 @@
     private DefaultGraphTypes() {
     }
 
+    @SuppressWarnings("unchecked")
     @Override
     public Class<?> enumClass(Object enumValue) {
         if (enumValue instanceof Enum<?>) {
-            return enumValue.getClass();
+            // check that the enum class is not actually an anonymous subclass:
+            Class<? extends Enum<?>> enumClass = (Class<? extends Enum<?>>) enumValue.getClass();
+            Enum<?>[] constants = enumClass.getEnumConstants();
+            if (constants == null && enumClass.isAnonymousClass()) {
+                enumClass = (Class<? extends Enum<?>>) enumClass.getSuperclass();
+            }
+            return enumClass;
         }
         return null;
     }
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/package-info.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/package-info.java	Thu Oct 10 10:57:42 2019 -0400
@@ -25,7 +25,7 @@
 
 /**
  *  Doclets provide the user-selectable backends for processing the
- *  documentation comnments in Java source code.
+ *  documentation comments in Java source code.
  *
  *  <p>Doclets are implementations of the {@link jdk.javadoc.doclet Doclet API}.</p>
  *
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/builders/MemberSummaryBuilder.java	Thu Oct 10 10:57:42 2019 -0400
@@ -320,7 +320,7 @@
                     //necessary.
                     DocFinder.Output inheritedDoc =
                             DocFinder.search(configuration,
-                                    new DocFinder.Input(utils, (ExecutableElement) member));
+                                    new DocFinder.Input(utils, member));
                     if (inheritedDoc.holder != null
                             && !utils.getFirstSentenceTrees(inheritedDoc.holder).isEmpty()) {
                         // let the comment helper know of the overridden element
@@ -473,7 +473,7 @@
     private void addSummaryFootNote(TypeElement inheritedClass, SortedSet<Element> inheritedMembers,
                                     Content linksTree, MemberSummaryWriter writer) {
         for (Element member : inheritedMembers) {
-            TypeElement t = (utils.isPackagePrivate(inheritedClass) && !utils.isLinkable(inheritedClass))
+            TypeElement t = utils.isUndocumentedEnclosure(inheritedClass)
                     ? typeElement : inheritedClass;
             writer.addInheritedMemberSummary(t, member, inheritedMembers.first() == member,
                     inheritedMembers.last() == member, linksTree);
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Thu Oct 10 10:57:42 2019 -0400
@@ -529,6 +529,10 @@
         return true;
     }
 
+    public boolean isUndocumentedEnclosure(TypeElement enclosingTypeElement) {
+        return isPackagePrivate(enclosingTypeElement) && !isLinkable(enclosingTypeElement);
+    }
+
     public boolean isError(TypeElement te) {
         if (isEnum(te) || isInterface(te) || isAnnotationType(te)) {
             return false;
@@ -1064,8 +1068,7 @@
 
         // Allow for the behavior that members of undocumented supertypes
         // may be included in documented types
-        TypeElement enclElem = getEnclosingTypeElement(elem);
-        if (typeElem != enclElem && isSubclassOf(typeElem, enclElem)) {
+        if (isUndocumentedEnclosure(getEnclosingTypeElement(elem))) {
             return true;
         }
 
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberTable.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/VisibleMemberTable.java	Thu Oct 10 10:57:42 2019 -0400
@@ -209,7 +209,7 @@
     public List<? extends Element> getVisibleMembers(Kind kind) {
         Predicate<Element> declaredAndLeafMembers = e -> {
             TypeElement encl = utils.getEnclosingTypeElement(e);
-            return encl == te || isUndocumentedEnclosure(encl);
+            return encl == te || utils.isUndocumentedEnclosure(encl);
         };
         return getVisibleMembers(kind, declaredAndLeafMembers);
     }
@@ -238,7 +238,8 @@
         ensureInitialized();
 
         OverridingMethodInfo found = overriddenMethodTable.get(e);
-        if (found != null && (found.simpleOverride || isUndocumentedEnclosure(utils.getEnclosingTypeElement(e)))) {
+        if (found != null
+                && (found.simpleOverride || utils.isUndocumentedEnclosure(utils.getEnclosingTypeElement(e)))) {
             return found.overrider;
         }
         return null;
@@ -347,10 +348,6 @@
         return pm == null ? null : pm.setter;
     }
 
-    boolean isUndocumentedEnclosure(TypeElement encl) {
-        return utils.isPackagePrivate(encl) && !utils.isLinkable(encl);
-    }
-
     private void computeParents() {
         for (TypeMirror intfType : te.getInterfaces()) {
             TypeElement intfc = utils.asTypeElement(intfType);
@@ -388,7 +385,7 @@
 
     private void computeLeafMembers(LocalMemberTable lmt, Kind kind) {
         List<Element> list = new ArrayList<>();
-        if (isUndocumentedEnclosure(te)) {
+        if (utils.isUndocumentedEnclosure(te)) {
             list.addAll(lmt.getOrderedMembers(kind));
         }
         parents.forEach(pvmt -> {
@@ -617,7 +614,7 @@
 
                 // Disallow package-private super methods to leak in
                 TypeElement encl = utils.getEnclosingTypeElement(inheritedMethod);
-                if (isUndocumentedEnclosure(encl)) {
+                if (utils.isUndocumentedEnclosure(encl)) {
                     overriddenMethodTable.computeIfAbsent(lMethod,
                             l -> new OverridingMethodInfo(inheritedMethod, false));
                     return false;
--- a/src/jdk.jcmd/share/classes/sun/tools/common/ProcessArgumentMatcher.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.jcmd/share/classes/sun/tools/common/ProcessArgumentMatcher.java	Thu Oct 10 10:57:42 2019 -0400
@@ -140,18 +140,14 @@
         return vids;
     }
 
-    public Collection<VirtualMachineDescriptor> getVirtualMachineDescriptors(Class<?> excludeClass) {
+    public Collection<VirtualMachineDescriptor> getVirtualMachineDescriptors() {
         if (singlePid != null) {
             return getSingleVMD(singlePid);
         } else {
-            return getVMDs(excludeClass, matchClass);
+            return getVMDs(null, matchClass);
         }
     }
 
-    public Collection<VirtualMachineDescriptor> getVirtualMachineDescriptors() {
-        return this.getVirtualMachineDescriptors(null);
-    }
-
     public Collection<String> getVirtualMachinePids(Class<?> excludeClass) {
         if (singlePid != null) {
             // There is a bug in AttachProvider, when VM is debuggee-suspended it's not listed by the AttachProvider.
@@ -162,7 +158,4 @@
         }
     }
 
-    public Collection<String> getVirtualMachinePids() {
-        return this.getVirtualMachinePids(null);
-    }
 }
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java	Thu Oct 10 10:57:42 2019 -0400
@@ -366,10 +366,16 @@
 
     public void setDestination(WriteableUserPath userSuppliedPath) throws IOException {
         synchronized (recorder) {
+            checkSetDestination(userSuppliedPath);
+            this.destination = userSuppliedPath;
+        }
+    }
+
+    public void checkSetDestination(WriteableUserPath userSuppliedPath) throws IOException {
+        synchronized (recorder) {
             if (Utils.isState(getState(), RecordingState.STOPPED, RecordingState.CLOSED)) {
                 throw new IllegalStateException("Destination can't be set on a recording that has been stopped/closed");
             }
-            this.destination = userSuppliedPath;
         }
     }
 
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ManagementSupport.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ManagementSupport.java	Thu Oct 10 10:57:42 2019 -0400
@@ -25,6 +25,8 @@
 
 package jdk.jfr.internal.management;
 
+import java.io.IOException;
+import java.nio.file.Paths;
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -98,4 +100,12 @@
         WriteableUserPath wup = pr.getDestination();
         return wup == null ? null : wup.getOriginalText();
     }
+
+    public static void checkSetDestination(Recording recording, String destination) throws IOException{
+        PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording);
+        if(destination != null){
+            WriteableUserPath wup = new WriteableUserPath(Paths.get(destination));
+            pr.checkSetDestination(wup);
+        }
+    }
 }
--- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java	Thu Oct 10 10:57:42 2019 -0400
@@ -28,6 +28,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringReader;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.security.AccessControlContext;
 import java.security.AccessController;
@@ -105,7 +106,8 @@
     private static final String OPTION_DISK = "disk";
     private static final String OPTION_DUMP_ON_EXIT = "dumpOnExit";
     private static final String OPTION_DURATION = "duration";
-    private static final List<String> OPTIONS = Arrays.asList(new String[] { OPTION_DUMP_ON_EXIT, OPTION_DURATION, OPTION_NAME, OPTION_MAX_AGE, OPTION_MAX_SIZE, OPTION_DISK, });
+    private static final String OPTION_DESTINATION = "destination";
+    private static final List<String> OPTIONS = Arrays.asList(new String[] { OPTION_DUMP_ON_EXIT, OPTION_DURATION, OPTION_NAME, OPTION_MAX_AGE, OPTION_MAX_SIZE, OPTION_DISK, OPTION_DESTINATION, });
     private final StreamManager streamHandler = new StreamManager();
     private final Map<Long, Object> changes = new ConcurrentHashMap<>();
     private final AtomicLong sequenceNumber = new AtomicLong();
@@ -283,6 +285,7 @@
         validateOption(ops, OPTION_MAX_AGE, MBeanUtils::duration);
         validateOption(ops, OPTION_MAX_SIZE, MBeanUtils::size);
         validateOption(ops, OPTION_DURATION, MBeanUtils::duration);
+        validateOption(ops, OPTION_DESTINATION, x -> MBeanUtils.destination(r, x));
 
         // All OK, now set them.atomically
         setOption(ops, OPTION_DUMP_ON_EXIT, "false", MBeanUtils::booleanValue, x -> r.setDumpOnExit(x));
@@ -291,6 +294,7 @@
         setOption(ops, OPTION_MAX_AGE, null, MBeanUtils::duration, x -> r.setMaxAge(x));
         setOption(ops, OPTION_MAX_SIZE, "0", MBeanUtils::size, x -> r.setMaxSize(x));
         setOption(ops, OPTION_DURATION, null, MBeanUtils::duration, x -> r.setDuration(x));
+        setOption(ops, OPTION_DESTINATION, null, x -> MBeanUtils.destination(r, x), x -> setOptionDestination(r, x));
     }
 
     @Override
@@ -305,6 +309,7 @@
         Long maxSize = r.getMaxSize();
         options.put(OPTION_MAX_SIZE, String.valueOf(maxSize == null ? "0" : maxSize.toString()));
         options.put(OPTION_DURATION, ManagementSupport.formatTimespan(r.getDuration(), " "));
+        options.put(OPTION_DESTINATION, ManagementSupport.getDestinationOriginalText(r));
         return options;
     }
 
@@ -349,6 +354,20 @@
         }
     }
 
+    private static void setOptionDestination(Recording recording, String destination){
+        try {
+            Path pathDestination = null;
+            if(destination != null){
+                pathDestination = Paths.get(destination);
+            }
+            recording.setDestination(pathDestination);
+        } catch (IOException e) {
+            IllegalArgumentException iae = new IllegalArgumentException("Not a valid destination " + destination);
+            iae.addSuppressed(e);
+            throw iae;
+        }
+    }
+
     private static <T, U> void validateOption(Map<String, String> options, String name, Function<String, U> validator) {
         try {
             String v = options.get(name);
--- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/MBeanUtils.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/MBeanUtils.java	Thu Oct 10 10:57:42 2019 -0400
@@ -24,6 +24,7 @@
  */
 package jdk.management.jfr;
 
+import java.io.IOException;
 import java.lang.management.ManagementPermission;
 import java.security.Permission;
 import java.time.DateTimeException;
@@ -37,6 +38,7 @@
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
+import jdk.jfr.Recording;
 import jdk.jfr.internal.management.ManagementSupport;
 
 final class MBeanUtils {
@@ -126,5 +128,16 @@
         }
         return size;
     }
+
+    public static String destination(Recording recording, String destination) throws IllegalArgumentException{
+        try {
+            ManagementSupport.checkSetDestination(recording, destination);
+            return destination;
+        }catch(IOException e){
+            IllegalArgumentException iae = new IllegalArgumentException("Not a valid destination " + destination);
+            iae.addSuppressed(e);
+            throw iae;
+        }
+    }
 }
 
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/JarFileSystem.java	Thu Oct 10 10:57:42 2019 -0400
@@ -60,18 +60,20 @@
 
     JarFileSystem(ZipFileSystemProvider provider, Path zfpath, Map<String,?> env) throws IOException {
         super(provider, zfpath, env);
-        if (isMultiReleaseJar()) {
+        Object o = getRuntimeVersion(env);
+        if (isMultiReleaseJar() && (o != null)) {
             int version;
-            Object o = env.get("multi-release");
             if (o instanceof String) {
                 String s = (String)o;
                 if (s.equals("runtime")) {
                     version = Runtime.version().feature();
+                } else if (s.matches("^[1-9][0-9]*$")) {
+                    version = Version.parse(s).feature();
                 } else {
-                    version = Integer.parseInt(s);
+                    throw new IllegalArgumentException("Invalid runtime version");
                 }
             } else if (o instanceof Integer) {
-                version = (Integer)o;
+                version = Version.parse(((Integer)o).toString()).feature();
             } else if (o instanceof Version) {
                 version = ((Version)o).feature();
             } else {
@@ -83,6 +85,23 @@
         }
     }
 
+    /**
+     * Utility method to get the release version for a multi-release JAR.  It
+     * first checks the documented property {@code releaseVersion} and if not
+     * found checks the original property {@code multi-release}
+     * @param env  ZIP FS map
+     * @return  release version or null if it is not specified
+     */
+    private Object getRuntimeVersion(Map<String, ?> env) {
+        Object o = null;
+        if (env.containsKey(ZipFileSystemProvider.PROPERTY_RELEASE_VERSION)) {
+            o = env.get(ZipFileSystemProvider.PROPERTY_RELEASE_VERSION);
+        } else {
+            o = env.get(ZipFileSystemProvider.PROPERTY_MULTI_RELEASE);
+        }
+        return o;
+    }
+
     private boolean isMultiReleaseJar() throws IOException {
         try (InputStream is = newInputStream(getBytes("/META-INF/MANIFEST.MF"))) {
             String multiRelease = new Manifest(is).getMainAttributes()
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Thu Oct 10 10:57:42 2019 -0400
@@ -81,13 +81,19 @@
         (PrivilegedAction<Boolean>)()->System.getProperty("os.name")
                                              .startsWith("Windows"));
     private static final byte[] ROOTPATH = new byte[] { '/' };
-    private static final String OPT_POSIX = "enablePosixFileAttributes";
-    private static final String OPT_DEFAULT_OWNER = "defaultOwner";
-    private static final String OPT_DEFAULT_GROUP = "defaultGroup";
-    private static final String OPT_DEFAULT_PERMISSIONS = "defaultPermissions";
+    private static final String PROPERTY_POSIX = "enablePosixFileAttributes";
+    private static final String PROPERTY_DEFAULT_OWNER = "defaultOwner";
+    private static final String PROPERTY_DEFAULT_GROUP = "defaultGroup";
+    private static final String PROPERTY_DEFAULT_PERMISSIONS = "defaultPermissions";
 
     private static final Set<PosixFilePermission> DEFAULT_PERMISSIONS =
         PosixFilePermissions.fromString("rwxrwxrwx");
+    // Property used to specify the compression mode to use
+    private static final String PROPERTY_COMPRESSION_METHOD = "compressionMethod";
+    // Value specified for compressionMethod property to compress Zip entries
+    private static final String COMPRESSION_METHOD_DEFLATED = "DEFLATED";
+    // Value specified for compressionMethod property to not compress Zip entries
+    private static final String COMPRESSION_METHOD_STORED = "STORED";
 
     private final ZipFileSystemProvider provider;
     private final Path zfpath;
@@ -124,8 +130,8 @@
         this.noExtt = "false".equals(env.get("zipinfo-time"));
         this.useTempFile  = isTrue(env, "useTempFile");
         this.forceEnd64 = isTrue(env, "forceZIP64End");
-        this.defaultCompressionMethod = isTrue(env, "noCompression") ? METHOD_STORED : METHOD_DEFLATED;
-        this.supportPosix = isTrue(env, OPT_POSIX);
+        this.defaultCompressionMethod = getDefaultCompressionMethod(env);
+        this.supportPosix = isTrue(env, PROPERTY_POSIX);
         this.defaultOwner = initOwner(zfpath, env);
         this.defaultGroup = initGroup(zfpath, env);
         this.defaultPermissions = initPermissions(env);
@@ -138,7 +144,7 @@
                     new END().write(os, 0, forceEnd64);
                 }
             } else {
-                throw new FileSystemNotFoundException(zfpath.toString());
+                throw new NoSuchFileException(zfpath.toString());
             }
         }
         // sm and existence check
@@ -163,6 +169,50 @@
         this.zfpath = zfpath;
     }
 
+    /**
+     * Return the compression method to use (STORED or DEFLATED).  If the
+     * property {@code commpressionMethod} is set use its value to determine
+     * the compression method to use.  If the property is not set, then the
+     * default compression is DEFLATED unless the property {@code noCompression}
+     * is set which is supported for backwards compatibility.
+     * @param env Zip FS map of properties
+     * @return The Compression method to use
+     */
+    private int getDefaultCompressionMethod(Map<String, ?> env) {
+        int result =
+                isTrue(env, "noCompression") ? METHOD_STORED : METHOD_DEFLATED;
+        if (env.containsKey(PROPERTY_COMPRESSION_METHOD)) {
+            Object compressionMethod =  env.get(PROPERTY_COMPRESSION_METHOD);
+            if (compressionMethod != null) {
+                if (compressionMethod instanceof String) {
+                    switch (((String) compressionMethod).toUpperCase()) {
+                        case COMPRESSION_METHOD_STORED:
+                            result = METHOD_STORED;
+                            break;
+                        case COMPRESSION_METHOD_DEFLATED:
+                            result = METHOD_DEFLATED;
+                            break;
+                        default:
+                            throw new IllegalArgumentException(String.format(
+                                    "The value for the %s property must be %s or %s",
+                                    PROPERTY_COMPRESSION_METHOD, COMPRESSION_METHOD_STORED,
+                                    COMPRESSION_METHOD_DEFLATED));
+                    }
+                } else {
+                    throw new IllegalArgumentException(String.format(
+                            "The Object type for the %s property must be a String",
+                            PROPERTY_COMPRESSION_METHOD));
+                }
+            } else {
+                throw new IllegalArgumentException(String.format(
+                        "The value for the %s property must be %s or %s",
+                        PROPERTY_COMPRESSION_METHOD, COMPRESSION_METHOD_STORED,
+                        COMPRESSION_METHOD_DEFLATED));
+            }
+        }
+        return result;
+    }
+
     // returns true if there is a name=true/"true" setting in env
     private static boolean isTrue(Map<String, ?> env, String name) {
         return "true".equals(env.get(name)) || TRUE.equals(env.get(name));
@@ -173,7 +223,7 @@
     // be determined, we try to go with system property "user.name". If that's not
     // accessible, we return "<zipfs_default>".
     private UserPrincipal initOwner(Path zfpath, Map<String, ?> env) throws IOException {
-        Object o = env.get(OPT_DEFAULT_OWNER);
+        Object o = env.get(PROPERTY_DEFAULT_OWNER);
         if (o == null) {
             try {
                 PrivilegedExceptionAction<UserPrincipal> pa = ()->Files.getOwner(zfpath);
@@ -193,7 +243,7 @@
         if (o instanceof String) {
             if (((String)o).isEmpty()) {
                 throw new IllegalArgumentException("Value for property " +
-                    OPT_DEFAULT_OWNER + " must not be empty.");
+                        PROPERTY_DEFAULT_OWNER + " must not be empty.");
             }
             return ()->(String)o;
         }
@@ -201,7 +251,7 @@
             return (UserPrincipal)o;
         }
         throw new IllegalArgumentException("Value for property " +
-            OPT_DEFAULT_OWNER + " must be of type " + String.class +
+                PROPERTY_DEFAULT_OWNER + " must be of type " + String.class +
             " or " + UserPrincipal.class);
     }
 
@@ -210,7 +260,7 @@
     // If this is not possible/unsupported, we will return a group principal going by
     // the same name as the default owner.
     private GroupPrincipal initGroup(Path zfpath, Map<String, ?> env) throws IOException {
-        Object o = env.get(OPT_DEFAULT_GROUP);
+        Object o = env.get(PROPERTY_DEFAULT_GROUP);
         if (o == null) {
             try {
                 PosixFileAttributeView zfpv = Files.getFileAttributeView(zfpath, PosixFileAttributeView.class);
@@ -232,7 +282,7 @@
         if (o instanceof String) {
             if (((String)o).isEmpty()) {
                 throw new IllegalArgumentException("Value for property " +
-                    OPT_DEFAULT_GROUP + " must not be empty.");
+                        PROPERTY_DEFAULT_GROUP + " must not be empty.");
             }
             return ()->(String)o;
         }
@@ -240,14 +290,14 @@
             return (GroupPrincipal)o;
         }
         throw new IllegalArgumentException("Value for property " +
-            OPT_DEFAULT_GROUP + " must be of type " + String.class +
+                PROPERTY_DEFAULT_GROUP + " must be of type " + String.class +
             " or " + GroupPrincipal.class);
     }
 
     // Initialize the default permissions for files inside the zip archive.
     // If not specified in env, it will return 777.
     private Set<PosixFilePermission> initPermissions(Map<String, ?> env) {
-        Object o = env.get(OPT_DEFAULT_PERMISSIONS);
+        Object o = env.get(PROPERTY_DEFAULT_PERMISSIONS);
         if (o == null) {
             return DEFAULT_PERMISSIONS;
         }
@@ -256,7 +306,7 @@
         }
         if (!(o instanceof Set)) {
             throw new IllegalArgumentException("Value for property " +
-                OPT_DEFAULT_PERMISSIONS + " must be of type " + String.class +
+                PROPERTY_DEFAULT_PERMISSIONS + " must be of type " + String.class +
                 " or " + Set.class);
         }
         Set<PosixFilePermission> perms = new HashSet<>();
@@ -264,7 +314,7 @@
             if (o2 instanceof PosixFilePermission) {
                 perms.add((PosixFilePermission)o2);
             } else {
-                throw new IllegalArgumentException(OPT_DEFAULT_PERMISSIONS +
+                throw new IllegalArgumentException(PROPERTY_DEFAULT_PERMISSIONS +
                     " must only contain objects of type " + PosixFilePermission.class);
             }
         }
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java	Thu Oct 10 10:57:42 2019 -0400
@@ -53,6 +53,11 @@
  */
 public class ZipFileSystemProvider extends FileSystemProvider {
 
+    // Property used to specify the entry version to use for a multi-release JAR
+    static final String PROPERTY_RELEASE_VERSION = "releaseVersion";
+    // Original property used to specify the entry version to use for a
+    // multi-release JAR which is kept for backwards compatibility.
+    static final String PROPERTY_MULTI_RELEASE = "multi-release";
     private final Map<Path, ZipFileSystem> filesystems = new HashMap<>();
 
     public ZipFileSystemProvider() {}
@@ -104,20 +109,7 @@
                 if (filesystems.containsKey(realPath))
                     throw new FileSystemAlreadyExistsException();
             }
-            ZipFileSystem zipfs;
-            try {
-                if (env.containsKey("multi-release")) {
-                    zipfs = new JarFileSystem(this, path, env);
-                } else {
-                    zipfs = new ZipFileSystem(this, path, env);
-                }
-            } catch (ZipException ze) {
-                String pname = path.toString();
-                if (pname.endsWith(".zip") || pname.endsWith(".jar"))
-                    throw ze;
-                // assume NOT a zip/jar file
-                throw new UnsupportedOperationException();
-            }
+            ZipFileSystem zipfs = getZipFileSystem(path, env);
             if (realPath == null) {  // newly created
                 realPath = path.toRealPath();
             }
@@ -131,20 +123,25 @@
         throws IOException
     {
         ensureFile(path);
+        return getZipFileSystem(path, env);
+    }
+
+    private ZipFileSystem getZipFileSystem(Path path, Map<String, ?> env) throws IOException {
+        ZipFileSystem zipfs;
         try {
-            ZipFileSystem zipfs;
-            if (env.containsKey("multi-release")) {
+            if (env.containsKey(PROPERTY_RELEASE_VERSION) ||
+                    env.containsKey(PROPERTY_MULTI_RELEASE)) {
                 zipfs = new JarFileSystem(this, path, env);
             } else {
                 zipfs = new ZipFileSystem(this, path, env);
             }
-            return zipfs;
         } catch (ZipException ze) {
             String pname = path.toString();
             if (pname.endsWith(".zip") || pname.endsWith(".jar"))
                 throw ze;
             throw new UnsupportedOperationException();
         }
+        return zipfs;
     }
 
     @Override
--- a/src/jdk.zipfs/share/classes/module-info.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/src/jdk.zipfs/share/classes/module-info.java	Thu Oct 10 10:57:42 2019 -0400
@@ -147,7 +147,7 @@
  * <tbody>
  * <tr>
  *   <th scope="row">create</th>
- *   <td>java.lang.String</td>
+ *   <td>{@link java.lang.String} or {@link java.lang.Boolean}</td>
  *   <td>false</td>
  *   <td>
  *       If the value is {@code true}, the Zip file system provider
@@ -156,7 +156,7 @@
  * </tr>
  * <tr>
  *   <th scope="row">encoding</th>
- *   <td>java.lang.String</td>
+ *   <td>{@link java.lang.String}</td>
  *   <td>UTF-8</td>
  *   <td>
  *       The value indicates the encoding scheme for the
@@ -164,8 +164,8 @@
  *   </td>
  * </tr>
  * <tr>
- *   <td scope="row">enablePosixFileAttributes</td>
- *   <td>java.lang.String</td>
+ *   <th scope="row">enablePosixFileAttributes</th>
+ *   <td>{@link java.lang.String} or {@link java.lang.Boolean}</td>
  *   <td>false</td>
  *   <td>
  *       If the value is {@code true}, the Zip file system will support
@@ -173,8 +173,9 @@
  *   </td>
  * </tr>
  * <tr>
- *   <td scope="row">defaultOwner</td>
- *   <td>{@link java.nio.file.attribute.UserPrincipal UserPrincipal}<br> or java.lang.String</td>
+ *   <th scope="row">defaultOwner</th>
+ *   <td>{@link java.nio.file.attribute.UserPrincipal UserPrincipal}<br> or
+ *   {@link java.lang.String}</td>
  *   <td>null/unset</td>
  *   <td>
  *       Override the default owner for entries in the Zip file system.<br>
@@ -182,8 +183,9 @@
  *   </td>
  * </tr>
  * <tr>
- *   <td scope="row">defaultGroup</td>
- *   <td>{@link java.nio.file.attribute.GroupPrincipal GroupPrincipal}<br> or java.lang.String</td>
+ *   <th scope="row">defaultGroup</th>
+ *   <td>{@link java.nio.file.attribute.GroupPrincipal GroupPrincipal}<br> or
+ *   {@link java.lang.String}</td>
  *   <td>null/unset</td>
  *   <td>
  *       Override the the default group for entries in the Zip file system.<br>
@@ -191,9 +193,9 @@
  *   </td>
  * </tr>
  * <tr>
- *   <td scope="row">defaultPermissions</td>
+ *   <th scope="row">defaultPermissions</th>
  *   <td>{@link java.util.Set Set}&lt;{@link java.nio.file.attribute.PosixFilePermission PosixFilePermission}&gt;<br>
- *       or java.lang.String</td>
+ *       or {@link java.lang.String}</td>
  *   <td>null/unset</td>
  *   <td>
  *       Override the default Set of permissions for entries in the Zip file system.<br>
@@ -201,7 +203,66 @@
  *       a String that is parsed by {@link java.nio.file.attribute.PosixFilePermissions#fromString PosixFilePermissions::fromString}
  *   </td>
  * </tr>
- * </tbody>
+ * <tr>
+ *   <th scope="row">compressionMethod</th>
+ *   <td>{@link java.lang.String}</td>
+ *   <td>"DEFLATED"</td>
+ *   <td>
+ *       The value representing the compression method to use when writing entries
+ *       to the Zip file system.
+ *       <ul>
+ *           <li>
+ *               If the value is {@code "STORED"}, the Zip file system provider will
+ *               not compress entries when writing to the Zip file system.
+ *           </li>
+ *           <li>
+ *               If the value is {@code "DEFLATED"} or the property is not set,
+ *               the Zip file system provider will use data compression when
+ *               writing entries to the Zip file system.
+ *           </li>
+ *           <li>
+ *               If the value is not {@code "STORED"} or {@code "DEFLATED"}, an
+ *               {@code IllegalArgumentException} will be thrown when the Zip
+ *               filesystem is created.
+ *           </li>
+ *       </ul>
+ *   </td>
+ * </tr>
+ * <tr>
+ *   <th scope="row">releaseVersion</th>
+ *   <td>{@link java.lang.String} or {@link java.lang.Integer}</td>
+ *   <td>null/unset</td>
+ *   <td>
+ *       A value representing the version entry to use when accessing a
+ *       <a href=="{@docRoot}/../specs/jar/jar.html#multi-release-jar-files">
+ *       multi-release JAR</a>. If the JAR is not a
+ *       <a href=="{@docRoot}/../specs/jar/jar.html#multi-release-jar-files">
+ *       multi-release JAR</a>, the value will be ignored and the JAR will be
+ *       considered un-versioned.
+ *       <p>
+ *       The value must be either the string "runtime" or represent a valid
+ *       {@linkplain Runtime.Version Java SE Platform version number},
+ *       such as {@code 9} or {@code 14}, in order to determine the version entry.
+ *
+ *       <ul>
+ *           <li>
+ *               If the value is {@code null} or the property is not set,
+ *               then the JAR will be treated as an un-versioned JAR.
+ *           </li>
+ *           <li>
+ *               If the value is {@code "runtime"}, the
+ *               version entry will be determined by invoking
+ *               {@linkplain Runtime.Version#feature() Runtime.Version.feature()}.
+ *           </li>
+ *           <li>
+ *               If the value does not represent a valid
+ *               {@linkplain Runtime.Version Java SE Platform version number},
+ *               an {@code IllegalArgumentException} will be thrown.
+ *           </li>
+ *       </ul>
+ *   </td>
+ * </tr>
+ *  </tbody>
  * </table>
  *
  * <h2>Examples:</h2>
@@ -223,7 +284,7 @@
  * <pre>
  * {@code
  *
- *     FileSystem zipfs = FileSystems.newFileSystem(Path.of("helloworld.jar"), null);
+ *     FileSystem zipfs = FileSystems.newFileSystem(Path.of("helloworld.jar"));
  *     Path rootDir = zipfs.getPath("/");
  *     Files.walk(rootDir)
  *            .forEach(System.out::println);
--- a/test/hotspot/gtest/runtime/test_os_windows.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/gtest/runtime/test_os_windows.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -354,7 +354,7 @@
 
   if (convert_to_cstring(buf, JVM_MAXPATHLEN, path)) {
     ::testing::Test::RecordProperty(name, buf);
-    snprintf(buf, JVM_MAXPATHLEN, "%d", (int) wcslen(path));
+    os::snprintf(buf, JVM_MAXPATHLEN, "%d", (int) wcslen(path));
     ::testing::Test::RecordProperty(len_name, buf);
   }
 }
--- a/test/hotspot/jtreg/ProblemList-graal.txt	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/ProblemList-graal.txt	Thu Oct 10 10:57:42 2019 -0400
@@ -236,7 +236,6 @@
 runtime/exceptionMsgs/AbstractMethodError/AbstractMethodErrorTest.java        8222582 generic-all
 
 # Graal unit tests
-org.graalvm.compiler.core.test.CheckGraalInvariants                              8205081
 org.graalvm.compiler.core.test.OptionsVerifierTest                               8205081
 org.graalvm.compiler.hotspot.test.CompilationWrapperTest                         8205081
 org.graalvm.compiler.replacements.test.classfile.ClassfileBytecodeProviderTest   8205081
--- a/test/hotspot/jtreg/compiler/codecache/stress/UnexpectedDeoptimizationAllTest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/compiler/codecache/stress/UnexpectedDeoptimizationAllTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -33,12 +33,14 @@
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  *                                sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
- *                   -XX:+WhiteBoxAPI -XX:-DeoptimizeRandom
+ *                   -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:-DeoptimizeRandom
  *                   -XX:CompileCommand=dontinline,compiler.codecache.stress.Helper$TestCase::method
  *                   -XX:-SegmentedCodeCache
  *                   compiler.codecache.stress.UnexpectedDeoptimizationAllTest
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
- *                   -XX:+WhiteBoxAPI -XX:-DeoptimizeRandom
+ *                   -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:-DeoptimizeRandom
  *                   -XX:CompileCommand=dontinline,compiler.codecache.stress.Helper$TestCase::method
  *                   -XX:+SegmentedCodeCache
  *                   compiler.codecache.stress.UnexpectedDeoptimizationAllTest
--- a/test/hotspot/jtreg/compiler/codecache/stress/UnexpectedDeoptimizationTest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/compiler/codecache/stress/UnexpectedDeoptimizationTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -33,12 +33,14 @@
  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  *                                sun.hotspot.WhiteBox$WhiteBoxPermission
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
- *                   -XX:+WhiteBoxAPI -XX:-DeoptimizeRandom
+ *                   -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:-DeoptimizeRandom
  *                   -XX:CompileCommand=dontinline,compiler.codecache.stress.Helper$TestCase::method
  *                   -XX:-SegmentedCodeCache
  *                   compiler.codecache.stress.UnexpectedDeoptimizationTest
  * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions
- *                   -XX:+WhiteBoxAPI -XX:-DeoptimizeRandom
+ *                   -XX:+WhiteBoxAPI
+ *                   -XX:+IgnoreUnrecognizedVMOptions -XX:-DeoptimizeRandom
  *                   -XX:CompileCommand=dontinline,compiler.codecache.stress.Helper$TestCase::method
  *                   -XX:+SegmentedCodeCache
  *                   compiler.codecache.stress.UnexpectedDeoptimizationTest
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/graalunit/CoreAarch64Test.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary
+ * @requires vm.opt.final.EnableJVMCI == true
+ *
+ * @modules jdk.internal.vm.compiler
+ *
+ * @library /test/lib /compiler/graalunit /
+ *
+ * @build compiler.graalunit.common.GraalUnitTestLauncher
+ *
+ * @run driver jdk.test.lib.FileInstaller ../../ProblemList-graal.txt ExcludeList.txt
+ *
+ * @run main compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.core.aarch64.test -exclude ExcludeList.txt
+ */
+
+/* DO NOT MODIFY THIS FILE. GENERATED BY generateTests.sh */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/graalunit/CoreJdk9Test.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary
+ * @requires vm.opt.final.EnableJVMCI == true
+ *
+ * @modules jdk.internal.vm.compiler
+ *
+ * @library /test/lib /compiler/graalunit /
+ *
+ * @build compiler.graalunit.common.GraalUnitTestLauncher
+ *
+ * @run driver jdk.test.lib.FileInstaller ../../ProblemList-graal.txt ExcludeList.txt
+ *
+ * @run main compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.core.jdk9.test -exclude ExcludeList.txt
+ */
+
+/* DO NOT MODIFY THIS FILE. GENERATED BY generateTests.sh */
--- a/test/hotspot/jtreg/compiler/graalunit/EA9Test.java	Wed Oct 09 10:58:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * @test
- * @summary
- * @requires vm.opt.final.EnableJVMCI == true
- *
- * @modules jdk.internal.vm.compiler
- *
- * @library /test/lib /compiler/graalunit /
- *
- * @build compiler.graalunit.common.GraalUnitTestLauncher
- *
- * @run driver jdk.test.lib.FileInstaller ../../ProblemList-graal.txt ExcludeList.txt
- *
- * @run main compiler.graalunit.common.GraalUnitTestLauncher -prefix org.graalvm.compiler.core.jdk9.test.ea -exclude ExcludeList.txt
- */
-
-/* DO NOT MODIFY THIS FILE. GENERATED BY generateTests.sh */
--- a/test/hotspot/jtreg/compiler/graalunit/TestPackages.txt	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/compiler/graalunit/TestPackages.txt	Thu Oct 10 10:57:42 2019 -0400
@@ -4,18 +4,19 @@
 AsmAarch64    org.graalvm.compiler.asm.aarch64.test
 AsmAmd64      org.graalvm.compiler.asm.amd64.test
 AsmSparc      org.graalvm.compiler.asm.sparc.test
-CoreAmd64     org.graalvm.compiler.core.amd64.test
 Core          org.graalvm.compiler.core.test       @requires !vm.graal.enabled
 EA            org.graalvm.compiler.core.test.ea
-EA9           org.graalvm.compiler.core.jdk9.test.ea
+CoreAmd64     org.graalvm.compiler.core.amd64.test
+CoreAarch64   org.graalvm.compiler.core.aarch64.test
+CoreJdk9      org.graalvm.compiler.core.jdk9.test
 Debug         org.graalvm.compiler.debug.test
 Graph         org.graalvm.compiler.graph.test      @requires vm.graal.enabled
+Hotspot       org.graalvm.compiler.hotspot.test
 HotspotAarch64 org.graalvm.compiler.hotspot.aarch64.test
 HotspotAmd64  org.graalvm.compiler.hotspot.amd64.test
 HotspotJdk9   org.graalvm.compiler.hotspot.jdk9.test
 HotspotSparc  org.graalvm.compiler.hotspot.sparc.test @requires vm.simpleArch == "sparcv9"
 HotspotLir    org.graalvm.compiler.hotspot.lir.test
-Hotspot       org.graalvm.compiler.hotspot.test
 Loop          org.graalvm.compiler.loop.test
 Nodes         org.graalvm.compiler.nodes.test      @requires vm.graal.enabled
 Options       org.graalvm.compiler.options.test
--- a/test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/FindClassesByAnnotatedMethods.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/FindClassesByAnnotatedMethods.java	Thu Oct 10 10:57:42 2019 -0400
@@ -73,7 +73,7 @@
             System.out.print(jarFilePath);
             while (e.hasMoreElements()) {
                 JarEntry je = e.nextElement();
-                if (je.isDirectory() || !je.getName().endsWith(".class")) {
+                if (je.isDirectory() || !je.getName().endsWith(".class") || je.getName().equals("module-info.class")) {
                     continue;
                 }
                 Set<String> methodAnnotationTypes = new HashSet<>();
@@ -84,6 +84,8 @@
                 } catch (UnsupportedClassVersionError ucve) {
                     isSupported = false;
                     unsupportedClasses++;
+                } catch (Throwable t) {
+                    throw new InternalError("Error while parsing class from " + je + " in " + jarFilePath, t);
                 }
                 String className = je.getName().substring(0, je.getName().length() - ".class".length()).replaceAll("/", ".");
                 if (!isSupported) {
@@ -129,7 +131,7 @@
     /*
      * Small bytecode parser that extract annotations.
      */
-    private static final int MAJOR_VERSION_JAVA7 = 51;
+    private static final int MAJOR_VERSION_JAVA6 = 50;
     private static final int MAJOR_VERSION_OFFSET = 44;
     private static final byte CONSTANT_Utf8 = 1;
     private static final byte CONSTANT_Integer = 3;
@@ -146,6 +148,8 @@
     private static final byte CONSTANT_MethodType = 16;
     private static final byte CONSTANT_Dynamic = 17;
     private static final byte CONSTANT_InvokeDynamic = 18;
+    private static final byte CONSTANT_Module = 19;
+    private static final byte CONSTANT_Package = 20;
 
     private static void readClassfile(DataInputStream stream, Collection<String> methodAnnotationTypes) throws IOException {
         // magic
@@ -154,7 +158,7 @@
 
         int minor = stream.readUnsignedShort();
         int major = stream.readUnsignedShort();
-        if (major < MAJOR_VERSION_JAVA7) {
+        if (major < MAJOR_VERSION_JAVA6) {
             throw new UnsupportedClassVersionError("Unsupported class file version: " + major + "." + minor);
         }
         // Starting with JDK8, ignore a classfile that has a newer format than the current JDK.
@@ -210,7 +214,9 @@
             switch (tag) {
                 case CONSTANT_Class:
                 case CONSTANT_String:
-                case CONSTANT_MethodType: {
+                case CONSTANT_MethodType:
+                case CONSTANT_Module:
+                case CONSTANT_Package: {
                     skipFully(stream, 2);
                     break;
                 }
--- a/test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/JLModule.java	Wed Oct 09 10:58:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,211 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.mxtool.junit;
-
-import java.lang.reflect.Method;
-import java.util.Arrays;
-import java.util.Set;
-
-/**
- * Facade for the {@code java.lang.Module} class introduced in JDK9 that allows tests to be
- * developed against JDK8 but use module logic if deployed on JDK9.
- */
-class JLModule {
-
-    private final Object realModule;
-
-    JLModule(Object module) {
-        this.realModule = module;
-    }
-
-    private static final Class<?> moduleClass;
-    private static final Class<?> layerClass;
-
-    private static final Method bootMethod;
-    private static final Method modulesMethod;
-    private static final Method getModuleMethod;
-    private static final Method getUnnamedModuleMethod;
-    private static final Method getNameMethod;
-    private static final Method getPackagesMethod;
-    private static final Method isExportedMethod;
-    private static final Method isExported2Method;
-    private static final Method addExportsMethod;
-    private static final Method addOpensMethod;
-    static {
-        try {
-            moduleClass = findModuleClass();
-            Class<?> modulesClass = Class.forName("jdk.internal.module.Modules");
-            layerClass = findModuleLayerClass();
-            bootMethod = layerClass.getMethod("boot");
-            modulesMethod = layerClass.getMethod("modules");
-            getModuleMethod = Class.class.getMethod("getModule");
-            getUnnamedModuleMethod = ClassLoader.class.getMethod("getUnnamedModule");
-            getNameMethod = moduleClass.getMethod("getName");
-            getPackagesMethod = moduleClass.getMethod("getPackages");
-            isExportedMethod = moduleClass.getMethod("isExported", String.class);
-            isExported2Method = moduleClass.getMethod("isExported", String.class, moduleClass);
-            addExportsMethod = modulesClass.getDeclaredMethod("addExports", moduleClass, String.class, moduleClass);
-            addOpensMethod = getDeclaredMethodOptional(modulesClass, "addOpens", moduleClass, String.class, moduleClass);
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    // API change http://hg.openjdk.java.net/jdk9/dev/hotspot/rev/afedee84773e.
-    protected static Class<?> findModuleClass() throws ClassNotFoundException {
-        try {
-            return Class.forName("java.lang.Module");
-        } catch (ClassNotFoundException e) {
-            return Class.forName("java.lang.reflect.Module");
-        }
-    }
-
-    // API change http://hg.openjdk.java.net/jdk9/dev/hotspot/rev/afedee84773e.
-    protected static Class<?> findModuleLayerClass() throws ClassNotFoundException {
-        try {
-            return Class.forName("java.lang.ModuleLayer");
-        } catch (ClassNotFoundException e) {
-            return Class.forName("java.lang.reflect.Layer");
-        }
-    }
-
-    private static Method getDeclaredMethodOptional(Class<?> declaringClass, String name, Class<?>... parameterTypes) {
-        try {
-            return declaringClass.getDeclaredMethod(name, parameterTypes);
-        } catch (NoSuchMethodException e) {
-            return null;
-        }
-    }
-
-    public static JLModule fromClass(Class<?> cls) {
-        try {
-            return new JLModule(getModuleMethod.invoke(cls));
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public static JLModule find(String name) {
-        try {
-            Object bootLayer = bootMethod.invoke(null);
-            Set<Object> modules = (Set<Object>) modulesMethod.invoke(bootLayer);
-            for (Object m : modules) {
-                JLModule module = new JLModule(m);
-                String mname = module.getName();
-                if (mname.equals(name)) {
-                    return module;
-                }
-            }
-        } catch (Exception e) {
-            throw new InternalError(e);
-        }
-        return null;
-    }
-
-    public static JLModule getUnnamedModuleFor(ClassLoader cl) {
-        try {
-            return new JLModule(getUnnamedModuleMethod.invoke(cl));
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    public String getName() {
-        try {
-            return (String) getNameMethod.invoke(realModule);
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    /**
-     * Exports all packages in this module to a given module.
-     */
-    public void exportAllPackagesTo(JLModule module) {
-        if (this != module) {
-            for (String pkg : getPackages()) {
-                // Export all JVMCI packages dynamically instead
-                // of requiring a long list of -XaddExports
-                // options on the JVM command line.
-                if (!isExported(pkg, module)) {
-                    addExports(pkg, module);
-                    addOpens(pkg, module);
-                }
-            }
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    public Iterable<String> getPackages() {
-        try {
-            // API change http://hg.openjdk.java.net/jdk9/dev/hotspot/rev/afedee84773e#l1.15
-            Object res = getPackagesMethod.invoke(realModule);
-            if (res instanceof String[]) {
-                return Arrays.asList((String[]) res);
-            }
-            return (Set<String>) res;
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    public boolean isExported(String pn) {
-        try {
-            return (Boolean) isExportedMethod.invoke(realModule, pn);
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    public boolean isExported(String pn, JLModule other) {
-        try {
-            return (Boolean) isExported2Method.invoke(realModule, pn, other.realModule);
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    public void addExports(String pn, JLModule other) {
-        try {
-            addExportsMethod.invoke(null, realModule, pn, other.realModule);
-        } catch (Exception e) {
-            throw new AssertionError(e);
-        }
-    }
-
-    public void addOpens(String pn, JLModule other) {
-        if (addOpensMethod != null) {
-            try {
-                addOpensMethod.invoke(null, realModule, pn, other.realModule);
-            } catch (Exception e) {
-                throw new AssertionError(e);
-            }
-        }
-    }
-
-    @Override
-    public String toString() {
-        return realModule.toString();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/ModuleSupport.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.mxtool.junit;
+
+import java.io.PrintStream;
+import java.util.Set;
+
+/**
+ * Interface to {@code java.lang.Module} related functionality.
+ */
+class ModuleSupport {
+
+    /**
+     * @param out stream to use for printing warnings
+     */
+    ModuleSupport(PrintStream out) {
+    }
+
+    /**
+     * Exports and opens packages based on {@code spec}. See further documentation in
+     * {@code mx_unittest.py}.
+     *
+     * @param spec
+     * @param context
+     * @param opened the set of opens performed are added to this set in the format
+     *            {@code <module>/<package>=<target-module>(,<target-module>)*} (e.g.
+     *            {@code "com.foo/com.foo.util=ALL-NAMED,com.bar"})
+     * @param exported the set of exports performed are added to this set in the format
+     *            {@code <module>/<package>=<target-module>(,<target-module>)*} (e.g.
+     *            {@code "com.foo/com.foo.util=ALL-NAMED,com.bar"})
+     */
+    void openPackages(String spec, Object context, Set<String> opened, Set<String> exported) {
+        // Nop on JDK 8
+    }
+
+    /**
+     * Updates modules specified in {@code AddExport} annotations on {@code classes} to export and
+     * open packages to the annotation classes' declaring modules.
+     *
+     * @param classes
+     * @param opened the set of opens performed are added to this set in the format
+     *            {@code <module>/<package>=<target-module>(,<target-module>)*} (e.g.
+     *            {@code "com.foo/com.foo.util=ALL-NAMED,com.bar"})
+     * @param exported the set of exports performed are added to this set in the format
+     *            {@code <module>/<package>=<target-module>(,<target-module>)*} (e.g.
+     *            {@code "com.foo/com.foo.util=ALL-NAMED,com.bar"})
+     */
+    void processAddExportsAnnotations(Set<Class<?>> classes, Set<String> opened, Set<String> exported) {
+        // Nop on JDK 8
+    }
+}
--- a/test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/MxJUnitWrapper.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/MxJUnitWrapper.java	Thu Oct 10 10:57:42 2019 -0400
@@ -29,18 +29,13 @@
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.PrintStream;
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.Optional;
 import java.util.ServiceLoader;
 import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.TreeSet;
 
 import org.junit.internal.JUnitSystem;
 import org.junit.internal.RealSystem;
@@ -59,6 +54,14 @@
 
 public class MxJUnitWrapper {
 
+    // Unit tests that start a JVM subprocess can use these system properties to
+    // add --add-exports and --add-opens as necessary to the JVM command line.
+    //
+    // Known usages:
+    // org.graalvm.compiler.test.SubprocessUtil.getPackageOpeningOptions()
+    public static final String OPENED_PACKAGES_PROPERTY_NAME = "com.oracle.mxtool.junit.opens";
+    public static final String EXPORTED_PACKAGES_PROPERTY_NAME = "com.oracle.mxtool.junit.exports";
+
     public static class MxJUnitConfig {
 
         public boolean verbose = false;
@@ -136,14 +139,25 @@
 
         String[] expandedArgs = expandArgs(args);
         int i = 0;
+        List<String> testSpecs = new ArrayList<>();
+        List<String> openPackagesSpecs = new ArrayList<>();
         while (i < expandedArgs.length) {
             String each = expandedArgs[i];
             if (each.charAt(0) == '-') {
                 // command line arguments
                 if (each.contentEquals("-JUnitVerbose")) {
                     config.verbose = true;
+                    config.enableTiming = true;
+                } else if (each.contentEquals("-JUnitOpenPackages")) {
+                    if (i + 1 >= expandedArgs.length) {
+                        system.out().println("Must include argument for -JUnitAddExports");
+                        System.exit(1);
+                    }
+                    openPackagesSpecs.add(expandedArgs[++i]);
                 } else if (each.contentEquals("-JUnitVeryVerbose")) {
+                    config.verbose = true;
                     config.veryVerbose = true;
+                    config.enableTiming = true;
                 } else if (each.contentEquals("-JUnitFailFast")) {
                     config.failFast = true;
                 } else if (each.contentEquals("-JUnitEnableTiming")) {
@@ -172,21 +186,35 @@
                 }
 
             } else {
-
-                try {
-                    builder.addTestSpec(each);
-                } catch (MxJUnitRequest.BuilderException ex) {
-                    system.out().println(ex.getMessage());
-                    System.exit(1);
-                }
+                testSpecs.add(each);
             }
             i++;
         }
 
-        MxJUnitRequest request = builder.build();
+        ModuleSupport moduleSupport = new ModuleSupport(system.out());
+        Set<String> opened = new TreeSet<>();
+        Set<String> exported = new TreeSet<>();
+        for (String spec : openPackagesSpecs) {
+            moduleSupport.openPackages(spec, "-JUnitOpenPackages", opened, exported);
+        }
 
-        if (System.getProperty("java.specification.version").compareTo("1.9") >= 0) {
-            addExports(request.classes, system.out());
+        for (String spec : testSpecs) {
+            try {
+                builder.addTestSpec(spec);
+            } catch (MxJUnitRequest.BuilderException ex) {
+                system.out().println(ex.getMessage());
+                System.exit(1);
+            }
+        }
+
+        MxJUnitRequest request = builder.build();
+        moduleSupport.processAddExportsAnnotations(request.classes, opened, exported);
+
+        if (!opened.isEmpty()) {
+            System.setProperty(OPENED_PACKAGES_PROPERTY_NAME, String.join(System.lineSeparator(), opened));
+        }
+        if (!exported.isEmpty()) {
+            System.setProperty(EXPORTED_PACKAGES_PROPERTY_NAME, String.join(System.lineSeparator(), exported));
         }
 
         for (RunListener p : ServiceLoader.load(RunListener.class)) {
@@ -285,8 +313,6 @@
         return result;
     }
 
-    private static final Pattern MODULE_PACKAGE_RE = Pattern.compile("([^/]+)/(.+)");
-
     private static class Timing<T> implements Comparable<Timing<T>> {
         final T subject;
         final long value;
@@ -344,93 +370,6 @@
     }
 
     /**
-     * Adds the super types of {@code cls} to {@code supertypes}.
-     */
-    private static void gatherSupertypes(Class<?> cls, Set<Class<?>> supertypes) {
-        if (!supertypes.contains(cls)) {
-            supertypes.add(cls);
-            Class<?> superclass = cls.getSuperclass();
-            if (superclass != null) {
-                gatherSupertypes(superclass, supertypes);
-            }
-            for (Class<?> iface : cls.getInterfaces()) {
-                gatherSupertypes(iface, supertypes);
-            }
-        }
-    }
-
-    /**
-     * Updates modules specified in {@code AddExport} annotations on {@code classes} to export
-     * concealed packages to the annotation classes' declaring modules.
-     */
-    private static void addExports(Set<Class<?>> classes, PrintStream out) {
-        Set<Class<?>> types = new HashSet<>();
-        for (Class<?> cls : classes) {
-            gatherSupertypes(cls, types);
-        }
-        for (Class<?> cls : types) {
-            Annotation[] annos = cls.getAnnotations();
-            for (Annotation a : annos) {
-                Class<? extends Annotation> annotationType = a.annotationType();
-                if (annotationType.getSimpleName().equals("AddExports")) {
-                    Optional<String[]> value = getElement("value", String[].class, a);
-                    if (value.isPresent()) {
-                        for (String export : value.get()) {
-                            Matcher m = MODULE_PACKAGE_RE.matcher(export);
-                            if (m.matches()) {
-                                String moduleName = m.group(1);
-                                String packageName = m.group(2);
-                                JLModule module = JLModule.find(moduleName);
-                                if (module == null) {
-                                    out.printf("%s: Cannot find module named %s specified in \"AddExports\" annotation: %s%n", cls.getName(), moduleName, a);
-                                } else {
-                                    if (packageName.equals("*")) {
-                                        module.exportAllPackagesTo(JLModule.fromClass(cls));
-                                    } else {
-                                        module.addExports(packageName, JLModule.fromClass(cls));
-                                        module.addOpens(packageName, JLModule.fromClass(cls));
-                                    }
-                                }
-                            } else {
-                                out.printf("%s: Ignoring \"AddExports\" annotation with value not matching <module>/<package> pattern: %s%n", cls.getName(), a);
-                            }
-                        }
-                    } else {
-                        out.printf("%s: Ignoring \"AddExports\" annotation without `String value` element: %s%n", cls.getName(), a);
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Gets the value of the element named {@code name} of type {@code type} from {@code annotation}
-     * if present.
-     *
-     * @return the requested element value wrapped in an {@link Optional} or
-     *         {@link Optional#empty()} if {@code annotation} has no element named {@code name}
-     * @throws AssertionError if {@code annotation} has an element of the given name but whose type
-     *             is not {@code type} or if there's some problem reading the value via reflection
-     */
-    private static <T> Optional<T> getElement(String name, Class<T> type, Annotation annotation) {
-        Class<? extends Annotation> annotationType = annotation.annotationType();
-        Method valueAccessor;
-        try {
-            valueAccessor = annotationType.getMethod(name);
-            if (!valueAccessor.getReturnType().equals(type)) {
-                throw new AssertionError(String.format("Element %s of %s is of type %s, not %s ", name, annotationType.getName(), valueAccessor.getReturnType().getName(), type.getName()));
-            }
-        } catch (NoSuchMethodException e) {
-            return Optional.empty();
-        }
-        try {
-            return Optional.of(type.cast(valueAccessor.invoke(annotation)));
-        } catch (Exception e) {
-            throw new AssertionError(String.format("Could not read %s element from %s", name, annotation), e);
-        }
-    }
-
-    /**
      * Expand any arguments starting with @ and return the resulting argument array.
      *
      * @return the expanded argument array
--- a/test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/TextRunListener.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/TextRunListener.java	Thu Oct 10 10:57:42 2019 -0400
@@ -74,7 +74,8 @@
     }
 
     public static RunListener createRunListener(MxRunListener l) {
-        return new TextListener(l.getWriter()) {
+        PrintStream theWriter = l.getWriter();
+        return new TextListener(theWriter) {
             private Class<?> lastClass;
             private int passedInLastClass;
             private int failedInLastClass;
@@ -143,6 +144,15 @@
             public void testAssumptionFailure(Failure failure) {
                 l.testAssumptionFailure(failure);
             }
+
+            @Override
+            protected void printFailure(Failure each, String prefix) {
+                // Print out the test message in the same format used to run a single test:
+                // my.package.MyClass#methodName
+                String header = each.getDescription().getClassName() + "#" + each.getDescription().getMethodName();
+                theWriter.println(prefix + ") " + header);
+                theWriter.print(each.getTrace());
+            }
         };
     }
 }
--- a/test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/TimingDecorator.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/compiler/graalunit/com.oracle.mxtool.junit/com/oracle/mxtool/junit/TimingDecorator.java	Thu Oct 10 10:57:42 2019 -0400
@@ -22,8 +22,8 @@
  */
 package com.oracle.mxtool.junit;
 
-import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 import org.junit.runner.Description;
 
@@ -40,8 +40,8 @@
 
     TimingDecorator(MxRunListener l) {
         super(l);
-        this.classTimes = new HashMap<>();
-        this.testTimes = new HashMap<>();
+        this.classTimes = new ConcurrentHashMap<>();
+        this.testTimes = new ConcurrentHashMap<>();
     }
 
     @Override
--- a/test/hotspot/jtreg/compiler/graalunit/common/GraalUnitTestLauncher.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/compiler/graalunit/common/GraalUnitTestLauncher.java	Thu Oct 10 10:57:42 2019 -0400
@@ -229,6 +229,8 @@
         javaFlags.add("jdk.internal.vm.compiler,jdk.internal.vm.ci");
         javaFlags.add("--add-exports");
         javaFlags.add("java.base/jdk.internal.module=ALL-UNNAMED");
+        javaFlags.add("--add-exports");
+        javaFlags.add("java.base/jdk.internal.misc=ALL-UNNAMED");
         javaFlags.addAll(getModuleExports("jdk.internal.vm.compiler", "ALL-UNNAMED"));
         javaFlags.addAll(getModuleExports("jdk.internal.vm.ci", "ALL-UNNAMED,jdk.internal.vm.compiler"));
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/SplitIfSharedFastLockBehindCastPP.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 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
+ * 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 8231620
+ * @summary assert(bol->is_Bool()) crash during split if due to FastLockNode
+ *
+ * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement SplitIfSharedFastLockBehindCastPP
+ */
+
+
+public class SplitIfSharedFastLockBehindCastPP {
+    private static boolean field;
+    private static A obj_field;
+
+    public static void main(String[] args) {
+        A lock = new A();
+        obj_field = lock;
+        for (int i = 0; i < 20_000; i++) {
+            test1(true, lock);
+            test1(false, lock);
+            test2(true);
+            test2(false);
+        }
+    }
+
+    private static void test1(boolean flag, Object obj) {
+        if (obj == null) {
+        }
+
+        boolean flag2;
+        if (flag) {
+            flag2 = true;
+        } else {
+            flag2 = false;
+            obj = obj_field;
+        }
+
+        // This loop will be unswitched. The condition becomes candidate for split if
+        for (int i = 0; i < 100; i++) {
+            if (flag2) {
+                field = true;
+            } else {
+                field = false;
+            }
+            synchronized (obj) {
+                field = true;
+            }
+        }
+    }
+
+    private static Object test2(boolean flag) {
+        int integer;
+        if (flag) {
+            field = true;
+            integer = 1;
+        } else {
+            field = false;
+            integer = 2;
+        }
+
+        Object obj = integer;
+
+        // This loop will be unswitched. The condition becomes candidate for split if
+        for (int i = 0; i < 100; i++) {
+            if (integer == 1) {
+                field = true;
+            } else {
+                field = false;
+            }
+            synchronized (obj) {
+                field = true;
+            }
+        }
+        return obj;
+    }
+
+    private static final class A {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopstripmining/TestConservativeAntiDep.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 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
+ * 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 8231550
+ * @summary C2: ShouldNotReachHere() in verify_strip_mined_scheduling
+ *
+ * @run main/othervm -XX:-BackgroundCompilation -XX:LoopMaxUnroll=0 TestConservativeAntiDep
+ *
+ */
+
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
+public class TestConservativeAntiDep {
+    private static long longField;
+
+    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
+        for (int i = 0; i < 20_000; i++) {
+            test1(A.class);
+            test2(B.class);
+        }
+    }
+
+    private static int test1(Class klass) {
+        Object[] in = (Object[])Array.newInstance(klass, 100);
+
+        Object[] o = in;
+        int v = 1;
+        // CountedLoop has control dependent CastPP
+        for (int i = 0; i < 100 ; i++) {
+            longField = i; // sunk in outer strip mined loop
+            o = (A[]) o;
+            v *= 2;
+        }
+
+        // LoadRange cannot float higher than CountedLoop (because of
+        // CastPP) and is found anti-dependent with long store so
+        // scheduled in outer strip mined loop
+        return v + o.length;
+    }
+
+    private static int test2(Class klass) throws IllegalAccessException, InstantiationException {
+        A in = (A)klass.newInstance();
+
+        A o = in;
+        int v = 1;
+        // CountedLoop has control dependent CastPP
+        for (int i = 0; i < 100 ; i++) {
+            longField = i;  // sunk in outer strip mined loop
+            o = (B) o;
+            v *= 2;
+        }
+
+        // Load cannot float higher than CountedLoop (because of
+        // CastPP) and is found anti-dependent with long store so
+        // scheduled in outer strip mined loop
+        return v + o.intField;
+    }
+
+    private static class A {
+        int intField;
+        public A() {}
+    }
+
+    private static class B extends A {
+        public B() {}
+    }
+}
--- a/test/hotspot/jtreg/gc/g1/TestRemsetLoggingThreads.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/gc/g1/TestRemsetLoggingThreads.java	Thu Oct 10 10:57:42 2019 -0400
@@ -54,7 +54,7 @@
 
     OutputAnalyzer output = new OutputAnalyzer(pb.start());
 
-    String pattern = "Concurrent RS threads times \\(s\\)$";
+    String pattern = "Concurrent refinement threads times \\(s\\)$";
     Matcher m = Pattern.compile(pattern, Pattern.MULTILINE).matcher(output.getStdout());
 
     if (!m.find()) {
--- a/test/hotspot/jtreg/gc/g1/TestRemsetLoggingTools.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/gc/g1/TestRemsetLoggingTools.java	Thu Oct 10 10:57:42 2019 -0400
@@ -110,7 +110,7 @@
     }
 
     public static void expectRSetSummaries(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
-        int actualTotal = result.split("concurrent refinement").length - 1;
+        int actualTotal = result.split("concurrent refinement statistics").length - 1;
         int actualCumulative = result.split("Cumulative RS summary").length - 1;
 
         if (expectedCumulative != actualCumulative) {
--- a/test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java	Thu Oct 10 10:57:42 2019 -0400
@@ -32,12 +32,6 @@
  *      -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
  *      -Dtarget=1000
  *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=1000
- *      TestGCThreadGroups
  */
 
 /**
@@ -71,46 +65,22 @@
  *      TestGCThreadGroups
  *
  * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=1000
- *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
  *      -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
  *      -Dtarget=1000
  *      TestGCThreadGroups
  *
  * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=1000
- *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
  *      -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
  *      -Dtarget=100
  *      TestGCThreadGroups
  *
  * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=100
- *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
  *      -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
  *      -Dtarget=100
  *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=100
- *      TestGCThreadGroups
  */
 
 /**
@@ -130,18 +100,6 @@
  *      -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
  *      -Dtarget=1000
  *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=1000
- *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=1000
- *      TestGCThreadGroups
 */
 
 public class TestGCThreadGroups {
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCounts.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCounts.java	Thu Oct 10 10:57:42 2019 -0400
@@ -61,7 +61,7 @@
             output.shouldHaveExitValue(1);
         } else if (conc > par) {
             output.shouldContain("Shenandoah expects ConcGCThreads <= ParallelGCThreads");
-            output.shouldHaveExitValue(0);
+            output.shouldHaveExitValue(1);
         } else {
             output.shouldNotContain("Shenandoah expects ConcGCThreads <= ParallelGCThreads");
             output.shouldHaveExitValue(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCountsOverride.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test TestThreadCountsOverride
+ * @summary Test that Shenandoah GC thread counts are overridable
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @run driver TestThreadCountsOverride
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class TestThreadCountsOverride {
+    public static void main(String[] args) throws Exception {
+        {
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+UnlockExperimentalVMOptions",
+                "-XX:+UseShenandoahGC",
+                "-XX:ParallelGCThreads=1",
+                "-XX:+PrintFlagsFinal",
+                "-version");
+            OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+            output.shouldMatch("ParallelGCThreads(.*)= 1 ");
+            output.shouldHaveExitValue(0);
+        }
+
+        {
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+UnlockExperimentalVMOptions",
+                "-XX:+UseShenandoahGC",
+                "-XX:ConcGCThreads=1",
+                "-XX:+PrintFlagsFinal",
+                "-version");
+            OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+            output.shouldMatch("ConcGCThreads(.*)= 1 ");
+            output.shouldHaveExitValue(0);
+        }
+    }
+
+}
--- a/test/hotspot/jtreg/runtime/cds/appcds/LotsOfClasses.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/runtime/cds/appcds/LotsOfClasses.java	Thu Oct 10 10:57:42 2019 -0400
@@ -39,7 +39,7 @@
 
 public class LotsOfClasses {
 
-    public static void main(String[] args) throws Throwable {
+    public static void main(String[] args) throws Exception {
         ArrayList<String> list = new ArrayList<>();
         TestCommon.findAllClasses(list);
 
--- a/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/runtime/cds/appcds/TestCommon.java	Thu Oct 10 10:57:42 2019 -0400
@@ -611,7 +611,7 @@
 
     static Pattern pattern;
 
-    static void findAllClasses(ArrayList<String> list) throws Throwable {
+    static void findAllClasses(ArrayList<String> list) throws Exception {
         // Find all the classes in the jrt file system
         pattern = Pattern.compile("/modules/[a-z.]*[a-z]+/([^-]*)[.]class");
         FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/"));
@@ -619,7 +619,7 @@
         findAllClassesAtPath(base, list);
     }
 
-    private static void findAllClassesAtPath(Path p, ArrayList<String> list) throws Throwable {
+    private static void findAllClassesAtPath(Path p, ArrayList<String> list) throws Exception {
         try (DirectoryStream<Path> stream = Files.newDirectoryStream(p)) {
             for (Path entry: stream) {
                 Matcher matcher = pattern.matcher(entry.toString());
@@ -629,7 +629,7 @@
                 }
                 try {
                     findAllClassesAtPath(entry, list);
-                } catch (Throwable t) {}
+                } catch (Exception ex) {}
             }
         }
     }
--- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/DynamicLotsOfClasses.java	Thu Oct 10 10:57:42 2019 -0400
@@ -45,22 +45,16 @@
 
 public class DynamicLotsOfClasses extends DynamicArchiveTestBase {
 
-    public static void main(String[] args) throws Throwable {
+    public static void main(String[] args) throws Exception {
         runTest(DynamicLotsOfClasses::testDefaultBase);
     }
 
     static void testDefaultBase() throws Exception {
         String topArchiveName = getNewArchiveName("top");
-        try {
-            doTest(topArchiveName);
-         } catch (Throwable th) {
-             System.out.println(th.toString());
-             Exception ex = new Exception(th);
-             throw ex;
-         }
+        doTest(topArchiveName);
     }
 
-    private static void doTest(String topArchiveName) throws Throwable {
+    private static void doTest(String topArchiveName) throws Exception {
         ArrayList<String> list = new ArrayList<>();
         TestCommon.findAllClasses(list);
 
--- a/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamic.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/runtime/cds/appcds/dynamicArchive/HelloDynamic.java	Thu Oct 10 10:57:42 2019 -0400
@@ -52,6 +52,9 @@
         doTest(baseArchiveName, topArchiveName);
     }
 
+    private static final String JDWP_OPTION =
+        "-Xrunjdwp:transport=dt_socket,server=y,suspend=n";
+
     private static void doTest(String baseArchiveName, String topArchiveName) throws Exception {
         String appJar = ClassFileInstaller.getJarPath("hello.jar");
         String mainClass = "Hello";
@@ -71,5 +74,19 @@
                     output.shouldContain("Hello source: shared objects file")
                           .shouldHaveExitValue(0);
                 });
+
+        // Sanity test with JDWP options.
+        // Test with the default base archive should be sufficient.
+        if (baseArchiveName == null) {
+            run2(baseArchiveName, topArchiveName,
+                JDWP_OPTION,
+                "-Xlog:class+load",
+                "-Xlog:cds+dynamic=debug,cds=debug",
+                "-cp", appJar, mainClass)
+                .assertNormalExit(output -> {
+                    output.shouldContain("Hello source: shared objects file")
+                          .shouldHaveExitValue(0);
+                    });
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/GetOwnedMonitorInfoWithEATest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2019 SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8230677
+ * @summary Test JVMTI's GetOwnedMonitorInfo with scalar replaced objects and eliminated locks on stack (optimizations based on escape analysis).
+ * @comment Without RFE 8227745 escape analysis needs to be switched off to pass the test. For the implementation of RFE 8227745 it serves as a regression test.
+ * @requires (vm.compMode != "Xcomp" & vm.compiler2.enabled)
+ * @library /test/lib
+ * @compile GetOwnedMonitorInfoWithEATest.java
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
+ *                  GetOwnedMonitorInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:-EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking -XX:-UseOptoBiasInlining
+ *                  GetOwnedMonitorInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
+ *                  GetOwnedMonitorInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
+ *                  GetOwnedMonitorInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
+ *                  GetOwnedMonitorInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
+ *                  GetOwnedMonitorInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
+ *                  GetOwnedMonitorInfoWithEATest
+ */
+
+import jdk.test.lib.Asserts;
+
+public class GetOwnedMonitorInfoWithEATest {
+
+    public static final int COMPILE_THRESHOLD = 20000;
+
+    /**
+     * Native wrapper arround JVMTI's GetOwnedMonitorInfo().
+     * @param t The thread for which the owned monitors information should be retrieved.
+     * @param ownedMonitors Array filled in by the call with the objects associated
+     *        with the monitors owned by the given thread.
+     * @param depths Per owned monitor the depth of the frame were it was locked.
+     *        Filled in by the call
+     * @return Number of monitors owned by the given thread.
+     */
+    public static native int getOwnedMonitorInfo(Thread t, Object[] ownedMonitors);
+
+    public static void main(String[] args) throws Exception {
+        new GetOwnedMonitorInfoWithEATest().runTest();
+    }
+
+    public void runTest() throws Exception {
+        new TestCase_1().run();
+        new TestCase_2().run();
+    }
+
+    public static abstract class TestCaseBase implements Runnable {
+
+        public long checkSum;
+        public boolean doLoop;
+        public volatile long loopCount;
+        public volatile boolean targetIsInLoop;
+
+        public void run() {
+            try {
+                msgHL("Executing test case " + getClass().getName());
+                warmUp();
+                runTest();
+            } catch (Exception e) {
+                Asserts.fail("Unexpected Exception", e);
+            }
+        }
+
+        public void warmUp() {
+            int callCount = COMPILE_THRESHOLD + 1000;
+            doLoop = true;
+            while (callCount-- > 0) {
+                dontinline_testMethod();
+            }
+        }
+
+        public abstract void runTest() throws Exception;
+        public abstract void dontinline_testMethod();
+
+        public long dontinline_endlessLoop() {
+            long cs = checkSum;
+            while (doLoop && loopCount-- > 0) {
+                targetIsInLoop = true;
+                checkSum += checkSum % ++cs;
+            }
+            loopCount = 3;
+            targetIsInLoop = false;
+            return checkSum;
+        }
+
+        public void waitUntilTargetThreadHasEnteredEndlessLoop() throws Exception {
+            while(!targetIsInLoop) {
+                msg("Target has not yet entered the loop. Sleep 200ms.");
+                try { Thread.sleep(200); } catch (InterruptedException e) { /*ignore */ }
+            }
+            msg("Target has entered the loop.");
+        }
+
+        public void terminateEndlessLoop() throws Exception {
+            msg("Terminate endless loop");
+            do {
+                doLoop = false;
+            } while(targetIsInLoop);
+        }
+
+        public void msg(String m) {
+            System.out.println();
+            System.out.println("### " + m);
+            System.out.println();
+        }
+
+        public void msgHL(String m) {
+            System.out.println();
+            System.out.println("#####################################################");
+            System.out.println("### " + m);
+            System.out.println("###");
+            System.out.println();
+        }
+    }
+
+    /**
+     * Starts target thread T and then queries monitor information for T using JVMTI's GetOwnedMonitorInfo().
+     * With escape analysis enabled the jit compiled method {@link #dontinline_testMethod()} has
+     * scalar replaced objects with eliminated (nested) locking in scope when the monitor
+     * information is retrieved. Effectively the objects escape through the JVMTI call. This works
+     * only with RFE 8227745. Without it escape analysis needs to be disabled.
+     */
+    public static class TestCase_1 extends TestCaseBase {
+
+        public void runTest() throws Exception {
+            loopCount = 1L << 62; // endless loop
+            Thread t1 = new Thread(() -> dontinline_testMethod(), "Target Thread");
+            t1.start();
+            try {
+                waitUntilTargetThreadHasEnteredEndlessLoop();
+                int expectedMonitorCount = 1;
+                int resultSize = expectedMonitorCount + 3;
+                Object[] ownedMonitors = new Object[resultSize];
+                msg("Get monitor info");
+                int monitorCount = getOwnedMonitorInfo(t1, ownedMonitors);
+                terminateEndlessLoop();
+                t1.join();
+                Asserts.assertGreaterThanOrEqual(monitorCount, 0, "getOwnedMonitorsFor() call failed");
+                msg("Monitor info:");
+                for (int i = 0; i < monitorCount; i++) {
+                    System.out.println(i + ": cls=" + (ownedMonitors[i] != null ? ownedMonitors[i].getClass() : null));
+                }
+                Asserts.assertEQ(monitorCount, expectedMonitorCount, "unexpected monitor count returned by getOwnedMonitorsFor()");
+                Asserts.assertNotNull(ownedMonitors[0]);
+                Asserts.assertSame(ownedMonitors[0].getClass(), LockCls.class);
+            } finally {
+                terminateEndlessLoop();
+                t1.join();
+            }
+        }
+
+        public void dontinline_testMethod() {
+            LockCls l1 = new LockCls();        // to be scalar replaced
+            synchronized (l1) {
+                inlinedTestMethodWithNestedLocking(l1);
+            }
+        }
+
+        public void inlinedTestMethodWithNestedLocking(LockCls l1) {
+            synchronized (l1) {              // nested
+                dontinline_endlessLoop();
+            }
+        }
+    }
+
+    /**
+     * Similar to {@link TestCase_1}. Additionally the target thread T has got eliminated locking
+     * for a synchronized method of a different type {@linkplain LockCls2}.
+     */
+    public static class TestCase_2 extends TestCaseBase {
+
+        public void runTest() throws Exception {
+            loopCount = 1L << 62; // endless loop
+            Thread t1 = new Thread(() -> dontinline_testMethod(), "Target Thread");
+            t1.start();
+            try {
+                waitUntilTargetThreadHasEnteredEndlessLoop();
+                int expectedMonitorCount = 2;
+                int resultSize = expectedMonitorCount + 3;
+                Object[] ownedMonitors = new Object[resultSize];
+                msg("Get monitor info");
+                int monitorCount = getOwnedMonitorInfo(t1, ownedMonitors);
+                terminateEndlessLoop();
+                t1.join();
+                Asserts.assertGreaterThanOrEqual(monitorCount, 0, "getOwnedMonitorsFor() call failed");
+                msg("Monitor info:");
+                for (int i = 0; i < monitorCount; i++) {
+                    System.out.println(i + ": cls=" + (ownedMonitors[i] != null ? ownedMonitors[i].getClass() : null));
+                }
+                Asserts.assertEQ(monitorCount, expectedMonitorCount, "unexpected monitor count returned by getOwnedMonitorsFor()");
+                Asserts.assertNotNull(ownedMonitors[0]);
+                Asserts.assertSame(ownedMonitors[0].getClass(), LockCls2.class);
+
+                Asserts.assertNotNull(ownedMonitors[1]);
+                Asserts.assertSame(ownedMonitors[1].getClass(), LockCls.class);
+            } finally {
+                terminateEndlessLoop();
+                t1.join();
+            }
+        }
+
+        public void dontinline_testMethod() {
+            LockCls l1 = new LockCls();
+            synchronized (l1) {
+                inlinedTestMethodWithNestedLocking(l1);
+            }
+        }
+
+        public void inlinedTestMethodWithNestedLocking(LockCls l1) {
+            synchronized (l1) {
+                dontinline_testMethod2();
+            }
+        }
+
+        public void dontinline_testMethod2() {
+            // Call synchronized method. Receiver of the call will be scalar replaced,
+            // and locking will be eliminated. Here we use a different type.
+            new LockCls2().inline_synchronized_testMethod(this);
+        }
+    }
+
+    public static class LockCls {
+    }
+
+    public static class LockCls2 {
+        public synchronized void inline_synchronized_testMethod(TestCaseBase testCase) {
+            testCase.dontinline_endlessLoop();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorInfo/libGetOwnedMonitorInfoWithEATest.c	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2019 SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "jvmti.h"
+#include "jni.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef JNI_ENV_ARG
+
+#ifdef __cplusplus
+#define JNI_ENV_ARG(x, y) y
+#define JNI_ENV_PTR(x) x
+#else
+#define JNI_ENV_ARG(x,y) x, y
+#define JNI_ENV_PTR(x) (*x)
+#endif
+
+#endif
+
+#define FAILED -1
+
+static jvmtiEnv *jvmti;
+
+static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved);
+
+static void ShowErrorMessage(jvmtiEnv *jvmti, jvmtiError errCode, const char *message) {
+    char *errMsg;
+    jvmtiError result;
+
+    result = (*jvmti)->GetErrorName(jvmti, errCode, &errMsg);
+    if (result == JVMTI_ERROR_NONE) {
+        fprintf(stderr, "%s: %s (%d)\n", message, errMsg, errCode);
+        (*jvmti)->Deallocate(jvmti, (unsigned char *)errMsg);
+    } else {
+        fprintf(stderr, "%s (%d)\n", message, errCode);
+    }
+}
+
+JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
+    return Agent_Initialize(jvm, options, reserved);
+}
+
+JNIEXPORT jint JNICALL
+Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
+    return Agent_Initialize(jvm, options, reserved);
+}
+
+JNIEXPORT jint JNICALL
+JNI_OnLoad(JavaVM *jvm, void *reserved) {
+    jint res;
+    JNIEnv *env;
+
+    res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &env),
+                                   JNI_VERSION_9);
+    if (res != JNI_OK || env == NULL) {
+        fprintf(stderr, "Error: GetEnv call failed(%d)!\n", res);
+        return JNI_ERR;
+    }
+
+    return JNI_VERSION_9;
+}
+
+static
+jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
+    jint res;
+    jvmtiError err;
+    jvmtiCapabilities caps;
+
+    printf("Agent_OnLoad started\n");
+
+    memset(&caps, 0, sizeof(caps));
+
+    res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),
+                                   JVMTI_VERSION_9);
+    if (res != JNI_OK || jvmti == NULL) {
+        fprintf(stderr, "Error: wrong result of a valid call to GetEnv!\n");
+        return JNI_ERR;
+    }
+
+    caps.can_get_owned_monitor_info = 1;
+
+    err = (*jvmti)->AddCapabilities(jvmti, &caps);
+    if (err != JVMTI_ERROR_NONE) {
+        ShowErrorMessage(jvmti, err,
+                         "Agent_OnLoad: error in JVMTI AddCapabilities");
+        return JNI_ERR;
+    }
+
+    err = (*jvmti)->GetCapabilities(jvmti, &caps);
+    if (err != JVMTI_ERROR_NONE) {
+        ShowErrorMessage(jvmti, err,
+                         "Agent_OnLoad: error in JVMTI GetCapabilities");
+        return JNI_ERR;
+    }
+
+    if (!caps.can_get_owned_monitor_info) {
+        fprintf(stderr, "Warning: GetOwnedMonitorInfo is not implemented\n");
+        return JNI_ERR;
+    }
+
+    printf("Agent_OnLoad finished\n");
+    return JNI_OK;
+}
+
+JNIEXPORT jint JNICALL
+Java_GetOwnedMonitorInfoWithEATest_getOwnedMonitorInfo(JNIEnv *env, jclass cls, jobject targetThread, jobjectArray resOwnedMonitors) {
+    jvmtiError err;
+    jvmtiThreadInfo threadInfo;
+    jint monitorCount;
+    jobject* monitors;
+    jint idx;
+
+    err = (*jvmti)->GetThreadInfo(jvmti, targetThread, &threadInfo);
+    if (err != JVMTI_ERROR_NONE) {
+        ShowErrorMessage(jvmti, err,
+                "getOwnedMonitorsFor: error in JVMTI GetThreadInfo");
+        return FAILED;
+    }
+
+    err = (*jvmti)->GetOwnedMonitorInfo(jvmti, targetThread, &monitorCount, &monitors);
+    if (err != JVMTI_ERROR_NONE) {
+        ShowErrorMessage(jvmti, err,
+                "getOwnedMonitorsFor: error in JVMTI GetOwnedMonitorInfo");
+        return FAILED;
+    }
+
+    printf("getOwnedMonitorsFor: %s owns %d monitor(s)\n", threadInfo.name, monitorCount);
+
+    for (idx = 0; idx < monitorCount; idx++) {
+      (*env)->SetObjectArrayElement(env, resOwnedMonitors, idx, monitors[idx]);
+    }
+
+    (*jvmti)->Deallocate(jvmti, (unsigned char *) monitors);
+    (*jvmti)->Deallocate(jvmti, (unsigned char *) threadInfo.name);
+    return monitorCount;
+}
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorStackDepthInfo/GetOwnedMonitorStackDepthInfoWithEATest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2019 SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8230677
+ * @summary Test JVMTI's GetOwnedMonitorStackDepthInfo with scalar replaced objects and eliminated locks on stack (optimizations based on escape analysis).
+ * @comment Without RFE 8227745 escape analysis needs to be switched off to pass the test. For the implementation of RFE 8227745 it serves as a regression test.
+ * @requires (vm.compMode != "Xcomp" & vm.compiler2.enabled)
+ * @library /test/lib
+ * @compile GetOwnedMonitorStackDepthInfoWithEATest.java
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorStackDepthInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
+ *                  GetOwnedMonitorStackDepthInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorStackDepthInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:-EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking -XX:-UseOptoBiasInlining
+ *                  GetOwnedMonitorStackDepthInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorStackDepthInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
+ *                  GetOwnedMonitorStackDepthInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorStackDepthInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:+UseBiasedLocking
+ *                  GetOwnedMonitorStackDepthInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorStackDepthInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:+DoEscapeAnalysis -XX:+EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
+ *                  GetOwnedMonitorStackDepthInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorStackDepthInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:+DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
+ *                  GetOwnedMonitorStackDepthInfoWithEATest
+ * @run main/othervm/native
+ *                  -agentlib:GetOwnedMonitorStackDepthInfoWithEATest
+ *                  -XX:+UnlockDiagnosticVMOptions
+ *                  -Xms128m -Xmx128m
+ *                  -XX:CompileCommand=dontinline,*::dontinline_*
+ *                  -XX:+PrintCompilation
+ *                  -XX:+PrintInlining
+ *                  -XX:-TieredCompilation
+ *                  -Xbatch
+ *                  -XX:CICompilerCount=1
+ *                  -XX:-DoEscapeAnalysis -XX:-EliminateAllocations -XX:+EliminateLocks -XX:+EliminateNestedLocks -XX:-UseBiasedLocking
+ *                  GetOwnedMonitorStackDepthInfoWithEATest
+ */
+
+import jdk.test.lib.Asserts;
+
+public class GetOwnedMonitorStackDepthInfoWithEATest {
+
+    public static final int COMPILE_THRESHOLD = 20000;
+
+    /**
+     * Native wrapper arround JVMTI's GetOwnedMonitorStackDepthInfo().
+     * @param t The thread for which the owned monitors information should be retrieved.
+     * @param ownedMonitors Array filled in by the call with the objects associated
+     *        with the monitors owned by the given thread.
+     * @param depths Per owned monitor the depth of the frame were it was locked.
+     *        Filled in by the call
+     * @return Number of monitors owned by the given thread.
+     */
+    public static native int getOwnedMonitorStackDepthInfo(Thread t, Object[] ownedMonitors, int[] depths);
+
+    public static void main(String[] args) throws Exception {
+        new GetOwnedMonitorStackDepthInfoWithEATest().runTest();
+    }
+
+    public void runTest() throws Exception {
+        new TestCase_1().run();
+        new TestCase_2().run();
+    }
+
+    public static abstract class TestCaseBase implements Runnable {
+
+        public long checkSum;
+        public boolean doLoop;
+        public volatile long loopCount;
+        public volatile boolean targetIsInLoop;
+
+        public void run() {
+            try {
+                msgHL("Executing test case " + getClass().getName());
+                warmUp();
+                runTest();
+            } catch (Exception e) {
+                Asserts.fail("Unexpected Exception", e);
+            }
+        }
+
+        public void warmUp() {
+            int callCount = COMPILE_THRESHOLD + 1000;
+            doLoop = true;
+            while (callCount-- > 0) {
+                dontinline_testMethod();
+            }
+        }
+
+        public abstract void runTest() throws Exception;
+        public abstract void dontinline_testMethod();
+
+        public long dontinline_endlessLoop() {
+            long cs = checkSum;
+            while (doLoop && loopCount-- > 0) {
+                targetIsInLoop = true;
+                checkSum += checkSum % ++cs;
+            }
+            loopCount = 3;
+            targetIsInLoop = false;
+            return checkSum;
+        }
+
+        public void waitUntilTargetThreadHasEnteredEndlessLoop() throws Exception {
+            while(!targetIsInLoop) {
+                msg("Target has not yet entered the loop. Sleep 200ms.");
+                try { Thread.sleep(200); } catch (InterruptedException e) { /*ignore */ }
+            }
+            msg("Target has entered the loop.");
+        }
+
+        public void terminateEndlessLoop() throws Exception {
+            msg("Terminate endless loop");
+            do {
+                doLoop = false;
+            } while(targetIsInLoop);
+        }
+
+        public void msg(String m) {
+            System.out.println();
+            System.out.println("### " + m);
+            System.out.println();
+        }
+
+        public void msgHL(String m) {
+            System.out.println();
+            System.out.println("#####################################################");
+            System.out.println("### " + m);
+            System.out.println("###");
+            System.out.println();
+        }
+    }
+
+    /**
+     * Starts target thread T and then queries monitor information for T using JVMTI's GetOwnedMonitorStackDepthInfo().
+     * With escape analysis enabled the jit compiled method {@link #dontinline_testMethod()} has
+     * scalar replaced objects with eliminated (nested) locking in scope when the monitor
+     * information is retrieved. Effectively the objects escape through the JVMTI call. This works
+     * only with RFE 8227745. Without it escape analysis needs to be disabled.
+     */
+    public static class TestCase_1 extends TestCaseBase {
+
+        public void runTest() throws Exception {
+            loopCount = 1L << 62; // endless loop
+            Thread t1 = new Thread(() -> dontinline_testMethod(), "Target Thread");
+            try {
+                t1.start();
+                waitUntilTargetThreadHasEnteredEndlessLoop();
+                int expectedMonitorCount = 1;
+                int resultSize = expectedMonitorCount + 3;
+                Object[] ownedMonitors = new Object[resultSize];
+                int[]    depths = new int[resultSize];
+                msg("Get monitor info");
+                int monitorCount = getOwnedMonitorStackDepthInfo(t1, ownedMonitors, depths);
+                Asserts.assertGreaterThanOrEqual(monitorCount, 0, "getOwnedMonitorsFor() call failed");
+                msg("Monitor info:");
+                for (int i = 0; i < monitorCount; i++) {
+                    System.out.println(i + ": cls=" + (ownedMonitors[i] != null ? ownedMonitors[i].getClass() : null) + " depth=" + depths[i]);
+                }
+                Asserts.assertEQ(monitorCount, expectedMonitorCount, "unexpected monitor count returned by getOwnedMonitorsFor()");
+                Asserts.assertNotNull(ownedMonitors[0]);
+                Asserts.assertSame(ownedMonitors[0].getClass(), LockCls.class);
+                Asserts.assertEQ(depths[0], 1, "unexpected depth for owned monitor at index 0");
+            } finally {
+                terminateEndlessLoop();
+                t1.join();
+            }
+        }
+
+        public void dontinline_testMethod() {
+            LockCls l1 = new LockCls();        // to be scalar replaced
+            synchronized (l1) {
+                inlinedTestMethodWithNestedLocking(l1);
+            }
+        }
+
+        public void inlinedTestMethodWithNestedLocking(LockCls l1) {
+            synchronized (l1) {              // nested
+                dontinline_endlessLoop();
+            }
+        }
+    }
+
+    /**
+     * Similar to {@link TestCase_1}. Additionally the target thread T has got eliminated locking
+     * for a synchronized method of a different type {@linkplain LockCls2}.
+     */
+    public static class TestCase_2 extends TestCaseBase {
+
+        public void runTest() throws Exception {
+            loopCount = 1L << 62; // endless loop
+            Thread t1 = new Thread(() -> dontinline_testMethod(), "Target Thread");
+            t1.start();
+            try {
+                waitUntilTargetThreadHasEnteredEndlessLoop();
+                int expectedMonitorCount = 2;
+                int resultSize = expectedMonitorCount + 3;
+                Object[] ownedMonitors = new Object[resultSize];
+                int[]    depths = new int[resultSize];
+                msg("Get monitor info");
+                int monitorCount = getOwnedMonitorStackDepthInfo(t1, ownedMonitors, depths);
+                terminateEndlessLoop();
+                t1.join();
+                Asserts.assertGreaterThanOrEqual(monitorCount, 0, "getOwnedMonitorsFor() call failed");
+                msg("Monitor info:");
+                for (int i = 0; i < monitorCount; i++) {
+                    System.out.println(i + ": cls=" + (ownedMonitors[i] != null ? ownedMonitors[i].getClass() : null) + " depth=" + depths[i]);
+                }
+                Asserts.assertEQ(monitorCount, expectedMonitorCount, "unexpected monitor count returned by getOwnedMonitorsFor()");
+                Asserts.assertNotNull(ownedMonitors[0]);
+                Asserts.assertSame(ownedMonitors[0].getClass(), LockCls2.class);
+                Asserts.assertEQ(depths[0], 1, "unexpected depth for owned monitor at index 0");
+
+                Asserts.assertNotNull(ownedMonitors[1]);
+                Asserts.assertSame(ownedMonitors[1].getClass(), LockCls.class);
+                Asserts.assertEQ(depths[1], 3, "unexpected depth for owned monitor at index 1");
+            } finally {
+                terminateEndlessLoop();
+                t1.join();
+            }
+        }
+
+        public void dontinline_testMethod() {
+            LockCls l1 = new LockCls();
+            synchronized (l1) {
+                inlinedTestMethodWithNestedLocking(l1);
+            }
+        }
+
+        public void inlinedTestMethodWithNestedLocking(LockCls l1) {
+            synchronized (l1) {
+                dontinline_testMethod2();
+            }
+        }
+
+        public void dontinline_testMethod2() {
+            // Call synchronized method. Receiver of the call will be scalar replaced,
+            // and locking will be eliminated. Here we use a different type.
+            new LockCls2().inline_synchronized_testMethod(this);
+        }
+    }
+
+    public static class LockCls {
+    }
+
+    public static class LockCls2 {
+        public synchronized void inline_synchronized_testMethod(TestCaseBase testCase) {
+            testCase.dontinline_endlessLoop();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/GetOwnedMonitorStackDepthInfo/libGetOwnedMonitorStackDepthInfoWithEATest.c	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2019 SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "jvmti.h"
+#include "jni.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef JNI_ENV_ARG
+
+#ifdef __cplusplus
+#define JNI_ENV_ARG(x, y) y
+#define JNI_ENV_PTR(x) x
+#else
+#define JNI_ENV_ARG(x,y) x, y
+#define JNI_ENV_PTR(x) (*x)
+#endif
+
+#endif
+
+#define FAILED -1
+
+static jvmtiEnv *jvmti;
+
+static jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved);
+
+static void ShowErrorMessage(jvmtiEnv *jvmti, jvmtiError errCode, const char *message) {
+    char *errMsg;
+    jvmtiError result;
+
+    result = (*jvmti)->GetErrorName(jvmti, errCode, &errMsg);
+    if (result == JVMTI_ERROR_NONE) {
+        fprintf(stderr, "%s: %s (%d)\n", message, errMsg, errCode);
+        (*jvmti)->Deallocate(jvmti, (unsigned char *)errMsg);
+    } else {
+        fprintf(stderr, "%s (%d)\n", message, errCode);
+    }
+}
+
+JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
+    return Agent_Initialize(jvm, options, reserved);
+}
+
+JNIEXPORT jint JNICALL
+Agent_OnAttach(JavaVM *jvm, char *options, void *reserved) {
+    return Agent_Initialize(jvm, options, reserved);
+}
+
+JNIEXPORT jint JNICALL
+JNI_OnLoad(JavaVM *jvm, void *reserved) {
+    jint res;
+    JNIEnv *env;
+
+    res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &env),
+                                   JNI_VERSION_9);
+    if (res != JNI_OK || env == NULL) {
+        fprintf(stderr, "Error: GetEnv call failed(%d)!\n", res);
+        return JNI_ERR;
+    }
+
+    return JNI_VERSION_9;
+}
+
+static
+jint Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
+    jint res;
+    jvmtiError err;
+    jvmtiCapabilities caps;
+
+    printf("Agent_OnLoad started\n");
+
+    memset(&caps, 0, sizeof(caps));
+
+    res = JNI_ENV_PTR(jvm)->GetEnv(JNI_ENV_ARG(jvm, (void **) &jvmti),
+                                   JVMTI_VERSION_9);
+    if (res != JNI_OK || jvmti == NULL) {
+        fprintf(stderr, "Error: wrong result of a valid call to GetEnv!\n");
+        return JNI_ERR;
+    }
+
+    caps.can_get_owned_monitor_stack_depth_info = 1;
+
+    err = (*jvmti)->AddCapabilities(jvmti, &caps);
+    if (err != JVMTI_ERROR_NONE) {
+        ShowErrorMessage(jvmti, err,
+                         "Agent_OnLoad: error in JVMTI AddCapabilities");
+        return JNI_ERR;
+    }
+
+    err = (*jvmti)->GetCapabilities(jvmti, &caps);
+    if (err != JVMTI_ERROR_NONE) {
+        ShowErrorMessage(jvmti, err,
+                         "Agent_OnLoad: error in JVMTI GetCapabilities");
+        return JNI_ERR;
+    }
+
+    if (!caps.can_get_owned_monitor_stack_depth_info) {
+        fprintf(stderr, "Warning: GetOwnedMonitorStackDepthInfo is not implemented\n");
+        return JNI_ERR;
+    }
+
+    printf("Agent_OnLoad finished\n");
+    return JNI_OK;
+}
+
+JNIEXPORT jint JNICALL
+Java_GetOwnedMonitorStackDepthInfoWithEATest_getOwnedMonitorStackDepthInfo(JNIEnv *env, jclass cls, jobject targetThread, jobjectArray ownedMonitors, jintArray depths) {
+    jvmtiError err;
+    jvmtiThreadInfo threadInfo;
+    jint monitorCount;
+    jvmtiMonitorStackDepthInfo* stackDepthInfo;
+    jint* depthsPtr;
+    jint idx = 0;
+
+    err = (*jvmti)->GetThreadInfo(jvmti, targetThread, &threadInfo);
+    if (err != JVMTI_ERROR_NONE) {
+        ShowErrorMessage(jvmti, err,
+                "getOwnedMonitorsFor: error in JVMTI GetThreadInfo");
+        return FAILED;
+    }
+
+    err = (*jvmti)->GetOwnedMonitorStackDepthInfo(jvmti, targetThread, &monitorCount, &stackDepthInfo);
+    if (err != JVMTI_ERROR_NONE) {
+        ShowErrorMessage(jvmti, err,
+                "getOwnedMonitorsFor: error in JVMTI GetOwnedMonitorStackDepthInfo");
+        return FAILED;
+    }
+
+    printf("getOwnedMonitorsFor: %s owns %d monitor(s)\n", threadInfo.name, monitorCount);
+
+    depthsPtr = (*env)->GetIntArrayElements(env, depths, NULL);
+    for (idx = 0; idx < monitorCount; idx++) {
+      (*env)->SetObjectArrayElement(env, ownedMonitors, idx, stackDepthInfo[idx].monitor);
+      depthsPtr[idx] = stackDepthInfo[idx].stack_depth;
+    }
+    (*env)->ReleaseIntArrayElements(env, depths, depthsPtr, 0);
+
+    (*jvmti)->Deallocate(jvmti, (unsigned char *) stackDepthInfo);
+    (*jvmti)->Deallocate(jvmti, (unsigned char *) threadInfo.name);
+    return monitorCount;
+}
+
+#ifdef __cplusplus
+}
+#endif
--- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineDeleteJmethod.java	Wed Oct 09 10:58:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * 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 8181171
- * @summary Test deleting static method pointing to by a jmethod
- * @library /test/lib
- * @modules java.base/jdk.internal.misc
- * @modules java.compiler
- *          java.instrument
- *          jdk.jartool/sun.tools.jar
- * @run main RedefineClassHelper
- * @run main/native/othervm -javaagent:redefineagent.jar -XX:+AllowRedefinitionToAddDeleteMethods -Xlog:redefine+class*=trace RedefineDeleteJmethod
- */
-
-class B {
-    private static int deleteMe() { System.out.println("deleteMe called"); return 5; }
-    public static int callDeleteMe() { return deleteMe(); }
-}
-
-public class RedefineDeleteJmethod {
-
-    public static String newB =
-        "class B {" +
-            "public static int callDeleteMe() { return 6; }" +
-        "}";
-
-    public static String newerB =
-        "class B {" +
-            "private static int deleteMe() { System.out.println(\"deleteMe (2) called\"); return 7; }" +
-            "public static int callDeleteMe() { return deleteMe(); }" +
-        "}";
-
-
-    static {
-        System.loadLibrary("RedefineDeleteJmethod");
-    }
-
-    static native int jniCallDeleteMe();
-
-    static void test(int expected, boolean nsme_expected) throws Exception {
-        // Call through static method
-        int res = B.callDeleteMe();
-        System.out.println("Result = " + res);
-        if (res != expected) {
-            throw new Error("returned " + res + " expected " + expected);
-        }
-
-        // Call through jmethodID, saved from first call.
-        try {
-            res = jniCallDeleteMe();
-            if (nsme_expected) {
-                throw new RuntimeException("Failed, NoSuchMethodError expected");
-            }
-            if (res != expected) {
-                throw new Error("returned " + res + " expected " + expected);
-            }
-        } catch (NoSuchMethodError ex) {
-            if (!nsme_expected) {
-                throw new RuntimeException("Failed, NoSuchMethodError not expected");
-            }
-            System.out.println("Passed, NoSuchMethodError expected");
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        test(5, false);
-        RedefineClassHelper.redefineClass(B.class, newB);
-        test(6, true);
-        RedefineClassHelper.redefineClass(B.class, newerB);
-        test(7, true);
-    }
-}
--- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/libRedefineDeleteJmethod.c	Wed Oct 09 10:58:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * 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 <jni.h>
-
-jmethodID mid;
-jclass cls;
-static int count = 0;
-
-JNIEXPORT jint JNICALL
-Java_RedefineDeleteJmethod_jniCallDeleteMe(JNIEnv* env, jobject obj) {
-
-    if (count == 0) {
-      count++;
-      cls = (*env)->FindClass(env, "B");
-      if (NULL == cls) {
-          (*env)->FatalError(env, "could not find class");
-      }
-
-      mid = (*env)->GetStaticMethodID(env, cls, "deleteMe", "()I");
-      if (NULL == mid) {
-          (*env)->FatalError(env, "could not find method");
-      }
-    }
-
-    return (*env)->CallStaticIntMethod(env, cls, mid);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithCurrentThread/SuspendWithCurrentThread.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,222 @@
+/*
+ * 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 8231595
+ * @summary [TEST] develop a test case for SuspendThreadList including current thread
+ * @library /test/lib
+ * @compile SuspendWithCurrentThread.java
+ * @run main/othervm/native -agentlib:SuspendWithCurrentThread SuspendWithCurrentThread SuspenderIndex=first
+ * @run main/othervm/native -agentlib:SuspendWithCurrentThread SuspendWithCurrentThread SuspenderIndex=last
+ */
+
+import java.io.PrintStream;
+
+public class SuspendWithCurrentThread {
+    private static final String AGENT_LIB = "SuspendWithCurrentThread";
+    private static final String SUSPENDER_OPT = "SuspenderIndex=";
+    private static final int THREADS_COUNT = 10;
+
+    private static void log(String msg) { System.out.println(msg); }
+
+    private static native void    registerTestedThreads(Thread[] threads);
+    private static native boolean checkTestedThreadsSuspended();
+    private static native void    resumeTestedThreads();
+    private static native void    releaseTestedThreadsInfo();
+
+    // The suspender thread index defines the thread which has to suspend
+    // the tested threads including itself with the JVMTI SuspendThreadList
+    private static int suspenderIndex;
+
+    public static void main(String args[]) throws Exception {
+        try {
+            System.loadLibrary(AGENT_LIB);
+            log("Loaded library: " + AGENT_LIB);
+        } catch (UnsatisfiedLinkError ule) {
+            log("Failed to load library: " + AGENT_LIB);
+            log("java.library.path: " + System.getProperty("java.library.path"));
+            throw ule;
+        }
+        if (args.length != 1) {
+            throw new RuntimeException("Main: wrong arguments count: " + args.length + ", expected: 1");
+        }
+        String arg = args[0];
+        if (arg.equals(SUSPENDER_OPT + "first")) {
+            suspenderIndex = 0;
+        } else if (arg.equals(SUSPENDER_OPT + "last")) {
+            suspenderIndex = THREADS_COUNT - 1;
+        } else {
+            throw new RuntimeException("Main: wrong argument: " + arg + ", expected: SuspenderIndex={first|last}");
+        }
+        log("Main: suspenderIndex: " + suspenderIndex);
+
+        SuspendWithCurrentThread test = new SuspendWithCurrentThread();
+        test.run();
+    }
+
+    private ThreadToSuspend[] startTestedThreads(int threadsCount) throws RuntimeException  {
+        ThreadToSuspend[]threads = new ThreadToSuspend[threadsCount];
+
+        // create tested threads
+        for (int i = 0; i < threads.length; i++) {
+            threads[i] = new ThreadToSuspend("ThreadToSuspend#" + i,
+                                             i == suspenderIndex // isSuspender
+                                            );
+        }
+        log("Main: starting tested threads");
+        for (int i = 0; i < threads.length; i++) {
+            threads[i].start();
+            if (!threads[i].checkReady()) {
+                throw new RuntimeException("Main: unable to prepare tested thread: " + threads[i]);
+            }
+        }
+        log("Main: tested threads started");
+
+        registerTestedThreads(threads);
+        return threads;
+    }
+
+    private boolean checkSuspendedStatus() throws RuntimeException  {
+        log("Main: checking all tested threads have been suspended");
+        return checkTestedThreadsSuspended();
+    }
+
+    /* The test does the following steps:
+     *  - main thread starts several (THREADS_COUNT) ThreadToSuspend tested threads
+     *  - main thread waits for threads to be ready with the thread.checkReady()
+     *  - main thread registers tested threads within the native agent library
+     *    with the native method registerTestedThreads()
+     *  - main thread triggers the suspender tested thread with the
+     *    ThreadToSuspend.setAllThreadsReady() to suspend tested threads
+     *  - suspender thread suspends tested threads including itself with the native
+     *    method suspendTestedThreads() (uses the JVMTI SuspendThreadList function)
+     *  - main thread checks tested threads suspended status with the native method
+     *    checkSuspendedStatus(); the tested threads are expected to have suspended status
+     *  - main thread resumes tested threads with the native method resumeTestedThreads()
+     *  - main thread releases tested threads with the native method releaseTestedThreads()
+     *  - main thread triggers the tested threads to finish with the thread.letFinish()
+     */
+    private void run() throws Exception {
+        ThreadToSuspend[] threads = null; // tested threads
+
+        log("Main: started");
+        try {
+            threads = startTestedThreads(THREADS_COUNT);
+
+            log("Main: trigger " + threads[suspenderIndex].getName() +
+                " to suspend all tested threads including itself");
+            ThreadToSuspend.setAllThreadsReady();
+
+            if (!checkSuspendedStatus()) {
+                throw new RuntimeException("Main: FAILED status returned from checkTestedThreadsSuspended");
+            }
+
+            log("Main: resuming all tested threads");
+            resumeTestedThreads();
+        } finally {
+            // let threads to finish
+            for (int i = 0; i < threads.length; i++) {
+                threads[i].letFinish();
+            }
+            log("Main: tested threads finished");
+        }
+
+        // wait for threads to finish
+        log("Main: joining tested threads");
+        try {
+            for (int i = 0; i < threads.length; i++) {
+                threads[i].join();
+            }
+            log("Main: tested thread joined");
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+        log("Main: releasing tested threads native info");
+        releaseTestedThreadsInfo();
+
+        log("Main: finished");
+    }
+}
+
+/* =================================================================== */
+
+// tested threads
+class ThreadToSuspend extends Thread {
+    private static void log(String msg) { System.out.println(msg); }
+
+    private static native void init();
+    private static native void suspendTestedThreads();
+    private static volatile boolean allThreadsReady = false;
+
+    public static void setAllThreadsReady() {
+        allThreadsReady = true;
+    }
+
+    private volatile boolean threadReady = false;
+    private volatile boolean shouldFinish = false;
+    private boolean isSuspender = false;
+
+    // make thread with specific name
+    public ThreadToSuspend(String name, boolean isSuspender) {
+        super(name);
+        this.isSuspender = isSuspender;
+    }
+
+    // run thread continuously
+    public void run() {
+        boolean needSuspend = true;
+
+        if (isSuspender) {
+            init();
+        }
+        threadReady = true;
+
+        // run in a loop
+        while (!shouldFinish) {
+            if (isSuspender && needSuspend && allThreadsReady) {
+                log(getName() + ": before suspending all tested threads including myself");
+                needSuspend = false;
+                suspendTestedThreads();
+                log(getName() + ": after suspending all tested threads including myself");
+            }
+        }
+    }
+
+    // check if thread is ready
+    public boolean checkReady() {
+        try {
+            while (!threadReady) {
+                sleep(1);
+            }
+        } catch (InterruptedException e) {
+            throw new RuntimeException("checkReady: sleep was interrupted\n\t" + e);
+        }
+        return threadReady;
+    }
+
+    // let thread to finish
+    public void letFinish() {
+        shouldFinish = true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/jvmti/SuspendWithCurrentThread/libSuspendWithCurrentThread.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,209 @@
+/*
+ * 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 <string.h>
+#include "jvmti.h"
+
+extern "C" {
+
+static jvmtiEnv* jvmti = NULL;
+static jthread* threads = NULL;
+static jsize threads_count = 0;
+static jrawMonitorID agent_monitor = NULL;
+
+#define LOG(...) \
+  do { \
+    printf(__VA_ARGS__); \
+    printf("\n"); \
+    fflush(stdout); \
+  } while (0)
+
+static void
+check_jvmti_status(JNIEnv* jni, jvmtiError err, const char* msg) {
+  if (err != JVMTI_ERROR_NONE) {
+    LOG("check_jvmti_status: JVMTI function returned error: %d", err);
+    jni->FatalError(msg);
+  }
+}
+
+static void
+agent_lock(JNIEnv* jni) {
+  jvmtiError err = jvmti->RawMonitorEnter(agent_monitor);
+  check_jvmti_status(jni, err, "monitor_enter: error in JVMTI RawMonitorEnter");
+}
+
+static void
+agent_unlock(JNIEnv* jni) {
+  jvmtiError err = jvmti->RawMonitorExit(agent_monitor);
+  check_jvmti_status(jni, err, "monitor_exit: error in JVMTI RawMonitorExit");
+}
+
+JNIEXPORT void JNICALL
+Java_SuspendWithCurrentThread_registerTestedThreads(JNIEnv *jni, jclass cls, jobjectArray threadsArr) {
+  LOG("\nregisterTestedThreads: started");
+  threads_count = jni->GetArrayLength(threadsArr);
+
+  jvmtiError err = jvmti->Allocate((threads_count * sizeof(jthread)),
+                                   (unsigned char**)&threads);
+  check_jvmti_status(jni, err, "registerTestedThreads: error in JVMTI Allocate threads array");
+
+  for (int i = 0; i < threads_count; i++) {
+    jobject elem = jni->GetObjectArrayElement(threadsArr, i);
+    threads[i] = (jthread)jni->NewGlobalRef(elem);
+  }
+  LOG("registerTestedThreads: finished\n");
+}
+
+/* This function is executed on the suspender thread, not the Main thread */
+JNIEXPORT void JNICALL
+Java_ThreadToSuspend_init(JNIEnv *jni, jclass cls) {
+  jvmtiError err = jvmti->CreateRawMonitor("Agent monitor", &agent_monitor);
+  check_jvmti_status(jni, err, "Java_ThreadToSuspend_init: error in JVMTI CreateRawMonitor");
+
+  // Main thread has to wait for the suspender thread to complete tested threads suspension
+  agent_lock(jni);
+}
+
+/* This function is executed on the suspender thread which is not Main thread */
+JNIEXPORT void JNICALL
+Java_ThreadToSuspend_suspendTestedThreads(JNIEnv *jni, jclass cls) {
+  jvmtiError* results = NULL;
+  jvmtiError err;
+
+  LOG("\nsuspendTestedThreads: started");
+  err = jvmti->Allocate((threads_count * sizeof(jvmtiError)),
+                        (unsigned char**)&results);
+  check_jvmti_status(jni, err, "suspendTestedThreads: error in JVMTI Allocate results array");
+
+  LOG("suspendTestedThreads: before JVMTI SuspendThreadList");
+  err = jvmti->SuspendThreadList(threads_count, threads, results);
+  check_jvmti_status(jni, err, "suspendTestedThreads: error in JVMTI SuspendThreadList");
+
+  LOG("suspendTestedThreads: check and print SuspendThreadList results:");
+  for (int i = 0; i < threads_count; i++) {
+    LOG("  thread #%d: (%d)", i, (int)results[i]);
+    check_jvmti_status(jni, results[i], "suspendTestedThreads: error in SuspendThreadList results[i]");
+  }
+  LOG("suspendTestedThreads: finished\n");
+
+  // Allow the Main thread to inspect the result of tested threads suspension
+  agent_unlock(jni);
+
+  err = jvmti->Deallocate((unsigned char*)results);
+  check_jvmti_status(jni, err, "suspendTestedThreads: error in JVMTI Deallocate results");
+}
+
+JNIEXPORT jboolean JNICALL
+Java_SuspendWithCurrentThread_checkTestedThreadsSuspended(JNIEnv *jni, jclass cls) {
+  LOG("checkTestedThreadsSuspended: started");
+
+  // Block until the suspender thread competes the tested threads suspension
+  agent_lock(jni);
+  agent_unlock(jni);
+
+  for (int i = 0; i < threads_count; i++) {
+    jint state = 0;
+    jvmtiError err = jvmti->GetThreadState(threads[i], &state);
+    check_jvmti_status(jni, err, "checkTestedThreadsSuspended: error in GetThreadState");
+
+    if ((state & JVMTI_THREAD_STATE_SUSPENDED) == 0) {
+      LOG("thread #%d has not been suspended yet: "
+             "#   state: (%#x)", i, (int)state);
+      jni->FatalError("checkTestedThreadsSuspended: error: expected all tested threads suspended");
+    }
+  }
+  LOG("checkTestedThreadsSuspended: finished\n");
+  return JNI_TRUE;
+}
+
+JNIEXPORT void JNICALL
+Java_SuspendWithCurrentThread_resumeTestedThreads(JNIEnv *jni, jclass cls) {
+  jvmtiError* results = NULL;
+  jvmtiError err;
+
+  LOG("\nresumeTestedThreads: started");
+  err = jvmti->Allocate((threads_count * sizeof(jvmtiError)),
+                        (unsigned char**)&results);
+  check_jvmti_status(jni, err, "resumeTestedThreads: error in JVMTI Allocate results array");
+
+  LOG("resumeTestedThreads: before JVMTI ResumeThreadList");
+  err = jvmti->ResumeThreadList(threads_count, threads, results);
+  check_jvmti_status(jni, err, "resumeTestedThreads: error in ResumeThreadList");
+
+  LOG("resumeTestedThreads: check and print ResumeThreadList results:");
+  for (int i = 0; i < threads_count; i++) {
+    LOG("  thread #%d: (%d)", i, (int)results[i]);
+    check_jvmti_status(jni, results[i], "resumeTestedThreads: error in ResumeThreadList results[i]");
+  }
+
+  err = jvmti->Deallocate((unsigned char*)results);
+  check_jvmti_status(jni, err, "resumeTestedThreads: error in JVMTI Deallocate results");
+
+  LOG("resumeTestedThreads: finished\n");
+}
+
+JNIEXPORT void JNICALL
+Java_SuspendWithCurrentThread_releaseTestedThreadsInfo(JNIEnv *jni, jclass cls) {
+  jvmtiError err;
+
+  LOG("\nreleaseTestedThreadsInfo: started");
+  err = jvmti->DestroyRawMonitor(agent_monitor);
+  check_jvmti_status(jni, err, "releaseTestedThreadsInfo: error in JVMTI DestroyRawMonitor");
+
+  for (int i = 0; i < threads_count; i++) {
+    if (threads[i] != NULL) {
+      jni->DeleteGlobalRef(threads[i]);
+    }
+  }
+  err = jvmti->Deallocate((unsigned char*)threads);
+  check_jvmti_status(jni, err, "releaseTestedThreadsInfo: error in JVMTI Deallocate threads");
+
+  LOG("releaseTestedThreadsInfo: finished\n");
+}
+
+
+/** Agent library initialization. */
+
+JNIEXPORT jint JNICALL
+Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
+  LOG("\nAgent_OnLoad started");
+
+  // create JVMTI environment
+  if (jvm->GetEnv((void **) (&jvmti), JVMTI_VERSION) != JNI_OK) {
+    return JNI_ERR;
+  }
+
+  // add specific capabilities for suspending thread
+  jvmtiCapabilities suspendCaps;
+  memset(&suspendCaps, 0, sizeof(suspendCaps));
+  suspendCaps.can_suspend = 1;
+
+  jvmtiError err = jvmti->AddCapabilities(&suspendCaps);
+  if (err != JVMTI_ERROR_NONE) {
+    return JNI_ERR;
+  }
+  LOG("Agent_OnLoad finished\n");
+  return JNI_OK;
+}
+
+}
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java	Thu Oct 10 10:57:42 2019 -0400
@@ -140,6 +140,7 @@
         for (String cmd : commands) {
             int index = commands.indexOf(cmd) + 1;
             OutputAnalyzer out = new OutputAnalyzer(parts[index]);
+            out.shouldNotMatch("Unrecognized command.");
 
             if (expectedStrMap != null) {
                 List<String> expectedStr = expectedStrMap.get(cmd);
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java	Thu Oct 10 10:57:42 2019 -0400
@@ -52,9 +52,8 @@
             List<String> cmds = List.of("pmap");
 
             Map<String, List<String>> expStrMap = new HashMap<>();
-            expStrMap.put("pmap", List.of(
-                    "jvm", "java", "net", "nio",
-                    "jimage", "zip", "verify"));
+            expStrMap.put("pmap",
+                    List.of("jvm", "java", "net", "nio", "jimage", "zip"));
 
             test.run(theApp.getPid(), cmds, expStrMap, null);
         } catch (SkippedException se) {
--- a/test/hotspot/jtreg/serviceability/sa/TestUniverse.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/serviceability/sa/TestUniverse.java	Thu Oct 10 10:57:42 2019 -0400
@@ -86,7 +86,7 @@
             break;
 
         case Shenandoah:
-            expStrings.add("Shenandoah Heap");
+            expStrings.add("Shenandoah heap");
             break;
         }
 
--- a/test/hotspot/jtreg/vmTestbase/metaspace/gc/HighWaterMarkTest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/metaspace/gc/HighWaterMarkTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -42,8 +42,6 @@
  * Test verifies that MinMetaspaceFreeRatio/MaxMetaspaceFreeRatio settings
  * affect the frequency of GC. (High-water mark)
  *
- * Note: The test doesn't check the GC count if CMS is used.
- *
  * Quoting: Java SE 8 HotSpot[tm] Virtual Machine Garbage Collection Tuning
  * <pre>
  * Class metadata is deallocated when the corresponding Java class is unloaded.
@@ -175,11 +173,6 @@
             throw new Fault("Committed amount hasn't achieved " + bytes2k(committedLevel));
         }
 
-        if (VMRuntimeEnvUtils.isVMOptionEnabled("UseConcMarkSweepGC")) {
-            System.out.println("ConcMarkSweep is used, cannot count GC");
-            return;
-        }
-
         int gcCount = getMetaspaceGCCount();
         if (gcCount < 0) {
             // perhpas, it's better to silently pass here... Let's see.
--- a/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_0_1/TestDescription.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_0_1/TestDescription.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -29,6 +29,11 @@
  * @summary converted from VM Testbase metaspace/gc/watermark_0_1.
  * VM Testbase keywords: [nonconcurrent, no_cds]
  *
+ * @comment Don't run test in configurations where we can't reliably count number of metaspace triggered GCs
+ * @requires vm.gc != null | !vm.opt.final.ClassUnloadingWithConcurrentMark
+ * @requires vm.gc != "G1" | !vm.opt.final.ClassUnloadingWithConcurrentMark
+ * @requires vm.gc != "ConcMarkSweep"
+ * @requires vm.gc != "Z"
  * @library /vmTestbase /test/lib
  * @run driver jdk.test.lib.FileInstaller . .
  * @run main/othervm
--- a/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_10_20/TestDescription.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_10_20/TestDescription.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -29,6 +29,11 @@
  * @summary converted from VM Testbase metaspace/gc/watermark_10_20.
  * VM Testbase keywords: [nonconcurrent, no_cds]
  *
+ * @comment Don't run test in configurations where we can't reliably count number of metaspace triggered GCs
+ * @requires vm.gc != null | !vm.opt.final.ClassUnloadingWithConcurrentMark
+ * @requires vm.gc != "G1" | !vm.opt.final.ClassUnloadingWithConcurrentMark
+ * @requires vm.gc != "ConcMarkSweep"
+ * @requires vm.gc != "Z"
  * @library /vmTestbase /test/lib
  * @run driver jdk.test.lib.FileInstaller . .
  * @run main/othervm
--- a/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_70_80/TestDescription.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_70_80/TestDescription.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -29,6 +29,11 @@
  * @summary converted from VM Testbase metaspace/gc/watermark_70_80.
  * VM Testbase keywords: [nonconcurrent, no_cds]
  *
+ * @comment Don't run test in configurations where we can't reliably count number of metaspace triggered GCs
+ * @requires vm.gc != null | !vm.opt.final.ClassUnloadingWithConcurrentMark
+ * @requires vm.gc != "G1" | !vm.opt.final.ClassUnloadingWithConcurrentMark
+ * @requires vm.gc != "ConcMarkSweep"
+ * @requires vm.gc != "Z"
  * @library /vmTestbase /test/lib
  * @run driver jdk.test.lib.FileInstaller . .
  * @run main/othervm
--- a/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_99_100/TestDescription.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/metaspace/gc/watermark_99_100/TestDescription.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -29,6 +29,11 @@
  * @summary converted from VM Testbase metaspace/gc/watermark_99_100.
  * VM Testbase keywords: [nonconcurrent, no_cds]
  *
+ * @comment Don't run test in configurations where we can't reliably count number of metaspace triggered GCs
+ * @requires vm.gc != null | !vm.opt.final.ClassUnloadingWithConcurrentMark
+ * @requires vm.gc != "G1" | !vm.opt.final.ClassUnloadingWithConcurrentMark
+ * @requires vm.gc != "ConcMarkSweep"
+ * @requires vm.gc != "Z"
  * @library /vmTestbase /test/lib
  * @run driver jdk.test.lib.FileInstaller . .
  * @run main/othervm
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorWait/rawmnwait005/rawmnwait005.cpp	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorWait/rawmnwait005/rawmnwait005.cpp	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
 static jvmtiEnv *jvmti = NULL;
 static jvmtiCapabilities caps;
 static jint result = PASSED;
-static jboolean printdump = JNI_FALSE;
+static jboolean printdump = JNI_TRUE;
 static jrawMonitorID monitor;
 static jrawMonitorID wait_lock;
 static jlong wait_time;
@@ -100,6 +100,8 @@
     jvmtiError err;
     const char* const thread_name = "test thread";
 
+    // Once we hold this monitor we know we can't get interrupted
+    // until we have called wait().
     err = jvmti->RawMonitorEnter(monitor);
     if (err != JVMTI_ERROR_NONE) {
         printf("(RawMonitorEnter#test) unexpected error: %s (%d)\n",
@@ -110,6 +112,7 @@
         printf(">>> [%s] acquired lock for 'monitor' ...\n", thread_name);
     }
 
+    // We can't get this monitor until the main thread has called wait() on it.
     err = jvmti->RawMonitorEnter(wait_lock);
     if (err != JVMTI_ERROR_NONE) {
         printf("(RawMonitorEnter#wait) unexpected error: %s (%d)\n",
@@ -156,6 +159,36 @@
         result = STATUS_FAILED;
     }
 
+    // We can't reacquire this monitor until the main thread is waiting for us to
+    // complete.
+    err = jvmti->RawMonitorEnter(wait_lock);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(RawMonitorEnter#wait) unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        result = STATUS_FAILED;
+        return;
+    }
+
+    if (printdump == JNI_TRUE) {
+        printf(">>> [%s] acquired lock for 'wait_lock' ...\n", thread_name);
+        printf(">>> [%s] notifying main thread we are done ...\n", thread_name);
+    }
+
+    err = jvmti->RawMonitorNotify(wait_lock);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(RawMonitorWait#wait) unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        result = STATUS_FAILED;
+        return;
+    }
+    err = jvmti->RawMonitorExit(wait_lock);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(RawMonitorExit#wait) unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        result = STATUS_FAILED;
+        return;
+    }
+
     if (printdump == JNI_TRUE) {
         printf(">>> [%s] all done\n", thread_name);
     }
@@ -223,6 +256,11 @@
     if (printdump == JNI_TRUE) {
         printf(">>> [%s] starting test thread ...\n", thread_name);
     }
+
+    // This starts a daemon thread, so we need to synchronize with it
+    // before we terminate - else the test will end before it checks
+    // it was interrupted!
+
     err = jvmti->RunAgentThread(thr, test_thread, NULL,
                                 JVMTI_THREAD_NORM_PRIORITY);
     if (err != JVMTI_ERROR_NONE) {
@@ -244,12 +282,7 @@
         printf(">>> [%s] got notification from test thread ...\n", thread_name);
     }
 
-    err = jvmti->RawMonitorExit(wait_lock);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(RawMonitorExit#wait) unexpected error: %s (%d)\n",
-               TranslateError(err), err);
-        return STATUS_FAILED;
-    }
+    // Keep the wait_lock so we can wait again at the end.
 
     err = jvmti->RawMonitorEnter(monitor);
     if (err != JVMTI_ERROR_NONE) {
@@ -280,6 +313,26 @@
     }
 
     if (printdump == JNI_TRUE) {
+        printf(">>> [%s] waiting for test thread to complete its wait and notify us ...\n", thread_name);
+    }
+    err = jvmti->RawMonitorWait(wait_lock, (jlong)0);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(RawMonitorWait#wait) unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        return STATUS_FAILED;
+    }
+    if (printdump == JNI_TRUE) {
+        printf(">>> [%s] got final notification from test thread ...\n", thread_name);
+    }
+
+    err = jvmti->RawMonitorExit(wait_lock);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(RawMonitorExit#wait) unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        return STATUS_FAILED;
+    }
+
+    if (printdump == JNI_TRUE) {
         printf(">>> [%s] all done\n", thread_name);
     }
 
--- a/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/hotspot/jtreg/vmTestbase/nsk/share/jdi/Binder.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -201,8 +201,6 @@
                 debugee = localLaunchDebugee(vmm, classToExecute, classPath);
             } else if (argumentHandler.isAttachingConnector()) {
                 debugee = localLaunchAndAttachDebugee(vmm, classToExecute, classPath);
-            } else if (argumentHandler.isLaunchingConnector()) {
-                debugee = localLaunchDebugee(vmm, classToExecute, classPath);
             } else if (argumentHandler.isListeningConnector()) {
                 debugee = localLaunchAndListenDebugee(vmm, classToExecute, classPath);
             } else {
--- a/test/jdk/ProblemList.txt	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/jdk/ProblemList.txt	Thu Oct 10 10:57:42 2019 -0400
@@ -861,6 +861,8 @@
 sun/tools/jstat/jstatClassloadOutput1.sh                        8173942 generic-all
 sun/tools/jhsdb/BasicLauncherTest.java                          8193639,8211767 solaris-all,linux-ppc64,linux-ppc64le
 sun/tools/jhsdb/HeapDumpTest.java                               8193639 solaris-all
+sun/tools/jhsdb/HeapDumpTestWithActiveProcess.java              8230731,8001227 windows-all
+sun/tools/jhsdb/HeapDumpTestWithActiveProcess.java              8231635,8231634 generic-all
 
 
 ############################################################################
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/jdi/JdbStopInNotificationThreadTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary Tests that the breakpoint in the notification listener is hit when the
+ * notification thread is enabled and is not hit when the notification thread is disabled
+ * (the service thread delivers the notifications in this case).
+ *
+ * @library /test/lib
+ * @run compile -g JdbStopInNotificationThreadTest.java
+ * @run main/othervm JdbStopInNotificationThreadTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import lib.jdb.JdbCommand;
+import lib.jdb.JdbTest;
+
+import javax.management.Notification;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationListener;
+import java.lang.management.*;
+import java.util.Collection;
+import java.util.LinkedList;
+
+class JdbStopInNotificationThreadTestTarg {
+
+    private static volatile boolean done = false;
+
+    private static final MemoryPoolMXBean tenuredGenPool =
+            findTenuredGenPool();
+
+    public static void main(String[] args) throws Exception {
+        test(); // @1 breakpoint
+    }
+
+    private static void test() throws Exception {
+        setPercentageUsageThreshold(0.1);
+        MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
+        NotificationEmitter emitter = (NotificationEmitter) mbean;
+        emitter.addNotificationListener(new NotificationListener() {
+            public void handleNotification(Notification n, Object hb) {
+                System.out.println("Notification received:" + n.getType());
+                if (n.getType().equals(
+                        MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) {
+                    done = true;
+                    System.out.println("Notification MEMORY_THRESHOLD_EXCEEDED received:");
+                    long maxMemory = tenuredGenPool.getUsage().getMax();
+                    long usedMemory = tenuredGenPool.getUsage().getUsed();
+                    System.out.println("Memory usage low!!!"); // @2 breakpoint
+                    double percentageUsed = ((double) usedMemory) / maxMemory;
+                    System.out.println("percentageUsed = " + percentageUsed);
+                }
+            }
+        }, null, null);
+
+        Collection<Object[]> numbers = new LinkedList();
+        long counter = 0;
+        while (!done) {
+            numbers.add(new Object[1000]);
+            counter++;
+            if (counter % 1000 == 0) {
+                Thread.sleep(100);
+            }
+        }
+        System.out.println("Done");
+    }
+
+    private static MemoryPoolMXBean findTenuredGenPool() {
+        for (MemoryPoolMXBean pool :
+                ManagementFactory.getMemoryPoolMXBeans()) {
+            if (pool.getType() == MemoryType.HEAP &&
+                    pool.isUsageThresholdSupported()) {
+                return pool;
+            }
+        }
+        throw new RuntimeException("Could not find tenured space");
+    }
+
+    public static void setPercentageUsageThreshold(double percentage) {
+        if (percentage <= 0.0 || percentage > 1.0) {
+            throw new IllegalArgumentException("Percentage not in range");
+        }
+        System.out.println("Setting threashold for pool " + tenuredGenPool.getName() + " percentage:" + percentage);
+        long maxMemory = tenuredGenPool.getUsage().getMax();
+        long warningThreshold = (long) (maxMemory * percentage);
+        tenuredGenPool.setUsageThreshold(warningThreshold);
+    }
+}
+
+public class JdbStopInNotificationThreadTest extends JdbTest {
+
+    private static final String DEBUGGEE_CLASS = JdbStopInNotificationThreadTestTarg.class.getName();
+    private static final String PATTERN1_TEMPLATE = "^Breakpoint hit: \"thread=Notification Thread\", " +
+            "JdbStopInNotificationThreadTestTarg\\$1\\.handleNotification\\(\\), line=%LINE_NUMBER.*\\R%LINE_NUMBER\\s+System\\.out\\.println\\(\"Memory usage low!!!\"\\);.*";
+
+    private JdbStopInNotificationThreadTest() {
+        super(DEBUGGEE_CLASS);
+    }
+
+    public static void main(String argv[]) {
+        new JdbStopInNotificationThreadTest().run();
+    }
+
+    @Override
+    protected void runCases() {
+        if (isNotificationThreadDisabled()) {
+            System.out.println("Notification Thread is disabled. Skipping the test");
+            return;
+        }
+        int bpLine2 = parseBreakpoints(getTestSourcePath("JdbStopInNotificationThreadTest.java"), 2).get(0);
+        jdb.command(JdbCommand.stopAt(DEBUGGEE_CLASS + "$1", bpLine2));
+        String pattern = PATTERN1_TEMPLATE.replaceAll("%LINE_NUMBER", String.valueOf(bpLine2));
+        jdb.command(JdbCommand.cont());
+        new OutputAnalyzer(jdb.getJdbOutput()).shouldMatch(pattern);
+    }
+
+    private boolean isNotificationThreadDisabled() {
+        int bpLine1 = parseBreakpoints(getTestSourcePath("JdbStopInNotificationThreadTest.java"), 1).get(0);
+        jdb.command(JdbCommand.stopAt(DEBUGGEE_CLASS, bpLine1));
+        jdb.command(JdbCommand.run());
+        jdb.command(JdbCommand.threads());
+        if (new OutputAnalyzer(jdb.getJdbOutput()).getOutput().contains("Notification Thread")) {
+            return false;
+        }
+        return true;
+    }
+}
--- a/test/jdk/java/net/DatagramSocket/DatagramTimeout.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/jdk/java/net/DatagramSocket/DatagramTimeout.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,32 +23,56 @@
 
 /**
  * @test
- * @bug 4163126
- * @summary  test to see if timeout hangs
- * @run main/timeout=15 DatagramTimeout
+ * @bug 4163126 8222829
+ * @summary Test to see if timeout hangs. Also checks that
+ * negative timeout value fails as expected.
+ * @run testng DatagramTimeout
  */
 import java.net.DatagramPacket;
 import java.net.DatagramSocket;
 import java.net.SocketTimeoutException;
+import java.nio.channels.DatagramChannel;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.expectThrows;
+
 
 public class DatagramTimeout {
-    public static void main(String[] args) throws Exception {
-        boolean success = false;
-        DatagramSocket sock = new DatagramSocket();
+    private static final Class<IllegalArgumentException> IAE = IllegalArgumentException.class;
+    private static final Class<SocketTimeoutException> STE = SocketTimeoutException.class;
 
-        try {
-            DatagramPacket p;
+    /**
+     * Test DatagramSocket setSoTimeout with a valid timeout value.
+     */
+    @Test
+    public void testSetTimeout() throws Exception {
+        try (DatagramSocket s = new DatagramSocket()) {
             byte[] buffer = new byte[50];
-            p = new DatagramPacket(buffer, buffer.length);
-            sock.setSoTimeout(2);
-            sock.receive(p);
-        } catch (SocketTimeoutException e) {
-            success = true;
-        } finally {
-            sock.close();
+            DatagramPacket p = new DatagramPacket(buffer, buffer.length);
+            s.setSoTimeout(2);
+            expectThrows(STE, () -> s.receive(p));
         }
-        if (!success)
-            throw new RuntimeException("Socket timeout failure.");
     }
 
+    /**
+     * Test DatagramSocket setSoTimeout with a negative timeout.
+     */
+    @Test
+    public void testSetNegativeTimeout() throws Exception {
+        try (DatagramSocket s = new DatagramSocket()) {
+            expectThrows(IAE, () -> s.setSoTimeout(-1));
+        }
+    }
+
+    /**
+     * Test DatagramSocketAdaptor setSoTimeout with a negative timeout.
+     */
+    @Test
+    public void testNegativeTimeout() throws Exception {
+        try (DatagramChannel dc = DatagramChannel.open()) {
+            var s = dc.socket();
+            expectThrows(IAE, () -> s.setSoTimeout(-1));
+        }
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/channels/DatagramChannel/AddressesAfterDisconnect.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,109 @@
+/*
+ * 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
+ * @library /test/lib
+ * @summary Test DatagramChannel local address after disconnect.
+ * @requires (os.family != "mac")
+ * @run testng/othervm AddressesAfterDisconnect
+ * @run testng/othervm -Djava.net.preferIPv6Addresses=true AddressesAfterDisconnect
+ * @run testng/othervm -Djava.net.preferIPv4Stack=true AddressesAfterDisconnect
+ */
+
+import jdk.test.lib.net.IPSupport;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.net.StandardProtocolFamily;
+import java.nio.channels.DatagramChannel;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.assertFalse;
+
+public class AddressesAfterDisconnect {
+
+    public static void main(String[] args) throws IOException {
+        new AddressesAfterDisconnect().execute();
+    }
+
+    @Test
+    public void execute() throws IOException {
+        IPSupport.throwSkippedExceptionIfNonOperational();
+        boolean preferIPv6 = Boolean.getBoolean("java.net.preferIPv6Addresses");
+
+        // test with default protocol family
+        try (DatagramChannel dc = DatagramChannel.open()) {
+            System.out.println("Test with default");
+            dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+            test(dc);
+            test(dc);
+        }
+
+        if (IPSupport.hasIPv6()) {
+            // test with IPv6 only
+            System.out.println("Test with IPv6 only");
+            try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET6)) {
+                dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+                test(dc);
+                test(dc);
+            }
+        }
+
+        if (IPSupport.hasIPv4() && !preferIPv6) {
+            // test with IPv4 only
+            System.out.println("Test with IPv4 only");
+            try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)) {
+                dc.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+                test(dc);
+                test(dc);
+            }
+        }
+    }
+
+    /**
+     * Connect DatagramChannel to a server, write a datagram and disconnect. Invoke
+     * a second or subsequent time with the same DatagramChannel instance to check
+     * that disconnect works as expected.
+     */
+    static void test(DatagramChannel dc) throws IOException {
+        SocketAddress local = dc.getLocalAddress();
+        try (DatagramChannel server = DatagramChannel.open()) {
+            server.bind(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0));
+            SocketAddress remote = server.getLocalAddress();
+            dc.connect(remote);
+            assertTrue(dc.isConnected());
+            // comment the following two lines on OS X to see JDK-8231259
+            assertEquals(dc.getLocalAddress(), local, "local address after connect");
+            assertEquals(dc.getRemoteAddress(), remote, "remote address after connect");
+            dc.disconnect();
+            assertFalse(dc.isConnected());
+            assertEquals(dc.getLocalAddress(), local, "local address after disconnect");
+            assertEquals(dc.getRemoteAddress(), null, "remote address after disconnect");
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/text/Format/DateFormat/SimpleDateFormatPatternTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,229 @@
+/*
+ * 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 4326988 6990146 8231213
+ * @summary test SimpleDateFormat, check its pattern in the constructor
+ * @run testng/othervm SimpleDateFormatPatternTest
+ */
+import java.lang.IllegalArgumentException;
+import java.text.DateFormat;
+import java.text.DateFormatSymbols;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class SimpleDateFormatPatternTest {
+    private static String[] validPat = {
+            "yyyy-MM-dd h.mm.ss.a z",
+            "yyyy'M'd' ahh'mm'ss' z",
+            "dd MMMM yyyy hh:mm:ss",
+            "d MMM yy HH:mm:ss",
+            "dd/MM/yyyy HH:mm:ss",
+            "d' / 'MMMM' / 'yyyy HH:mm:ss z",
+            "d.M.yyyy H:mm:ss",
+            "d' de 'MMMM' de 'yyyy H'h'm'min's's' z",
+            "dd. MMMM yyyy HH:mm:ss z",
+            "d-M-yyyy H:mm:ss",
+            "EEEE''d MMMM G yyyy, H'  'm'  'ss' '",
+            "dd.MMM.yyyy HH:mm:ss",
+            "yy-MM-dd h:mm:ss.a",
+            "d' de 'MMMM' de 'yyyy hh:mm:ss a z",
+            "EEEE d MMMM yyyy H' h 'mm' min 'ss' s 'z",
+            "d MMMM yyyy H:mm:ss",
+            "d/MM/yyyy hh:mm:ss a",
+            "EEEE, d, MMMM yyyy HH:mm:ss z",
+            "EEEE, d. MMMM yyyy HH.mm.' h' z",
+            "EEEE, d' / 'MMMM' / 'yyyy HH:mm:ss z",
+            "d/MM/yyyy HH:mm:ss",
+            "d MMMM yyyy H:mm:ss z",
+            "MMMM d, yyyy h:mm:ss a z",
+            "yyyy. MMMM d. H:mm:ss z",
+            "d' de 'MMMM' de 'yyyy H:mm:ss z",
+            "EEEE, MMMM d, yyyy h:mm:ss a z",
+            "d/M/yyyy H:mm:ss",
+            "d-MMM-yy HH:mm:ss",
+            "EEEE d' de 'MMMM' de 'yyyy hh:mm:ss a z",
+            "yyyy'M'd' ahh'mm'ss'",
+            "yyyy'MM'dd' EEEE ahh'mm'ss'",
+            "EEEE, d MMMM yyyy HH:mm:ss z",
+
+            //6990146: 'Y' for year; 'X' for time zone; 'u' for day number of the week
+            "d/M/YYYY H:mm:ss",
+            "d-MMM-YY HH:mm:ss",
+            "EEEE d' de 'MMMM' de 'YYYY hh:mm:ss a X",
+            "YYYY M d ahh:mm:ss",
+            "YYYY MM dd EEEE u ahh/mm/ss",
+            "EEEE, u, d MMMM YYYY HH:mm:ss X",
+            "YYYY M d Z ahh mm ss",
+            "YYYY-MM-dd EEEE u ahh-mm-ss",
+
+            //*added for sr-Latn*
+            "EEEE, dd. MMMM y. HH.mm.ss zzzz",
+            "dd. MMMM y. HH.mm.ss z",
+            "dd.MM.y. HH.mm.ss",
+            "d.M.yy. HH.mm"
+    };
+
+    private static String[] invalidPat = {
+            "yyyy'M'd' ahh:mm:ss",
+            "EEEe d MM MM yyyy HH' h 'mm zzzZ",
+            "d MMMM\\ yyyy, H'  'm' 'g",
+            "EEEE d' @# MMMMde 'yyys HHH'mm z",
+            "yyyy'MMe 2 #dd' EEEEahh'mm'ss' z,z",
+            "yyyy.M.d H;mm.ses",
+            "EEEe, d MMMM yyyy h:mm:ss a z",
+            "EEEE, MMMM d, 'y y y y h:mm:ss 'o''clock' a z",
+            "dd MMMM yyyy 0HHcl:mm:ss z",
+            "d.M_M_y.yy1yy HextH:mm|45:",
+            "d,D MMMTTTTTTTTTKM yy|+yy HH:m m:ss z",
+            "d-MDtM M-yy H:mm:ss",
+            "yyyy/M///m/nM/d Dd H:m$m:s s",
+            "EEEE, dd. MMMM yyyy HH:m'''m' Uhr 'z",
+            //6990146
+            "EEEE d' de 'MMMM' de 'YYYY hh:mm:ss a x",
+            "EEEE, U, d MMMM YYYY HH:mm:ss Z"
+    };
+
+    private static Locale[] locales = DateFormat.getAvailableLocales();
+    private static Object[][] dfAllLocalesObj = createAllLocales();
+    private static Object[][] invalidPatObj = createPatternObj(invalidPat);
+    private static Object[][] validPatObj = createPatternObj(validPat);
+
+    private static Object[][] createAllLocales() {
+        Object[][] objArray = new Object[locales.length][];
+        for (int i = 0; i < locales.length; i++) {
+            objArray[i] = new Object[1];
+            objArray[i][0] = locales[i];
+        }
+        return objArray;
+    }
+
+    private static Object[][] createPatternObj(String[] pattern){
+        Object[][] objArray = new Object[locales.length * pattern.length][];
+        int k = 0;
+        for (int i = 0; i < locales.length; i++) {
+            for (int j = 0; j < pattern.length; j++) {
+                objArray[k] = new Object[2];
+                objArray[k][0] = pattern[j];
+                objArray[k][1] = locales[i];
+                k = k + 1;
+            }
+        }
+        return objArray;
+    }
+
+    @DataProvider(name = "dfAllLocalesObj")
+    Object[][] dfAllLocalesObj() {
+        return dfAllLocalesObj;
+    }
+
+    @DataProvider(name = "invalidPatternObj")
+    Object[][] invalidPatternObj() {
+        return invalidPatObj;
+    }
+
+    @DataProvider(name = "validPatternObj")
+    Object[][] validPatternObj() {
+        return validPatObj;
+    }
+
+    //check Constructors for invalid pattern
+    @Test(dataProvider = "invalidPatternObj",
+            expectedExceptions = IllegalArgumentException.class)
+    public void testIllegalArgumentException1(String pattern, Locale loc)
+            throws IllegalArgumentException {
+        Locale.setDefault(loc);
+        new SimpleDateFormat(pattern);
+    }
+
+    @Test(dataProvider = "invalidPatternObj",
+            expectedExceptions = IllegalArgumentException.class)
+    public void testIllegalArgumentException2(String pattern, Locale loc)
+            throws IllegalArgumentException {
+        Locale.setDefault(loc);
+        new SimpleDateFormat(pattern, new DateFormatSymbols());
+    }
+
+    @Test(dataProvider = "invalidPatternObj",
+            expectedExceptions = IllegalArgumentException.class)
+    public void testIllegalArgumentException3 (String pattern, Locale loc)
+            throws IllegalArgumentException {
+        Locale.setDefault(loc);
+        new SimpleDateFormat(pattern, Locale.getDefault());
+    }
+
+    @Test(dataProvider = "invalidPatternObj",
+            expectedExceptions = IllegalArgumentException.class)
+    public void testIllegalArgumentException4(String pattern, Locale loc)
+            throws IllegalArgumentException {
+        Locale.setDefault(loc);
+        new SimpleDateFormat().applyPattern(pattern);
+    }
+
+    //check Constructors for null pattern
+    @Test(dataProvider = "dfAllLocalesObj",
+            expectedExceptions = NullPointerException.class)
+    public void testNullPointerException1(Locale loc)
+            throws NullPointerException {
+        Locale.setDefault(loc);
+        new SimpleDateFormat(null);
+    }
+
+    @Test(dataProvider = "dfAllLocalesObj",
+            expectedExceptions = NullPointerException.class)
+    public void testNullPointerException2(Locale loc)
+            throws NullPointerException {
+        Locale.setDefault(loc);
+        new SimpleDateFormat(null, new DateFormatSymbols());
+    }
+
+    @Test(dataProvider = "dfAllLocalesObj",
+            expectedExceptions = NullPointerException.class)
+    public void testNullPointerException3(Locale loc)
+            throws NullPointerException {
+        Locale.setDefault(loc);
+        new SimpleDateFormat(null, Locale.getDefault());
+    }
+
+    @Test(dataProvider = "dfAllLocalesObj",
+            expectedExceptions = NullPointerException.class)
+    public void testNullPointerException4(Locale loc)
+            throws NullPointerException {
+        Locale.setDefault(loc);
+        new SimpleDateFormat().applyPattern(null);
+    }
+
+    @Test(dataProvider = "validPatternObj")
+    //check Constructors for valid pattern
+    public void testValidPattern(String pattern, Locale loc) {
+        Locale.setDefault(loc);
+        new SimpleDateFormat(pattern);
+        new SimpleDateFormat(pattern, new DateFormatSymbols());
+        new SimpleDateFormat(pattern, Locale.getDefault());
+        new SimpleDateFormat().applyPattern(pattern);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/util/stream/test/org/openjdk/tests/java/util/stream/CollectorExample.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,105 @@
+/*
+ * 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.openjdk.tests.java.util.stream;
+
+/*
+ * THE CONTENTS OF THIS FILE HAVE TO BE IN SYNC WITH THE EXAMPLES USED
+ * IN THE JAVADOC.
+ *
+ * @test
+ * @bug 8231161
+ * @compile CollectorExample.java
+ * @summary Compilation test only. Compile code snippets from
+ * java.util.stream.Collector class-level API documentation
+ */
+
+import java.util.*;
+import java.util.function.BiConsumer;
+import java.util.function.BinaryOperator;
+import java.util.function.Function;
+import java.util.function.Supplier;
+import java.util.stream.Collector;
+import java.util.stream.Collectors;
+
+public class CollectorExample {
+
+    // Empty helper classes
+
+    class Widget {
+    }
+
+    class Employee {
+        public int getSalary() {
+            return 0;    // money isn't everything
+        }
+
+        public Department getDepartment() {
+            return new Department();
+        }
+    }
+
+    class Department {
+    }
+
+    <T, A, R> void testSnippet1(Collector<T, A, R> collector, T t1, T t2) {
+
+        Supplier<A> supplier = collector.supplier();
+        BiConsumer<A, T> accumulator = collector.accumulator();
+        BinaryOperator<A> combiner = collector.combiner();
+        Function<A, R> finisher = collector.finisher();
+
+        // Example start
+        A a1 = supplier.get();
+        accumulator.accept(a1, t1);
+        accumulator.accept(a1, t2);
+        R r1 = finisher.apply(a1);
+
+        A a2 = supplier.get();
+        accumulator.accept(a2, t1);
+        A a3 = supplier.get();
+        accumulator.accept(a3, t2);
+        R r2 = finisher.apply(combiner.apply(a2, a3));
+    }
+
+    void testSnippet2() {
+        Collector<Widget, ?, TreeSet<Widget>> intoSet =
+                Collector.of(TreeSet::new, TreeSet::add,
+                        (left, right) -> { left.addAll(right); return left; });
+    }
+
+    <T, A, R> void testSnippet3(Collector<T, A, R> collector, Collection<T> data) {
+        A container = collector.supplier().get();
+        for (T t : data)
+            collector.accumulator().accept(container, t);
+        collector.finisher().apply(container);
+    }
+
+    void testSnippet4and5() {
+        Collector<Employee, ?, Integer> summingSalaries
+                = Collectors.summingInt(Employee::getSalary);
+
+        Collector<Employee, ?, Map<Department, Integer>> summingSalariesByDept
+                = Collectors.groupingBy(Employee::getDepartment, summingSalaries);
+    }
+}
--- a/test/jdk/java/util/zip/FlaterTest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/jdk/java/util/zip/FlaterTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,10 +23,11 @@
 
 /**
  * @test
- * @bug 6348045 6341887
+ * @bug 6348045 6341887 8231770
  * @summary GZipOutputStream/InputStream goes critical(calls JNI_Get*Critical)
- * and causes slowness.  This test uses Deflater and Inflater directly.
+ * and causes slowness. This test uses Deflater and Inflater directly.
  * @key randomness
+ * @run main/othervm -Xcheck:jni FlaterTest
  */
 
 import java.nio.*;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/javax/management/mxbean/ThreadStartTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,56 @@
+/*
+ * 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 8231666
+ * @summary Test checks that new threads could be successfully started when the thread
+ * table introduced in 8185005 is growing. The test enables the thread table by calling
+ * ThreadMXBean.getThreadInfo() and then creates a number of threads to force the thread
+ * table to grow.
+ *
+ * @run main ThreadStartTest
+ */
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.ThreadMXBean;
+
+public class ThreadStartTest {
+    public static void main(String[] args) {
+
+        ThreadMXBean mbean = ManagementFactory.getThreadMXBean();
+        // Enable thread table
+        mbean.getThreadInfo(Thread.currentThread().getId());
+
+        // Create a large number of threads to make the thread table grow
+        for (int i = 0; i < 1000; i++) {
+            Thread t = new Thread(() -> {
+                try {
+                    Thread.sleep(1000);
+                } catch (InterruptedException ex) {
+                }
+            });
+            t.start();
+        }
+    }
+}
--- a/test/jdk/jdk/jfr/jmx/TestRecordingOptions.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/jdk/jdk/jfr/jmx/TestRecordingOptions.java	Thu Oct 10 10:57:42 2019 -0400
@@ -25,6 +25,7 @@
 
 package jdk.jfr.jmx;
 
+import java.io.File;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -49,7 +50,7 @@
         options.put("dumpOnExit", "false");
         options.put("disk", "false");
         options.put("duration", "1 h"); // don't want recording to stop
-
+        options.put("destination", "." + File.separator + "dump.jfr");
         FlightRecorderMXBean bean = JmxHelper.getFlighteRecorderMXBean();
         long recId = bean.newRecording();
         Map<String, String> defaults = bean.getRecordingOptions(recId);
@@ -72,6 +73,7 @@
         Asserts.assertEquals(outOptions.get("dumpOnExit"), "false", "Wrong dumpOnExit");
         Asserts.assertEquals(outOptions.get("disk"), "false", "Wrong disk");
         Asserts.assertEquals(outOptions.get("duration"), "1 h", "Wrong duration");
+        Asserts.assertEquals(outOptions.get("destination"), "." + File.separator + "dump.jfr", "Wrong destination");
 
         // try empty map
         bean.setRecordingOptions(recId, new HashMap<>());
@@ -116,6 +118,7 @@
         nullMap.put("dumpOnExit", null);
         nullMap.put("disk", null);
         nullMap.put("duration", null);
+        nullMap.put("destination", null);
         bean.setRecordingOptions(recId, nullMap);
         Asserts.assertEquals(bean.getRecordingOptions(recId), defaults);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/nio/zipfs/CompressionModeTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+import org.testng.annotations.*;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import static java.lang.String.format;
+import static java.util.stream.Collectors.joining;
+import static org.testng.Assert.*;
+
+/**
+ * @test
+ * @bug 8231093
+ * @summary Test Zip FS compressionMethod property
+ * @modules jdk.zipfs
+ * @run testng CompressionModeTest
+ */
+public class CompressionModeTest {
+
+    private static final Path HERE = Path.of(".");
+
+    /**
+     * Number of ZIP entries to create
+     */
+    private static final int ENTRIES = 5;
+
+    /**
+     * Value used for creating the required entries in a ZIP or JAR file
+     */
+    private static final String ZIP_FILE_VALUE = "US Open 2019";
+    private static final byte[] ZIP_FILE_ENTRY =
+            ZIP_FILE_VALUE.getBytes(StandardCharsets.UTF_8);
+
+    private static final SecureRandom random = new SecureRandom();
+
+    /**
+     * Validate that you can create a ZIP file with and without compression
+     * and that entries are created with the specified compression method.
+     *
+     * @param env         Properties used for creating the ZIP Filesystem
+     * @param compression Indicates whether the files are DEFLATED(default)
+     *                    or STORED
+     * @throws Exception If an error occurs during the creation, verification or
+     *                   deletion of the ZIP file
+     */
+    @Test(dataProvider = "validCompressionMethods", enabled = true)
+    public void testValidCompressionMehods(Map<String, String> env,
+                                           int compression) throws Exception {
+
+        System.out.printf("ZIP FS Map = %s, Compression mode= %s%n ",
+                formatMap(env), compression);
+
+        Path zipfile = generatePath(HERE, "test", ".zip");
+        Files.deleteIfExists(zipfile);
+        createZipFile(zipfile, env, ENTRIES);
+        verify(zipfile, compression, ENTRIES, 0);
+        Files.deleteIfExists(zipfile);
+    }
+
+    /**
+     * Validate that an IllegalArgumentException is thrown when an invalid
+     * value is specified for the compressionMethod property.
+     *
+     * @param env Properties used for creating the ZIP Filesystem
+     * @throws Exception if an error occurs other than the expected
+     * IllegalArgumentException
+     */
+    @Test(dataProvider = "invalidCompressionMethod")
+    public void testInvalidCompressionMethod(Map<String, String> env) throws Exception {
+        System.out.printf("ZIP FS Map = %s%n ", formatMap(env));
+        Path zipfile = generatePath(HERE, "test", ".zip");
+        Files.deleteIfExists(zipfile);
+        assertThrows(IllegalArgumentException.class, () ->
+                createZipFile(zipfile, env, ENTRIES));
+        Files.deleteIfExists(zipfile);
+    }
+
+    /**
+     * Create a ZIP File System using the specified properties and a ZIP file
+     * with the specified number of entries
+     *
+     * @param zipFile Path to the ZIP File to create
+     * @param env     Properties used for creating the ZIP Filesystem
+     * @param entries Number of entries to add to the ZIP File
+     * @throws IOException If an error occurs while creating the ZIP file
+     */
+    private void createZipFile(Path zipFile, Map<String, String> env,
+                               int entries) throws IOException {
+        System.out.printf("Creating file = %s%n", zipFile);
+        try (FileSystem zipfs =
+                     FileSystems.newFileSystem(zipFile, env)) {
+
+            for (int i = 0; i < entries; i++) {
+                Files.writeString(zipfs.getPath("Entry-" + i), ZIP_FILE_VALUE);
+            }
+        }
+    }
+
+    /**
+     * DataProvider used to validate that you can create a ZIP file with and
+     * without compression.
+     */
+    @DataProvider(name = "validCompressionMethods")
+    private Object[][] validCompressionMethods() {
+        return new Object[][]{
+                {Map.of("create", "true"), ZipEntry.DEFLATED},
+                {Map.of("create", "true", "noCompression", "true"),
+                        ZipEntry.STORED},
+                {Map.of("create", "true", "noCompression", "false"),
+                        ZipEntry.DEFLATED},
+                {Map.of("create", "true", "compressionMethod", "STORED"),
+                        ZipEntry.STORED},
+                {Map.of("create", "true", "compressionMethod", "DEFLATED"),
+                        ZipEntry.DEFLATED},
+                {Map.of("create", "true", "compressionMethod", "stored"),
+                        ZipEntry.STORED},
+                {Map.of("create", "true", "compressionMethod", "deflated"),
+                        ZipEntry.DEFLATED}
+        };
+    }
+
+    /**
+     * DataProvider used to validate that an IllegalArgumentException is thrown
+     * for an invalid value for the compressionMethod property.
+     */
+    @DataProvider(name = "invalidCompressionMethod")
+    private Object[][] invalidCompressionMethod() {
+        HashMap<String, String> map = new HashMap<>();
+        map.put("create", "true");
+        map.put("compressionMethod", null);
+        return new Object[][]{
+                {map},
+                {Map.of("create", "true", "compressionMethod", "")},
+                {Map.of("create", "true", "compressionMethod",
+                        Integer.parseInt("5"))},
+                {Map.of("create", "true", "compressionMethod", "invalid")}
+        };
+    }
+
+    /**
+     * Verify that the given path is a ZIP file containing the
+     * expected entries.
+     *
+     * @param zipfile ZIP file to be validated
+     * @param method  Expected Compression method: STORED or DEFLATED
+     * @param entries Number of expected entries
+     * @param start   Starting number for verifying entries
+     * @throws Exception If an error occurs while examining the ZIP file
+     */
+    private static void verify(Path zipfile, int method, int entries,
+                               int start) throws Exception {
+        // check entries with ZIP API
+        try (ZipFile zf = new ZipFile(zipfile.toFile())) {
+            // check entry count
+            assertEquals(entries, zf.size());
+
+            // check compression method and content of each entry
+            for (int i = start; i < entries; i++) {
+                ZipEntry ze = zf.getEntry("Entry-" + i);
+                assertNotNull(ze);
+                assertEquals(method, ze.getMethod());
+                try (InputStream is = zf.getInputStream(ze)) {
+                    byte[] bytes = is.readAllBytes();
+                    assertTrue(Arrays.equals(bytes, ZIP_FILE_ENTRY));
+                }
+            }
+        }
+        // check entries with FileSystem API
+        try (FileSystem fs = FileSystems.newFileSystem(zipfile)) {
+
+            // check entry count
+            Path top = fs.getPath("/");
+            long count = Files.find(top, Integer.MAX_VALUE, (path, attrs) ->
+                    attrs.isRegularFile() || (attrs.isDirectory() &&
+                            path.getFileName() != null &&
+                            path.getFileName().toString().equals("META-INF")))
+                    .count();
+            assertEquals(entries, count);
+
+            // check content of each entry
+            for (int i = start; i < entries; i++) {
+                Path file = fs.getPath("Entry-" + i);
+                byte[] bytes = Files.readAllBytes(file);
+                assertTrue(Arrays.equals(bytes, ZIP_FILE_ENTRY));
+            }
+        }
+    }
+
+    /**
+     * Generate a temporary file Path
+     *
+     * @param dir    Directory used to create the path
+     * @param prefix The prefix string used to create the path
+     * @param suffix The suffix string used to create the path
+     * @return Path that was generated
+     */
+    private static Path generatePath(Path dir, String prefix, String suffix) {
+        long n = random.nextLong();
+        String s = prefix + Long.toUnsignedString(n) + suffix;
+        Path name = dir.getFileSystem().getPath(s);
+        // the generated name should be a simple file name
+        if (name.getParent() != null)
+            throw new IllegalArgumentException("Invalid prefix or suffix");
+        return dir.resolve(name);
+    }
+
+    /**
+     * Utility method to return a formatted String of the key:value entries for
+     * a Map
+     *
+     * @param env Map to format
+     * @return Formatted string of the Map entries
+     */
+    private static String formatMap(Map<String, String> env) {
+        return env.entrySet().stream()
+                .map(e -> format("(%s:%s)", e.getKey(), e.getValue()))
+                .collect(joining(", "));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/nio/zipfs/NonExistentPathTests.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.FileSystemNotFoundException;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.util.Map;
+
+import static org.testng.Assert.assertThrows;
+
+/**
+ * @test
+ * @bug 8223771
+ * @summary Validate the correct Exception is thrown if the Zip/JAR is not found
+ *
+ * @modules jdk.zipfs
+ * @run testng/othervm NonExistentPathTests
+ */
+public class NonExistentPathTests {
+    private static final String ZIPFS_SCHEME = "jar";
+    private static final ClassLoader CLASS_LOADER = null;
+    // Non-exist JAR file to test against
+    private static final Path INVALID_JAR_FILE = Path.of("jarDoesNotExist.jar");
+    // Standard Exception expected from FileSystems.newFileSystem
+    private static Class<? extends Exception> testException = IOException.class;
+
+    /**
+     * Validate that the correct Exception is thrown  when specifying a Path
+     * to a JAR that does not exist and is not being created.
+     */
+    @Test
+    public void testNewFileSystemWithPath() {
+        assertThrows(testException, () ->
+                FileSystems.newFileSystem(INVALID_JAR_FILE));
+        assertThrows(testException, () ->
+                FileSystems.newFileSystem(INVALID_JAR_FILE, Map.of()));
+        assertThrows(testException, () ->
+                FileSystems.newFileSystem(INVALID_JAR_FILE, CLASS_LOADER));
+        assertThrows(testException, () ->
+                FileSystems.newFileSystem(INVALID_JAR_FILE, Map.of(), CLASS_LOADER));
+    }
+
+    /**
+     * Validate that the correct Exception is thrown  when specifying a URI
+     * to a JAR that does not exist and is not being created.
+     */
+    @Test
+    public void testNewFileSystemWithUri() throws Exception {
+        var jarURI = new URI(ZIPFS_SCHEME,
+                INVALID_JAR_FILE.toUri().toString(), null);
+
+        assertThrows(testException, () ->
+                FileSystems.newFileSystem(jarURI, Map.of()));
+
+        assertThrows(testException, () ->
+                FileSystems.newFileSystem(jarURI, Map.of(), CLASS_LOADER));
+    }
+}
--- a/test/jdk/jdk/nio/zipfs/jarfs/MultiReleaseJarTest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/jdk/jdk/nio/zipfs/jarfs/MultiReleaseJarTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8144355 8144062 8176709 8194070 8193802
+ * @bug 8144355 8144062 8176709 8194070 8193802 8231093
  * @summary Test aliasing additions to ZipFileSystem for multi-release jar files
  * @library /lib/testlibrary/java/util/jar
  * @modules jdk.compiler
@@ -40,6 +40,7 @@
 import java.lang.Runtime.Version;
 import java.net.URI;
 import java.nio.file.*;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -88,8 +89,7 @@
     public Object[][] createStrings() {
         return new Object[][]{
                 {"runtime", MAJOR_VERSION},
-                {"-20", 8},
-                {"0", 8},
+                {null, 8},
                 {"8", 8},
                 {"9", 9},
                 {Integer.toString(MAJOR_VERSION), MAJOR_VERSION},
@@ -101,8 +101,7 @@
     @DataProvider(name="integers")
     public Object[][] createIntegers() {
         return new Object[][] {
-                {Integer.valueOf(-5), 8},
-                {Integer.valueOf(0), 8},
+                {null, 8},
                 {Integer.valueOf(8), 8},
                 {Integer.valueOf(9), 9},
                 {Integer.valueOf(MAJOR_VERSION), MAJOR_VERSION},
@@ -114,6 +113,7 @@
     @DataProvider(name="versions")
     public Object[][] createVersions() {
         return new Object[][] {
+                {null,    8},
                 {Version.parse("8"),    8},
                 {Version.parse("9"),    9},
                 {Version.parse(Integer.toString(MAJOR_VERSION)),  MAJOR_VERSION},
@@ -122,6 +122,20 @@
         };
     }
 
+    @DataProvider(name="invalidVersions")
+    public Object[][] invalidVersions() {
+        return new Object[][] {
+                {Map.of("releaseVersion", "")},
+                {Map.of("releaseVersion", "invalid")},
+                {Map.of("releaseVersion", "0")},
+                {Map.of("releaseVersion", "-1")},
+                {Map.of("releaseVersion", "11.0.1")},
+                {Map.of("releaseVersion", new ArrayList<Long>())},
+                {Map.of("releaseVersion", Integer.valueOf(0))},
+                {Map.of("releaseVersion", Integer.valueOf(-1))}
+        };
+    }
+
     // Not the best test but all I can do since ZipFileSystem and JarFileSystem
     // are not public, so I can't use (fs instanceof ...)
     @Test
@@ -131,7 +145,7 @@
         try (FileSystem fs = FileSystems.newFileSystem(mruri, env)) {
             Assert.assertTrue(readAndCompare(fs, 8));
         }
-        env.put("multi-release", "runtime");
+        env.put("releaseVersion", "runtime");
         // a configuration and jar file is multi-release
         try (FileSystem fs = FileSystems.newFileSystem(mruri, env)) {
             Assert.assertTrue(readAndCompare(fs, MAJOR_VERSION));
@@ -150,30 +164,67 @@
 
     @Test(dataProvider="strings")
     public void testStrings(String value, int expected) throws Throwable {
+        stringEnv.put("releaseVersion", value);
+        runTest(stringEnv, expected);
+    }
+
+    @Test(dataProvider="integers")
+    public void testIntegers(Integer value, int expected) throws Throwable {
+        integerEnv.put("releaseVersion", value);
+        runTest(integerEnv, expected);
+    }
+
+    @Test(dataProvider="versions")
+    public void testVersions(Version value, int expected) throws Throwable {
+        versionEnv.put("releaseVersion", value);
+        runTest(versionEnv, expected);
+    }
+
+    @Test
+    public void testShortJar() throws Throwable {
+        integerEnv.put("releaseVersion", Integer.valueOf(MAJOR_VERSION));
+        runTest(smruri, integerEnv, MAJOR_VERSION);
+        integerEnv.put("releaseVersion", Integer.valueOf(9));
+        runTest(smruri, integerEnv, 8);
+    }
+
+    /**
+     * Validate that an invalid value for the "releaseVersion" property throws
+     * an {@code IllegalArgumentException}
+     * @param env Zip FS map
+     * @throws Throwable  Exception thrown for anything other than the expected
+     * IllegalArgumentException
+     */
+    @Test(dataProvider="invalidVersions")
+    public void testInvalidVersions(Map<String,?> env) throws Throwable {
+        Assert.assertThrows(IllegalArgumentException.class, () ->
+                FileSystems.newFileSystem(Path.of(userdir,
+                        "multi-release.jar"), env));
+    }
+
+    // The following tests are for backwards compatibility to validate that
+    // the original property still works
+    @Test(dataProvider="strings")
+    public void testMRStrings(String value, int expected) throws Throwable {
+        stringEnv.clear();
         stringEnv.put("multi-release", value);
         runTest(stringEnv, expected);
     }
 
     @Test(dataProvider="integers")
-    public void testIntegers(Integer value, int expected) throws Throwable {
+    public void testMRIntegers(Integer value, int expected) throws Throwable {
+        integerEnv.clear();
         integerEnv.put("multi-release", value);
         runTest(integerEnv, expected);
     }
 
     @Test(dataProvider="versions")
-    public void testVersions(Version value, int expected) throws Throwable {
+    public void testMRVersions(Version value, int expected) throws Throwable {
+        versionEnv.clear();
         versionEnv.put("multi-release", value);
         runTest(versionEnv, expected);
     }
 
-    @Test
-    public void testShortJar() throws Throwable {
-        integerEnv.put("multi-release", Integer.valueOf(MAJOR_VERSION));
-        runTest(smruri, integerEnv, MAJOR_VERSION);
-        integerEnv.put("multi-release", Integer.valueOf(9));
-        runTest(smruri, integerEnv, 8);
-    }
-
     private void runTest(Map<String,?> env, int expected) throws Throwable {
         runTest(mruri, env, expected);
     }
@@ -213,7 +264,7 @@
         JarBuilder jb = new JarBuilder(jfname);
         jb.addAttribute("Multi-Release", "true");
         jb.build();
-        Map<String,String> env = Map.of("multi-release", "runtime");
+        Map<String,String> env = Map.of("releaseVersion", "runtime");
         try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
             Assert.assertTrue(true);
         }
@@ -228,7 +279,7 @@
         creator.buildCustomMultiReleaseJar(fileName, value, Map.of(),
                 /*addEntries*/true);
 
-        Map<String,String> env = Map.of("multi-release", "runtime");
+        Map<String,String> env = Map.of("releaseVersion", "runtime");
         Path filePath = Paths.get(userdir, fileName);
         String ssp = filePath.toUri().toString();
         URI customJar = new URI("jar", ssp , null);
--- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/ComodoCA.java	Thu Oct 10 10:57:42 2019 -0400
@@ -23,7 +23,7 @@
 
  /*
  * @test
- * @bug 8189131
+ * @bug 8189131 8231887
  * @summary Interoperability tests with Comodo RSA, ECC, userTrust RSA, and
  *          userTrust ECC CAs
  * @build ValidatePathWithParams
@@ -112,13 +112,66 @@
 
     // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
     // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
+    // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB,
+    // SERIALNUMBER=04058690
+    // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Serial number: a0c7cabcc25ed9358ded02cc1d485545
+    // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIH0TCCBrmgAwIBAgIRAKDHyrzCXtk1je0CzB1IVUUwDQYJKoZIhvcNAQELBQAw\n" +
+            "gZIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" +
+            "BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYD\n" +
+            "VQQDEy9DT01PRE8gUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZl\n" +
+            "ciBDQTAeFw0xOTA5MzAwMDAwMDBaFw0yMTEyMjgyMzU5NTlaMIIBPjERMA8GA1UE\n" +
+            "BRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFByaXZh\n" +
+            "dGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VRMRAw\n" +
+            "DgYDVQQHEwdTYWxmb3JkMRYwFAYDVQQJEw1UcmFmZm9yZCBSb2FkMRYwFAYDVQQJ\n" +
+            "Ew1FeGNoYW5nZSBRdWF5MSUwIwYDVQQJExwzcmQgRmxvb3IsIDI2IE9mZmljZSBW\n" +
+            "aWxsYWdlMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxGjAYBgNVBAsTEUNPTU9E\n" +
+            "TyBFViBTR0MgU1NMMTgwNgYDVQQDEy9jb21vZG9yc2FjZXJ0aWZpY2F0aW9uYXV0\n" +
+            "aG9yaXR5LWV2LmNvbW9kb2NhLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\n" +
+            "AQoCggEBAND/eZQBTjpBDsuteKwl+zpTitF8tJzwHAhcQHC2AaLF/GJl1rnjx4Of\n" +
+            "elMhKhN1Od9KU6onHGOd2w4mD4EiYK9TpXwuwTyzfkCmnkqxZjYK3KAJN013o4L+\n" +
+            "8y1zsGVUulpN/GfMaxTb4XdmeSekTP91Phw3xezijBq3sa++1rO5RBaT1IHeHhHv\n" +
+            "iC9WNrG8CIg/j5MyC9i43LZHiRXLER1LzT/MCIRsiG5AEbiYXV5BNd5SiiHtBJ1q\n" +
+            "0ZJH+AxL2ERaT41VCppboZwThmJGGoky9FWjp6z8U6Enx0fAMJIZNEzW6LAJFKPE\n" +
+            "ynEU004jFFCEumPUqqCC4ogxulphY80CAwEAAaOCA3EwggNtMB8GA1UdIwQYMBaA\n" +
+            "FDna/8ooFIqodBMIueQOqdL6fp1pMB0GA1UdDgQWBBQ+S4ZhIrwOoeGs9BBT4uXq\n" +
+            "89Ux/jAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggr\n" +
+            "BgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA7BgwrBgEEAbIxAQIBBQEwKzAp\n" +
+            "BggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwBwYFZ4EM\n" +
+            "AQEwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09N\n" +
+            "T0RPUlNBRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGHBggr\n" +
+            "BgEFBQcBAQR7MHkwUQYIKwYBBQUHMAKGRWh0dHA6Ly9jcnQuY29tb2RvY2EuY29t\n" +
+            "L0NPTU9ET1JTQUV4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAk\n" +
+            "BggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMDoGA1UdEQQzMDGC\n" +
+            "L2NvbW9kb3JzYWNlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29t\n" +
+            "MIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdQDuS723dc5guuFCaR+r4Z5mow9+\n" +
+            "X7By2IMAxHuJeqj9ywAAAW2DAXefAAAEAwBGMEQCIDqP1einOiPHnaG1fOZMDrEc\n" +
+            "RAxjq3vEl94fp4pkmke7AiBsJOvPE6irgcOO1/lnP7NRuln7iPJjU7T20PEK5/rm\n" +
+            "KwB2AFWB1MIWkDYBSuoLm1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABbYMBd0kAAAQD\n" +
+            "AEcwRQIhALgUI5XxM1NHbJDdr19h2pe3LhzK4tpuB/OQ9BgCyrGXAiBdr6mNCB/G\n" +
+            "rbdVx0u7iezwC7mq7iaWugR3rrWlSA8fWQB2ALvZ37wfinG1k5Qjl6qSe0c4V5UK\n" +
+            "q1LoGpCWZDaOHtGFAAABbYMBd1oAAAQDAEcwRQIgXbG32dagMeLhuZb+LSpJO1vI\n" +
+            "BmxmRnNdiz5FbG9cCbwCIQCr1X9f+ebT5fhlDUNBURUorTtM8QQciBiueBqvHk7+\n" +
+            "1DANBgkqhkiG9w0BAQsFAAOCAQEAM/A/1dgoc5NP1n+w3SX9qWcN7QT7ExdrnZSl\n" +
+            "Ygn0PF2fx4gz7cvNKucbpQJNA4C9awGydyYK8/o5KDUXt3K7eb1OAZ/NZBjygsJs\n" +
+            "ikXvxlBh8oEoqBOfOtr24l0NGUWnP8Qeu/VPcIMER4V8qX+in0pCXkSd67nkp6Bs\n" +
+            "EcqhDPgmzdSC1gQHsZuBdotG14OfdH1cG1bRK6GadISLG1h8BFukVem42B149v8F\n" +
+            "MCIUQAYprAVv2WlTZKBx9XzuK6IK3+klHZ07Jfvjvt7PPG5HKSMWBMnMaTHKcyQI\n" +
+            "G3t91yw7BnNNInZlBSsFtqjbHhDcr7uruZdbi0rerSsi2qDr0w==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
+    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
     // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
     // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
     // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
     // ST=Greater Manchester, C=GB
     // Serial number: d3df2597cbed1ab6e02ee82021771614
     // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021
-    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
             "MIIH7jCCBtagAwIBAgIRANPfJZfL7Rq24C7oICF3FhQwDQYJKoZIhvcNAQELBQAw\n" +
             "gZIxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" +
             "BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMTgwNgYD\n" +
@@ -164,60 +217,6 @@
             "YrTYerPngjPbZB0bfLOja0vb\n" +
             "-----END CERTIFICATE-----";
 
-    // Owner: CN=comodorsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=COMODO CA Limited,
-    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
-    // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
-    // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
-    // Issuer: CN=COMODO RSA Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
-    // ST=Greater Manchester, C=GB
-    // Serial number: 720aa2cfa40094521224f901a984b167
-    // Valid from: Thu Jun 29 17:00:00 PDT 2017 until: Sun Sep 29 16:59:59 PDT 2019
-    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIH8jCCBtqgAwIBAgIQcgqiz6QAlFISJPkBqYSxZzANBgkqhkiG9w0BAQsFADCB\n" +
-            "kjELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" +
-            "A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNV\n" +
-            "BAMTL0NPTU9ETyBSU0EgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVy\n" +
-            "IENBMB4XDTE3MDYzMDAwMDAwMFoXDTE5MDkyOTIzNTk1OVowggFdMREwDwYDVQQF\n" +
-            "EwgwNDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0\n" +
-            "ZSBPcmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExGzAZ\n" +
-            "BgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEWMBQG\n" +
-            "A1UECRMNVHJhZmZvcmQgUm9hZDEWMBQGA1UECRMNRXhjaGFuZ2UgUXVheTElMCMG\n" +
-            "A1UECRMcM3JkIEZsb29yLCAyNiBPZmZpY2UgVmlsbGFnZTEaMBgGA1UEChMRQ09N\n" +
-            "T0RPIENBIExpbWl0ZWQxGjAYBgNVBAsTEUNPTU9ETyBFViBTR0MgU1NMMTgwNgYD\n" +
-            "VQQDEy9jb21vZG9yc2FjZXJ0aWZpY2F0aW9uYXV0aG9yaXR5LWV2LmNvbW9kb2Nh\n" +
-            "LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAND/eZQBTjpBDsut\n" +
-            "eKwl+zpTitF8tJzwHAhcQHC2AaLF/GJl1rnjx4OfelMhKhN1Od9KU6onHGOd2w4m\n" +
-            "D4EiYK9TpXwuwTyzfkCmnkqxZjYK3KAJN013o4L+8y1zsGVUulpN/GfMaxTb4Xdm\n" +
-            "eSekTP91Phw3xezijBq3sa++1rO5RBaT1IHeHhHviC9WNrG8CIg/j5MyC9i43LZH\n" +
-            "iRXLER1LzT/MCIRsiG5AEbiYXV5BNd5SiiHtBJ1q0ZJH+AxL2ERaT41VCppboZwT\n" +
-            "hmJGGoky9FWjp6z8U6Enx0fAMJIZNEzW6LAJFKPEynEU004jFFCEumPUqqCC4ogx\n" +
-            "ulphY80CAwEAAaOCA3QwggNwMB8GA1UdIwQYMBaAFDna/8ooFIqodBMIueQOqdL6\n" +
-            "fp1pMB0GA1UdDgQWBBQ+S4ZhIrwOoeGs9BBT4uXq89Ux/jAOBgNVHQ8BAf8EBAMC\n" +
-            "BaAwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw\n" +
-            "TwYDVR0gBEgwRjA7BgwrBgEEAbIxAQIBBQEwKzApBggrBgEFBQcCARYdaHR0cHM6\n" +
-            "Ly9zZWN1cmUuY29tb2RvLmNvbS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmg\n" +
-            "R4ZFaHR0cDovL2NybC5jb21vZG9jYS5jb20vQ09NT0RPUlNBRXh0ZW5kZWRWYWxp\n" +
-            "ZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGHBggrBgEFBQcBAQR7MHkwUQYIKwYB\n" +
-            "BQUHMAKGRWh0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JTQUV4dGVuZGVk\n" +
-            "VmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAkBggrBgEFBQcwAYYYaHR0cDov\n" +
-            "L29jc3AuY29tb2RvY2EuY29tMDoGA1UdEQQzMDGCL2NvbW9kb3JzYWNlcnRpZmlj\n" +
-            "YXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29tMIIBgAYKKwYBBAHWeQIEAgSC\n" +
-            "AXAEggFsAWoAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAVz5\n" +
-            "cV7GAAAEAwBHMEUCIQCpgc0Eqw3g4pr+oX88h5xgL1VEAiDpqAhbRtilgYwBbgIg\n" +
-            "UaIm+n8AHi55nB//Sb4Nz18GYVcfELfpIzRh1vW9HbYAdwBWFAaaL9fC7NP14b1E\n" +
-            "sj7HRna5vJkRXMDvlJhV1onQ3QAAAVz5cVybAAAEAwBIMEYCIQDdsgC4KZ++OP44\n" +
-            "X7LbUcNaxe0kFzbctF2L3bnmhp9nXQIhAM0/g+PrZBIBpYlOtzidePi8bBHrLWn2\n" +
-            "uBiP3pYIntl4AHcA7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFc\n" +
-            "+XFeoQAABAMASDBGAiEAoySTb/QKw7JwtZtPHnECEMzgENQSFy58Kl+Mvcd3SmcC\n" +
-            "IQD8cU66Ih3ejvt0OTX+lfxQPKyggQfm4Uk/lwn5LEJXbDANBgkqhkiG9w0BAQsF\n" +
-            "AAOCAQEAKEaSYWn3Hi8rfJS4cMTJoMkVp2vpPH2dGXySBEy67TEGRw9+f75w3q95\n" +
-            "r1m3P+xsR6dBoidTq/6wqUYI51lB4Fq9ylh1Stp5Gj54CuyT+S31l7lD7sl0KMsn\n" +
-            "HDUDQHId7hKeORYpiIZOcrKOglKdi1uiGwDgoiLKh98lUrZA6durrhH+sl69wqp2\n" +
-            "0XAu+3hurXzCoZFJfyngTO1kt9qcFUAxc5LofIa9QvC6VR7dI4aAh7dUpIRlnjG3\n" +
-            "jJ1mUMTqWO6TFTtddb+uQjDqNgkYYYNuSax1WMEIZWbIi13EjXK1GPQUXJe6gQin\n" +
-            "NUq9JH9NPK6m8A1YKT+wgzfTDeaV2Q==\n" +
-            "-----END CERTIFICATE-----";
-
     public void runTest(ValidatePathWithParams pathValidator) throws Exception {
         // Validate valid
         pathValidator.validate(new String[]{VALID, INT},
@@ -226,7 +225,7 @@
         // Validate Revoked
         pathValidator.validate(new String[]{REVOKED, INT},
                 ValidatePathWithParams.Status.REVOKED,
-                "Thu Nov 29 08:41:09 PST 2018", System.out);
+                "Wed Oct 02 06:06:24 PDT 2019", System.out);
     }
 }
 
@@ -263,13 +262,58 @@
 
     // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, OU=COMODO EV SSL, O=Sectigo Limited,
     // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
+    // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB,
+    // SERIALNUMBER=04058690
+    // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Serial number: 7972d9d8472a2d52ad1ee6edfb16cbe1
+    // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIGPzCCBeWgAwIBAgIQeXLZ2EcqLVKtHubt+xbL4TAKBggqhkjOPQQDAjCBkjEL\n" +
+            "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" +
+            "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\n" +
+            "L0NPTU9ETyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" +
+            "MB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggE6MREwDwYDVQQFEwgw\n" +
+            "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" +
+            "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEDAOBgNV\n" +
+            "BAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4\n" +
+            "Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxh\n" +
+            "Z2UxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEWMBQGA1UECxMNQ09NT0RPIEVW\n" +
+            "IFNTTDE4MDYGA1UEAxMvY29tb2RvZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1l\n" +
+            "di5jb21vZG9jYS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS3bqoFLtNG\n" +
+            "7/J9H5GKosDNbYL5SykVmU5FzgSEt81gyAWShkqMSfAnO50fpr65E+o86E+BR3o8\n" +
+            "V9FAU5wuOaGBo4IDcDCCA2wwHwYDVR0jBBgwFoAU007DGbpYWdEcYLdhU0c7p3eP\n" +
+            "+IowHQYDVR0OBBYEFOlnS3MqxwXDpne8IQMXMZHlVKRXMA4GA1UdDwEB/wQEAwIF\n" +
+            "gDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBP\n" +
+            "BgNVHSAESDBGMDsGDCsGAQQBsjEBAgEFATArMCkGCCsGAQUFBwIBFh1odHRwczov\n" +
+            "L3NlY3VyZS5jb21vZG8uY29tL0NQUzAHBgVngQwBATBWBgNVHR8ETzBNMEugSaBH\n" +
+            "hkVodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9FQ0NFeHRlbmRlZFZhbGlk\n" +
+            "YXRpb25TZWN1cmVTZXJ2ZXJDQS5jcmwwgYcGCCsGAQUFBwEBBHsweTBRBggrBgEF\n" +
+            "BQcwAoZFaHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPRUNDRXh0ZW5kZWRW\n" +
+            "YWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8v\n" +
+            "b2NzcC5jb21vZG9jYS5jb20wOgYDVR0RBDMwMYIvY29tb2RvZWNjY2VydGlmaWNh\n" +
+            "dGlvbmF1dGhvcml0eS1ldi5jb21vZG9jYS5jb20wggF8BgorBgEEAdZ5AgQCBIIB\n" +
+            "bASCAWgBZgB1AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAABbYME\n" +
+            "EzgAAAQDAEYwRAIgbdo71lBleuJiq+D0ZLp51oVUyWD9EyrtgBSCNwIW4cMCIAqg\n" +
+            "0VFTWHEmAVjaV23fGj3Ybu3mpSiHr6viGlgA2lYaAHUAVYHUwhaQNgFK6gubVzxT\n" +
+            "8MDkOHhwJQgXL6OqHQcT0wwAAAFtgwQTKAAABAMARjBEAiBb/gW1RU7kgFBiNpHx\n" +
+            "LStujKIocyENUTXsMbsac+LktwIgXbEr8vOOCEdBdXQ2F/FKec8ft6gz57mHNmwl\n" +
+            "pp7phbQAdgC72d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAW2DBBM6\n" +
+            "AAAEAwBHMEUCIQDjKN3h86ofR94+JxLFoYuoA+DRtxEY8XGg+NQXlZfUrgIgEoO2\n" +
+            "ZzKbGfohdwj/WtDwJDRX5pjXF4M0nECiwtYXDIwwCgYIKoZIzj0EAwIDSAAwRQIg\n" +
+            "AkIRVQBwrElFjrnqk5XPvnlnwkIm1A70ayqOf1FexoQCIQC8tBTn//RCfrhcgTjd\n" +
+            "ER4wRjFfFoc6lC68OHGVg9CZZg==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, OU=COMODO EV SSL, O=Sectigo Limited,
+    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
     // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
     // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
     // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
     // ST=Greater Manchester, C=GB
     // Serial number: 603a5c2f85b63e00ba46ce8c3f6000b0
     // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021
-    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
             "MIIGXzCCBgWgAwIBAgIQYDpcL4W2PgC6Rs6MP2AAsDAKBggqhkjOPQQDAjCBkjEL\n" +
             "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" +
             "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\n" +
@@ -307,52 +351,6 @@
             "KOC7\n" +
             "-----END CERTIFICATE-----";
 
-    // Owner: CN=comodoecccertificationauthority-ev.comodoca.com, OU=COMODO EV SSL, O=COMODO CA Limited,
-    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
-    // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
-    // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
-    // Issuer: CN=COMODO ECC Extended Validation Secure Server CA, O=COMODO CA Limited, L=Salford,
-    // ST=Greater Manchester, C=GB
-    // Serial number: 414e5d66ec7d15ca504213f2811d57af
-    // Valid from: Mon Jul 03 17:00:00 PDT 2017 until: Thu Oct 03 16:59:59 PDT 2019
-    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIGYDCCBgWgAwIBAgIQQU5dZux9FcpQQhPygR1XrzAKBggqhkjOPQQDAjCBkjEL\n" +
-            "MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE\n" +
-            "BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxODA2BgNVBAMT\n" +
-            "L0NPTU9ETyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" +
-            "MB4XDTE3MDcwNDAwMDAwMFoXDTE5MTAwMzIzNTk1OVowggFZMREwDwYDVQQFEwgw\n" +
-            "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" +
-            "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExGzAZBgNV\n" +
-            "BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEWMBQGA1UE\n" +
-            "CRMNVHJhZmZvcmQgUm9hZDEWMBQGA1UECRMNRXhjaGFuZ2UgUXVheTElMCMGA1UE\n" +
-            "CRMcM3JkIEZsb29yLCAyNiBPZmZpY2UgVmlsbGFnZTEaMBgGA1UEChMRQ09NT0RP\n" +
-            "IENBIExpbWl0ZWQxFjAUBgNVBAsTDUNPTU9ETyBFViBTU0wxODA2BgNVBAMTL2Nv\n" +
-            "bW9kb2VjY2NlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29tMFkw\n" +
-            "EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEt26qBS7TRu/yfR+RiqLAzW2C+UspFZlO\n" +
-            "Rc4EhLfNYMgFkoZKjEnwJzudH6a+uRPqPOhPgUd6PFfRQFOcLjmhgaOCA3EwggNt\n" +
-            "MB8GA1UdIwQYMBaAFNNOwxm6WFnRHGC3YVNHO6d3j/iKMB0GA1UdDgQWBBTpZ0tz\n" +
-            "KscFw6Z3vCEDFzGR5VSkVzAOBgNVHQ8BAf8EBAMCBYAwDAYDVR0TAQH/BAIwADAd\n" +
-            "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwTwYDVR0gBEgwRjA7BgwrBgEE\n" +
-            "AbIxAQIBBQEwKzApBggrBgEFBQcCARYdaHR0cHM6Ly9zZWN1cmUuY29tb2RvLmNv\n" +
-            "bS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5jb21v\n" +
-            "ZG9jYS5jb20vQ09NT0RPRUNDRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVy\n" +
-            "Q0EuY3JsMIGHBggrBgEFBQcBAQR7MHkwUQYIKwYBBQUHMAKGRWh0dHA6Ly9jcnQu\n" +
-            "Y29tb2RvY2EuY29tL0NPTU9ET0VDQ0V4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNl\n" +
-            "cnZlckNBLmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29t\n" +
-            "MDoGA1UdEQQzMDGCL2NvbW9kb2VjY2NlcnRpZmljYXRpb25hdXRob3JpdHktZXYu\n" +
-            "Y29tb2RvY2EuY29tMIIBfQYKKwYBBAHWeQIEAgSCAW0EggFpAWcAdgCkuQmQtBhY\n" +
-            "FIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAV0NLqsqAAAEAwBHMEUCIAz9Jjq3\n" +
-            "qLUd/a2PYZnLGsEG/MrL7vab5rmGBg8RGAJxAiEA7JJnar07NIjCLLO77xJ3UFcu\n" +
-            "UMM3M8JgGC8wbuRwxbUAdgBWFAaaL9fC7NP14b1Esj7HRna5vJkRXMDvlJhV1onQ\n" +
-            "3QAAAV0NLqjmAAAEAwBHMEUCIHRvPWKr7vPMBWx1gLPkt8inPINWPNSoax178e5A\n" +
-            "D0cPAiEAvRL/VP4DLiyHvcU9AOqTzQXGuWCzswWKG59hSm7gS4kAdQDuS723dc5g\n" +
-            "uuFCaR+r4Z5mow9+X7By2IMAxHuJeqj9ywAAAV0NLqsDAAAEAwBGMEQCIFALT043\n" +
-            "X5IffLsxIAGXTrWgkZHf12QKgrYKXVB629eOAiAIeci2xi3fUW6mU8tT4LwyjowV\n" +
-            "DkrSCw1ZMo0JApsfzTAKBggqhkjOPQQDAgNJADBGAiEA7HUxjwx0MBC+4PuPx4Z1\n" +
-            "WpKz7jdHOMTh1sdaoVV5hNoCIQDrnjBFUopXHTvm/rj+aMFIeYejggPqv14KJOqT\n" +
-            "gym+uA==\n" +
-            "-----END CERTIFICATE-----";
-
     public void runTest(ValidatePathWithParams pathValidator) throws Exception {
         // Validate valid
         pathValidator.validate(new String[]{VALID, INT},
@@ -361,19 +359,61 @@
         // Validate Revoked
         pathValidator.validate(new String[]{REVOKED, INT},
                 ValidatePathWithParams.Status.REVOKED,
-                "Thu Nov 29 08:12:02 PST 2018", System.out);
+                "Wed Oct 02 06:05:57 PDT 2019", System.out);
     }
 }
 
 class ComodoUserTrustRSA {
 
+    // Owner: CN=Sectigo RSA Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Issuer: CN=USERTrust RSA Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US
+    // Serial number: 284e39c14b386d889c7299e58cd05a57
+    // Valid from: Thu Nov 01 17:00:00 PDT 2018 until: Tue Dec 31 15:59:59 PST 2030
+    private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIGNDCCBBygAwIBAgIQKE45wUs4bYiccpnljNBaVzANBgkqhkiG9w0BAQwFADCB\n" +
+            "iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n" +
+            "cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n" +
+            "BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTgx\n" +
+            "MTAyMDAwMDAwWhcNMzAxMjMxMjM1OTU5WjCBkTELMAkGA1UEBhMCR0IxGzAZBgNV\n" +
+            "BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE\n" +
+            "ChMPU2VjdGlnbyBMaW1pdGVkMTkwNwYDVQQDEzBTZWN0aWdvIFJTQSBFeHRlbmRl\n" +
+            "ZCBWYWxpZGF0aW9uIFNlY3VyZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUA\n" +
+            "A4IBDwAwggEKAoIBAQCaoslYBiqFev0Yc4TXPa0s9oliMcn9VaENfTUK4GVT7niB\n" +
+            "QXxC6Mt8kTtvyr5lU92hDQDh2WDPQsZ7oibh75t2kowT3z1S+Sy1GsUDM4NbdOde\n" +
+            "orcmzFm/b4bwD4G/G+pB4EX1HSfjN9eT0Hje+AGvCrd2MmnxJ+Yymv9BH9OB65jK\n" +
+            "rUO9Na4iHr48XWBDFvzsPCJ11Uioof6dRBVp+Lauj88Z7k2X8d606HeXn43h6acp\n" +
+            "LLURWyqXM0CrzedVWBzuXKuBEaqD6w/1VpLJvSU+wl3ScvXSLFp82DSRJVJONXWl\n" +
+            "dp9gjJioPGRByeZw11k3galbbF5gFK9xSnbDx29LAgMBAAGjggGNMIIBiTAfBgNV\n" +
+            "HSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQULGn/gMmHkK40\n" +
+            "4bTnTJOFmUDpp7IwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAw\n" +
+            "HQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMDoGA1UdIAQzMDEwLwYEVR0g\n" +
+            "ADAnMCUGCCsGAQUFBwIBFhlodHRwczovL2Nwcy51c2VydHJ1c3QuY29tMFAGA1Ud\n" +
+            "HwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RS\n" +
+            "U0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDB2BggrBgEFBQcBAQRqMGgwPwYI\n" +
+            "KwYBBQUHMAKGM2h0dHA6Ly9jcnQudXNlcnRydXN0LmNvbS9VU0VSVHJ1c3RSU0FB\n" +
+            "ZGRUcnVzdENBLmNydDAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0\n" +
+            "LmNvbTANBgkqhkiG9w0BAQwFAAOCAgEAQ4AzPxVypLyy3IjUUmVl7FaxrHsXQq2z\n" +
+            "Zt2gKnHQShuA+5xpRPNndjvhHk4D08PZXUe6Im7E5knqxtyl5aYdldb+HI/7f+zd\n" +
+            "W/1ub2N4Vq4ZYUjcZ1ECOFK7Z2zoNicDmU+Fe/TreXPuPsDicTG/tMcWEVM558OQ\n" +
+            "TJkB2LK3ZhGukWM/RTMRcRdXaXOX8Lh0ylzRO1O0ObXytvOFpkkkD92HGsfS06i7\n" +
+            "NLDPJEeZXqzHE5Tqj7VSAj+2luwfaXaPLD8lQEVci8xmsPGOn0mXE1ZzsChEPhVq\n" +
+            "FYQUsbiRJRhidKauhd+G2CkRTcR5fpsuz+iStB9s5Fks9lKoXnn0hv78VYjvR78C\n" +
+            "Cvj5FW/ounHjWTWMb3il9S5ngbFGcelB1l/MQkR63+1ybdi2OpjNWJCftxOWUpkC\n" +
+            "xaRdnOnSj7GQY0NLn8Gtq9FcSZydtkVgXpouSFZkXNS/MYwbcCCcRKBbrk8ss0SI\n" +
+            "Xg1gTURjh9VP1OHm0OktYcUw9e90wHIDn7h0qA+bWOsZquSRzT4s2crF3ZSA3tuV\n" +
+            "/UJ33mjdVO8wBD8aI5y10QreSPJvZHHNDyCmoyjXvNhR+u3arXUoHWxO+MZBeXbi\n" +
+            "iF7Nwn/IEmQvWBW8l6D26CXIavcY1kAJcfyzHkrPbLo+fAOa/KFl3lIU+0biEVNk\n" +
+            "Q9zXE6hC6X4=\n" +
+            "-----END CERTIFICATE-----";
+
     // Owner: CN=USERTrust RSA Extended Validation Secure Server CA,
     // O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US
     // Issuer: CN=USERTrust RSA Certification Authority, O=The USERTRUST Network,
     // L=Jersey City, ST=New Jersey, C=US
     // Serial number: f6bb751efa7d2e8368e606407334f83
     // Valid from: Sat Feb 11 16:00:00 PST 2012 until: Thu Feb 11 15:59:59 PST 2027
-    private static final String INT = "-----BEGIN CERTIFICATE-----\n"
+    private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n"
             + "MIIGGTCCBAGgAwIBAgIQD2u3Ue+n0ug2jmBkBzNPgzANBgkqhkiG9w0BAQwFADCB\n"
             + "iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl\n"
             + "cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV\n"
@@ -409,15 +449,69 @@
             + "4fokbdNREXoShKClNIPbB5iY+WdSzb9CKLyb96g=\n"
             + "-----END CERTIFICATE-----";
 
-    // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL,
-    // O=Sectigo Limited, STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road,
-    // L=Salford, ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
+    // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
+    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford, ST=Manchester,
+    // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB,
+    // SERIALNUMBER=04058690
+    // Issuer: CN=Sectigo RSA Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Serial number: b07fd164b5790c9d5d1fddff5819cdb2
+    // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIH5TCCBs2gAwIBAgIRALB/0WS1eQydXR/d/1gZzbIwDQYJKoZIhvcNAQELBQAw\n" +
+            "gZExCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" +
+            "BgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE5MDcGA1UE\n" +
+            "AxMwU2VjdGlnbyBSU0EgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVy\n" +
+            "IENBMB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggFWMREwDwYDVQQF\n" +
+            "EwgwNDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0\n" +
+            "ZSBPcmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEzAR\n" +
+            "BgNVBAgTCk1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRy\n" +
+            "YWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNy\n" +
+            "ZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGDAWBgNVBAoTD1NlY3RpZ28gTGlt\n" +
+            "aXRlZDEaMBgGA1UECxMRQ09NT0RPIEVWIFNHQyBTU0wxOzA5BgNVBAMTMnVzZXJ0\n" +
+            "cnVzdHJzYWNlcnRpZmljYXRpb25hdXRob3JpdHktZXYuY29tb2RvY2EuY29tMIIB\n" +
+            "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnh/rxeiYwpLa651eLvGnR+RE\n" +
+            "rhDWkTZtqZcHw9Oy7JL2uELyEPbM+v0az40cBHS0bQZJZbWmXNukMUMSwIb4z7t8\n" +
+            "OXlxz9uvxEufvlqBl4qeC/z3LpFBRRHEero3yGKVwkoe1aP2Pq7Udi+7i7eVZZdA\n" +
+            "1ticxZWo/UBU9mwbIOYqf/4xzZ6G891hKb+NAuuEfxG52vXZl8odMThfHuDlkfS7\n" +
+            "nZMQBaO40KJeSEBhr+5TIS7d7tWWye/F6oEQ0+dHBiF9PyZ1dXoO8aue/80mP+0F\n" +
+            "MYTmRFsKHge6ZjojfH9cLlR5kTqtP5Tqh5GBQ4zp3uyIBBU6ylKp9PNHkewGUQID\n" +
+            "AQABo4IDbjCCA2owHwYDVR0jBBgwFoAULGn/gMmHkK404bTnTJOFmUDpp7IwHQYD\n" +
+            "VR0OBBYEFHz7cvDn1LYe2M+z4plwQn7rt938MA4GA1UdDwEB/wQEAwIFoDAMBgNV\n" +
+            "HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBJBgNVHSAE\n" +
+            "QjBAMDUGDCsGAQQBsjEBAgEFATAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3Rp\n" +
+            "Z28uY29tL0NQUzAHBgVngQwBATBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3Js\n" +
+            "LnNlY3RpZ28uY29tL1NlY3RpZ29SU0FFeHRlbmRlZFZhbGlkYXRpb25TZWN1cmVT\n" +
+            "ZXJ2ZXJDQS5jcmwwgYYGCCsGAQUFBwEBBHoweDBRBggrBgEFBQcwAoZFaHR0cDov\n" +
+            "L2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNBRXh0ZW5kZWRWYWxpZGF0aW9uU2Vj\n" +
+            "dXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdv\n" +
+            "LmNvbTA9BgNVHREENjA0gjJ1c2VydHJ1c3Ryc2FjZXJ0aWZpY2F0aW9uYXV0aG9y\n" +
+            "aXR5LWV2LmNvbW9kb2NhLmNvbTCCAX4GCisGAQQB1nkCBAIEggFuBIIBagFoAHYA\n" +
+            "7ku9t3XOYLrhQmkfq+GeZqMPfl+wctiDAMR7iXqo/csAAAFtgzv54wAABAMARzBF\n" +
+            "AiB5PmhsK3zU3XdKvyxw/wWHMmLI7apHLa1yKdjkA8H+ggIhALdUx7Tl8aeWhK6z\n" +
+            "lh+PHvMAdCcAJK6w9qBJGQtSrYO5AHUAVYHUwhaQNgFK6gubVzxT8MDkOHhwJQgX\n" +
+            "L6OqHQcT0wwAAAFtgzv5zgAABAMARjBEAiBumSwAUamibqJXTN2cf/H3mjd0T35/\n" +
+            "UK9w2hu9gFobxgIgSXTLndHyqFUmcmquu3It0WC1yl6YMceGixbQL1e8BQcAdwC7\n" +
+            "2d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQlmQ2jh7RhQAAAW2DO/nXAAAEAwBIMEYC\n" +
+            "IQDHRs10oYoXE5yq6WsiksjdQsUWZNpbSsrmz0u+KlxTVQIhAJ4rvHItKSeJLkaN\n" +
+            "S3YpVZnkN8tOwuxPsYeyVx/BtaNpMA0GCSqGSIb3DQEBCwUAA4IBAQAPFIsUFymo\n" +
+            "VTp0vntHrZpBApBQzDeriQv7Bi7tmou/Ng47RtXW3DjGdrePGSfOdl7h62k8qprU\n" +
+            "JeLyloDqhvmT/CG/hdwrfZ3Sv3N2xpetGcnW5S3oEi3m+/M1ls9eD+x1vybqV9Kd\n" +
+            "lcjuV7SYDlbvAS9w7TcygudhdW0cI8XTCvesGKohBkAlqaQ/MWYpt4WvsxHjbWgn\n" +
+            "5ZlIYR6A1ZFEjADifViH/5AA79lgGhAskkIWPjvRFalEVKTKtjhRK76eCfZs4Frr\n" +
+            "CEOpon+BeNKk+x/K/r10dSoWe0SV2uGVxTD83zkP++eREwo1hTgn8bXn7ftlnA3j\n" +
+            "7ml+Usz6udaD\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
+    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
+    // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
     // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
     // Issuer: CN=USERTrust RSA Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City,
     // ST=New Jersey, C=US
     // Serial number: d3c204e8df6a1539568cf15e97e57b1d
     // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021
-    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
             "MIIIADCCBuigAwIBAgIRANPCBOjfahU5VozxXpflex0wDQYJKoZIhvcNAQELBQAw\n" +
             "gZUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtK\n" +
             "ZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYD\n" +
@@ -463,81 +557,56 @@
             "3Ld31zbQaywKdpCsT74/hEBMfcDiP02mmtyrlqHD4R3tdYne\n" +
             "-----END CERTIFICATE-----";
 
-    // Owner: CN=usertrustrsacertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=COMODO CA Limited,
-    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
-    // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
-    // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
-    // Issuer: CN=USERTrust RSA Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City,
-    // ST=New Jersey, C=US
-    // Serial number: ffcada019c9fb1155a32300083cb99c9
-    // Valid from: Mon Jul 03 17:00:00 PDT 2017 until: Thu Oct 03 16:59:59 PDT 2019
-    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIIATCCBumgAwIBAgIRAP/K2gGcn7EVWjIwAIPLmckwDQYJKoZIhvcNAQELBQAw\n" +
-            "gZUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtK\n" +
-            "ZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYD\n" +
-            "VQQDEzJVU0VSVHJ1c3QgUlNBIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNl\n" +
-            "cnZlciBDQTAeFw0xNzA3MDQwMDAwMDBaFw0xOTEwMDMyMzU5NTlaMIIBYDERMA8G\n" +
-            "A1UEBRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFBy\n" +
-            "aXZhdGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VR\n" +
-            "MRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQx\n" +
-            "FjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkx\n" +
-            "JTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGjAYBgNVBAoT\n" +
-            "EUNPTU9ETyBDQSBMaW1pdGVkMRowGAYDVQQLExFDT01PRE8gRVYgU0dDIFNTTDE7\n" +
-            "MDkGA1UEAxMydXNlcnRydXN0cnNhY2VydGlmaWNhdGlvbmF1dGhvcml0eS1ldi5j\n" +
-            "b21vZG9jYS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCeH+vF\n" +
-            "6JjCktrrnV4u8adH5ESuENaRNm2plwfD07Lskva4QvIQ9sz6/RrPjRwEdLRtBkll\n" +
-            "taZc26QxQxLAhvjPu3w5eXHP26/ES5++WoGXip4L/PcukUFFEcR6ujfIYpXCSh7V\n" +
-            "o/Y+rtR2L7uLt5Vll0DW2JzFlaj9QFT2bBsg5ip//jHNnobz3WEpv40C64R/Ebna\n" +
-            "9dmXyh0xOF8e4OWR9LudkxAFo7jQol5IQGGv7lMhLt3u1ZbJ78XqgRDT50cGIX0/\n" +
-            "JnV1eg7xq57/zSY/7QUxhOZEWwoeB7pmOiN8f1wuVHmROq0/lOqHkYFDjOne7IgE\n" +
-            "FTrKUqn080eR7AZRAgMBAAGjggN8MIIDeDAfBgNVHSMEGDAWgBQvgU/iZvq8aL+Z\n" +
-            "Q4RSiSA6gvOkpTAdBgNVHQ4EFgQUfPty8OfUth7Yz7PimXBCfuu33fwwDgYDVR0P\n" +
-            "AQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsG\n" +
-            "AQUFBwMCMEsGA1UdIAREMEIwNwYMKwYBBAGyMQECAQUBMCcwJQYIKwYBBQUHAgEW\n" +
-            "GWh0dHBzOi8vY3BzLnVzZXJ0cnVzdC5jb20wBwYFZ4EMAQEwWgYDVR0fBFMwUTBP\n" +
-            "oE2gS4ZJaHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdFJTQUV4dGVu\n" +
-            "ZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNybDCBjQYIKwYBBQUHAQEEgYAw\n" +
-            "fjBVBggrBgEFBQcwAoZJaHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVz\n" +
-            "dFJTQUV4dGVuZGVkVmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAlBggrBgEF\n" +
-            "BQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTA9BgNVHREENjA0gjJ1c2Vy\n" +
-            "dHJ1c3Ryc2FjZXJ0aWZpY2F0aW9uYXV0aG9yaXR5LWV2LmNvbW9kb2NhLmNvbTCC\n" +
-            "AX8GCisGAQQB1nkCBAIEggFvBIIBawFpAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5\n" +
-            "G9+443fNDsgN3BAAAAFdDU2iYQAABAMARzBFAiB0o4GnVHD8MeVQ32D0XYu+EQQW\n" +
-            "jvN78rmCfk0OEBxyFAIhAKgyctIn0IaDJiZzsrtAiqEnkcMtuh8o+R0Rqw1ygAjk\n" +
-            "AHcAVhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFdDU2gFgAABAMA\n" +
-            "SDBGAiEA7mcmZ8H5uHuNCdI0CVxsqDZQcZX/gVk94KckePkzQoACIQCHwm5hcvNC\n" +
-            "M8vNmFkboQN79DglRctHrlh143A6mUTk8QB2AO5Lvbd1zmC64UJpH6vhnmajD35f\n" +
-            "sHLYgwDEe4l6qP3LAAABXQ1NojoAAAQDAEcwRQIhAPqwijgE0Fr6uJ+yF+TvyXco\n" +
-            "Hduv9h7R5WWwJfghXiMyAiBB4+fJm4rIcOnJBZmOqFnRpIjPN0jwDqJT0nDHxaXA\n" +
-            "nDANBgkqhkiG9w0BAQsFAAOCAQEACXitF1bTEvV1HX11WrT/XuoMhsoPK4TS16rs\n" +
-            "FqztV4iXKlA1/h5qbsjYY1gVrM+/6kQkmEs5qrxsek2WNxY80NO3WAzroRJ3H9Sd\n" +
-            "mPn0No2P8LZ5Fs5hvaD/PfWO5xxey80c3kGyvWOej90P3IrL/1RiULyh95TrXBjI\n" +
-            "ddCBsZ28904wsQUrPBPMpiu0DKl1HR/em9WkcipMi+onJxxFWjucssz5PW/BzGYF\n" +
-            "jfWLDEI0tN5L4CWV3iVXFXOURY1Mwhtsey9jvlEyxSsys55QdKF40yGgtV9VC+os\n" +
-            "7hJP33+qA0cvCTaRytiPP6z/l2G/KSIXTyv6SxzGhsTFfzLAOg==\n" +
-            "-----END CERTIFICATE-----";
-
     public void runTest(ValidatePathWithParams pathValidator) throws Exception {
         // Validate valid
-        pathValidator.validate(new String[]{VALID, INT},
+        pathValidator.validate(new String[]{VALID, INT_VALID},
                 ValidatePathWithParams.Status.GOOD, null, System.out);
 
         // Validate Revoked
-        pathValidator.validate(new String[]{REVOKED, INT},
+        pathValidator.validate(new String[]{REVOKED, INT_REVOKED},
                 ValidatePathWithParams.Status.REVOKED,
-                "Thu Nov 29 10:58:13 PST 2018", System.out);
+                "Wed Oct 02 06:07:12 PDT 2019", System.out);
     }
 }
 
 class ComodoUserTrustECC {
 
+    // Owner: CN=Sectigo ECC Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Issuer: CN=USERTrust ECC Certification Authority, O=The USERTRUST Network, L=Jersey City, ST=New Jersey, C=US
+    // Serial number: 80f5606d3a162b143adc12fbe8c2066f
+    // Valid from: Thu Nov 01 17:00:00 PDT 2018 until: Tue Dec 31 15:59:59 PST 2030
+    private static final String INT_VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIDyTCCA0+gAwIBAgIRAID1YG06FisUOtwS++jCBm8wCgYIKoZIzj0EAwMwgYgx\n" +
+            "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz\n" +
+            "ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQD\n" +
+            "EyVVU0VSVHJ1c3QgRUNDIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MTEw\n" +
+            "MjAwMDAwMFoXDTMwMTIzMTIzNTk1OVowgZExCzAJBgNVBAYTAkdCMRswGQYDVQQI\n" +
+            "ExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoT\n" +
+            "D1NlY3RpZ28gTGltaXRlZDE5MDcGA1UEAxMwU2VjdGlnbyBFQ0MgRXh0ZW5kZWQg\n" +
+            "VmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENBMFkwEwYHKoZIzj0CAQYIKoZIzj0D\n" +
+            "AQcDQgAEAyJ5Ca9JyXq8bO+krLVWysbtm7fdMSJ54uFD23t0x6JAC4IjxevfQJzW\n" +
+            "z4T6yY+FybTBqtOa++ijJFnkB5wKy6OCAY0wggGJMB8GA1UdIwQYMBaAFDrhCYbU\n" +
+            "zxnClnZ0SXbc4DXGY2OaMB0GA1UdDgQWBBTvwSqVDDLa+3Mw3IoT2BVL9xPo+DAO\n" +
+            "BgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggr\n" +
+            "BgEFBQcDAQYIKwYBBQUHAwIwOgYDVR0gBDMwMTAvBgRVHSAAMCcwJQYIKwYBBQUH\n" +
+            "AgEWGWh0dHBzOi8vY3BzLnVzZXJ0cnVzdC5jb20wUAYDVR0fBEkwRzBFoEOgQYY/\n" +
+            "aHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVDQ0NlcnRpZmljYXRp\n" +
+            "b25BdXRob3JpdHkuY3JsMHYGCCsGAQUFBwEBBGowaDA/BggrBgEFBQcwAoYzaHR0\n" +
+            "cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdEVDQ0FkZFRydXN0Q0EuY3J0\n" +
+            "MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMAoGCCqGSM49\n" +
+            "BAMDA2gAMGUCMQCjHztBDL90GCRXHlGqm0H7kzP04hd0MxwakKjWzOmstXNFLONj\n" +
+            "RFa0JqI/iKUJMFcCMCbLgyzcFW7DihtY5XE0XCLCw+git0NjxiFB6FaOFIlyDdqT\n" +
+            "j+Th+DJ92JLvICVD/g==\n" +
+            "-----END CERTIFICATE-----";
+
     // Owner: CN=USERTrust ECC Extended Validation Secure Server CA, O=The USERTRUST Network,
     // L=Jersey City, ST=New Jersey, C=US
     // Issuer: CN=USERTrust ECC Certification Authority, O=The USERTRUST Network,
     // L=Jersey City, ST=New Jersey, C=US
     // Serial number: 3d09b24f5c08a7ce8eb85a51d3c1aa52
     // Valid from: Sun Apr 14 17:00:00 PDT 2013 until: Fri Apr 14 16:59:59 PDT 2028
-    private static final String INT = "-----BEGIN CERTIFICATE-----\n"
+    private static final String INT_REVOKED = "-----BEGIN CERTIFICATE-----\n"
             + "MIIDwTCCA0igAwIBAgIQPQmyT1wIp86OuFpR08GqUjAKBggqhkjOPQQDAzCBiDEL\n"
             + "MAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNl\n"
             + "eSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMT\n"
@@ -563,13 +632,58 @@
 
     // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
     // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
+    // OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization, OID.1.3.6.1.4.1.311.60.2.1.3=GB,
+    // SERIALNUMBER=04058690
+    // Issuer: CN=Sectigo ECC Extended Validation Secure Server CA, O=Sectigo Limited, L=Salford,
+    // ST=Greater Manchester, C=GB
+    // Serial number: 8b72489b7f505a55e2a22659c90ed2ab
+    // Valid from: Sun Sep 29 17:00:00 PDT 2019 until: Tue Dec 28 15:59:59 PST 2021
+    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+            "MIIGRTCCBeugAwIBAgIRAItySJt/UFpV4qImWckO0qswCgYIKoZIzj0EAwIwgZEx\n" +
+            "CzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNV\n" +
+            "BAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDE5MDcGA1UEAxMw\n" +
+            "U2VjdGlnbyBFQ0MgRXh0ZW5kZWQgVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\n" +
+            "MB4XDTE5MDkzMDAwMDAwMFoXDTIxMTIyODIzNTk1OVowggFBMREwDwYDVQQFEwgw\n" +
+            "NDA1ODY5MDETMBEGCysGAQQBgjc8AgEDEwJHQjEdMBsGA1UEDxMUUHJpdmF0ZSBP\n" +
+            "cmdhbml6YXRpb24xCzAJBgNVBAYTAkdCMQ8wDQYDVQQREwZNNSAzRVExEDAOBgNV\n" +
+            "BAcTB1NhbGZvcmQxFjAUBgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4\n" +
+            "Y2hhbmdlIFF1YXkxJTAjBgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxh\n" +
+            "Z2UxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEaMBgGA1UECxMRQ09NT0RPIEVW\n" +
+            "IFNHQyBTU0wxOzA5BgNVBAMTMnVzZXJ0cnVzdGVjY2NlcnRpZmljYXRpb25hdXRo\n" +
+            "b3JpdHktZXYuY29tb2RvY2EuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE\n" +
+            "LTJfEd92Wlg+h/AVtPsMmwX9Puvi+WGCv3sgFRpur8Iy2kGVpXHRQTCn2j9aky4t\n" +
+            "FQGm7OG2klJA/MEeevKVaaOCA28wggNrMB8GA1UdIwQYMBaAFO/BKpUMMtr7czDc\n" +
+            "ihPYFUv3E+j4MB0GA1UdDgQWBBSzrWHzmiHwx2Rrm7SjRC0UegNrKzAOBgNVHQ8B\n" +
+            "Af8EBAMCB4AwDAYDVR0TAQH/BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYB\n" +
+            "BQUHAwIwSQYDVR0gBEIwQDA1BgwrBgEEAbIxAQIBBQEwJTAjBggrBgEFBQcCARYX\n" +
+            "aHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwBwYFZ4EMAQEwVgYDVR0fBE8wTTBLoEmg\n" +
+            "R4ZFaHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvRUNDRXh0ZW5kZWRWYWxp\n" +
+            "ZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGGBggrBgEFBQcBAQR6MHgwUQYIKwYB\n" +
+            "BQUHMAKGRWh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb0VDQ0V4dGVuZGVk\n" +
+            "VmFsaWRhdGlvblNlY3VyZVNlcnZlckNBLmNydDAjBggrBgEFBQcwAYYXaHR0cDov\n" +
+            "L29jc3Auc2VjdGlnby5jb20wPQYDVR0RBDYwNIIydXNlcnRydXN0ZWNjY2VydGlm\n" +
+            "aWNhdGlvbmF1dGhvcml0eS1ldi5jb21vZG9jYS5jb20wggF/BgorBgEEAdZ5AgQC\n" +
+            "BIIBbwSCAWsBaQB2AO5Lvbd1zmC64UJpH6vhnmajD35fsHLYgwDEe4l6qP3LAAAB\n" +
+            "bYL/SJoAAAQDAEcwRQIhAL7EJt/Rgz6NBnx2v8Hevux3Gpcxy64kaeyLVgFeNqFk\n" +
+            "AiBRf+OWLOtZzEav/oERljrk8hgZB4CR1nj/Tn98cmRrwwB2AFWB1MIWkDYBSuoL\n" +
+            "m1c8U/DA5Dh4cCUIFy+jqh0HE9MMAAABbYL/SIgAAAQDAEcwRQIgVtZZaiBMC2lu\n" +
+            "atBzUHQmOq4qrUQP7nS83cd3VzPhToECIQDnlpOCdaxJwr8C0MtkvYpKSabwBPFL\n" +
+            "ASEkwmOpjuQErAB3ALvZ37wfinG1k5Qjl6qSe0c4V5UKq1LoGpCWZDaOHtGFAAAB\n" +
+            "bYL/SJoAAAQDAEgwRgIhAI8OgzP/kzF1bOJRHU2S/ewij/6HpGPy7Mbm7Hyuv3IU\n" +
+            "AiEAxDmX2FmORlgeerQmQ+ar3D9/TwA9RQckVDu5IrgweREwCgYIKoZIzj0EAwID\n" +
+            "SAAwRQIhAPwQWGWd3oR7YJ7ngCDQ9TAbdPgND51SiR34WfEgaTQtAiAxD4umKm02\n" +
+            "59GEMj5NpyF2ZQEq5mEGcjJNojrn+PC4zg==\n" +
+            "-----END CERTIFICATE-----";
+
+    // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=Sectigo Limited,
+    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
     // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
     // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
     // Issuer: CN=USERTrust ECC Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City,
     // ST=New Jersey, C=US
     // Serial number: ab1455f9833ae7783f95de8744181f6a
     // Valid from: Wed Nov 28 16:00:00 PST 2018 until: Fri Feb 26 15:59:59 PST 2021
-    private static final String VALID = "-----BEGIN CERTIFICATE-----\n" +
+    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
             "MIIGhjCCBiygAwIBAgIRAKsUVfmDOud4P5Xeh0QYH2owCgYIKoZIzj0EAwIwgZUx\n" +
             "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz\n" +
             "ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYDVQQD\n" +
@@ -607,60 +721,14 @@
             "11EPtBSCEhUCIBcyI0yl5dRff6+4x8IeCrLiAOYsfzM7Y/a5uRKFnbYz\n" +
             "-----END CERTIFICATE-----";
 
-    // Owner: CN=usertrustecccertificationauthority-ev.comodoca.com, OU=COMODO EV SGC SSL, O=COMODO CA Limited,
-    // STREET="3rd Floor, 26 Office Village", STREET=Exchange Quay, STREET=Trafford Road, L=Salford,
-    // ST=Greater Manchester, OID.2.5.4.17=M5 3EQ, C=GB, OID.2.5.4.15=Private Organization,
-    // OID.1.3.6.1.4.1.311.60.2.1.3=GB, SERIALNUMBER=04058690
-    // Issuer: CN=USERTrust ECC Extended Validation Secure Server CA, O=The USERTRUST Network, L=Jersey City,
-    // ST=New Jersey, C=US
-    // Serial number: 9bd0c93cac9ca2edc1a7dd923316b3c6
-    // Valid from: Mon Jul 03 17:00:00 PDT 2017 until: Thu Oct 03 16:59:59 PDT 2019
-    private static final String REVOKED = "-----BEGIN CERTIFICATE-----\n" +
-            "MIIGhzCCBi2gAwIBAgIRAJvQyTysnKLtwafdkjMWs8YwCgYIKoZIzj0EAwIwgZUx\n" +
-            "CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJz\n" +
-            "ZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMTswOQYDVQQD\n" +
-            "EzJVU0VSVHJ1c3QgRUNDIEV4dGVuZGVkIFZhbGlkYXRpb24gU2VjdXJlIFNlcnZl\n" +
-            "ciBDQTAeFw0xNzA3MDQwMDAwMDBaFw0xOTEwMDMyMzU5NTlaMIIBYDERMA8GA1UE\n" +
-            "BRMIMDQwNTg2OTAxEzARBgsrBgEEAYI3PAIBAxMCR0IxHTAbBgNVBA8TFFByaXZh\n" +
-            "dGUgT3JnYW5pemF0aW9uMQswCQYDVQQGEwJHQjEPMA0GA1UEERMGTTUgM0VRMRsw\n" +
-            "GQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxFjAU\n" +
-            "BgNVBAkTDVRyYWZmb3JkIFJvYWQxFjAUBgNVBAkTDUV4Y2hhbmdlIFF1YXkxJTAj\n" +
-            "BgNVBAkTHDNyZCBGbG9vciwgMjYgT2ZmaWNlIFZpbGxhZ2UxGjAYBgNVBAoTEUNP\n" +
-            "TU9ETyBDQSBMaW1pdGVkMRowGAYDVQQLExFDT01PRE8gRVYgU0dDIFNTTDE7MDkG\n" +
-            "A1UEAxMydXNlcnRydXN0ZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1ldi5jb21v\n" +
-            "ZG9jYS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQtMl8R33ZaWD6H8BW0\n" +
-            "+wybBf0+6+L5YYK/eyAVGm6vwjLaQZWlcdFBMKfaP1qTLi0VAabs4baSUkD8wR56\n" +
-            "8pVpo4IDjjCCA4owHwYDVR0jBBgwFoAUKpxa+U6hMNpASyvpS/H1nNwC+S4wHQYD\n" +
-            "VR0OBBYEFLOtYfOaIfDHZGubtKNELRR6A2srMA4GA1UdDwEB/wQEAwIFgDAMBgNV\n" +
-            "HRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjBQBgNVHSAE\n" +
-            "STBHMDwGDCsGAQQBsjEBAgEFATAsMCoGCCsGAQUFBwIBFh5odHRwczovL2Nwcy50\n" +
-            "cnVzdC1wcm92aWRlci5jb20wBwYFZ4EMAQEwXwYDVR0fBFgwVjBUoFKgUIZOaHR0\n" +
-            "cDovL2NybC50cnVzdC1wcm92aWRlci5jb20vVVNFUlRydXN0RUNDRXh0ZW5kZWRW\n" +
-            "YWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3JsMIGYBggrBgEFBQcBAQSBizCBiDBa\n" +
-            "BggrBgEFBQcwAoZOaHR0cDovL2NydC50cnVzdC1wcm92aWRlci5jb20vVVNFUlRy\n" +
-            "dXN0RUNDRXh0ZW5kZWRWYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCoGCCsG\n" +
-            "AQUFBzABhh5odHRwOi8vb2NzcC50cnVzdC1wcm92aWRlci5jb20wPQYDVR0RBDYw\n" +
-            "NIIydXNlcnRydXN0ZWNjY2VydGlmaWNhdGlvbmF1dGhvcml0eS1ldi5jb21vZG9j\n" +
-            "YS5jb20wggF8BgorBgEEAdZ5AgQCBIIBbASCAWgBZgB1AKS5CZC0GFgUh7sTosxn\n" +
-            "cAo8NZgE+RvfuON3zQ7IDdwQAAABXQ0/jQ0AAAQDAEYwRAIgPbaNWgoi6OfyNwL2\n" +
-            "+jiySsoLrkx+0d4NJE1WnZQcfzwCICW4yvsXaMxoOXpQp3EPgrYk5Ajfvy/dY3Ui\n" +
-            "0/dbQtHxAHYAVhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFdDT+K\n" +
-            "xwAABAMARzBFAiB3GQasrX+akoHX02ZvXCcvhWCqv6qQOhLCUqflPoRbuAIhALwe\n" +
-            "hrQo8S1Tm5vbMcxGiViq5ZcawxENWhxZ9hS0BZweAHUA7ku9t3XOYLrhQmkfq+Ge\n" +
-            "ZqMPfl+wctiDAMR7iXqo/csAAAFdDT+M4AAABAMARjBEAiAjvp8w/fdTVW1VGE0T\n" +
-            "I0YcCIXTYFDgzUMsEUiKHANAgwIgETQUcac7Hiis2fgQ+GdGF9yuh+xMo2Z8QXNu\n" +
-            "1Cknf+8wCgYIKoZIzj0EAwIDSAAwRQIgQ5UiUI7xodmmMYNs3CmqlZHw/04BQRAR\n" +
-            "4gRm7blZSIMCIQDHvIWTaPzSO6vwVzs6wSD6FqebLiFxoddC6aZG8Nm0wQ==\n" +
-            "-----END CERTIFICATE-----";
-
     public void runTest(ValidatePathWithParams pathValidator) throws Exception {
         // Validate valid
-        pathValidator.validate(new String[]{VALID, INT},
+        pathValidator.validate(new String[]{VALID, INT_VALID},
                 ValidatePathWithParams.Status.GOOD, null, System.out);
 
         // Validate Revoked
-        pathValidator.validate(new String[]{REVOKED, INT},
+        pathValidator.validate(new String[]{REVOKED, INT_REVOKED},
                 ValidatePathWithParams.Status.REVOKED,
-                "Thu Nov 29 10:06:00 PST 2018", System.out);
+                "Wed Oct 02 06:06:50 PDT 2019", System.out);
     }
 }
--- a/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java	Thu Oct 10 10:57:42 2019 -0400
@@ -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
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8080462
+ * @bug 8080462 8229243
  * @library /test/lib ..
  * @modules jdk.crypto.cryptoki
  * @run main TestGCMKeyAndIvCheck
@@ -81,6 +81,7 @@
                     ", no support for " + mode);
             return;
         }
+        System.out.println("Testing against " + p.getName());
         SecretKey key = new SecretKeySpec(new byte[16], "AES");
         // First try parameter-less init.
         c.init(Cipher.ENCRYPT_MODE, key);
@@ -111,12 +112,11 @@
             throw new Exception("Parameters contains incorrect IV value");
         }
 
-        // Should be ok to use the same key+iv for decryption
         c.init(Cipher.DECRYPT_MODE, key, params);
         c.updateAAD(AAD);
         byte[] recovered = c.doFinal(ctPlusTag);
         if (!Arrays.equals(recovered, PT)) {
-            throw new Exception("decryption result mismatch");
+            throw new Exception("Decryption result mismatch");
         }
 
         // Now try to encrypt again using the same key+iv; should fail also
@@ -125,6 +125,7 @@
             throw new Exception("Should throw exception when same key+iv is used");
         } catch (InvalidAlgorithmParameterException iape) {
             // expected
+            System.out.println("Expected IAPE thrown");
         }
 
         // Now try to encrypt again using parameter-less init; should work
@@ -138,7 +139,8 @@
         }
 
         // Now try to encrypt again using a different parameter; should work
-        AlgorithmParameterSpec spec2 = new GCMParameterSpec(128, new byte[30]);
+        AlgorithmParameterSpec spec2 = new GCMParameterSpec(128,
+            "Solaris PKCS11 lib does not allow all-zero IV".getBytes());
         c.init(Cipher.ENCRYPT_MODE, key, spec2);
         c.updateAAD(AAD);
         c.doFinal(PT);
@@ -154,7 +156,7 @@
         c.updateAAD(AAD);
         recovered = c.doFinal(ctPlusTag);
         if (!Arrays.equals(recovered, PT)) {
-            throw new Exception("decryption result mismatch");
+            throw new Exception("Decryption result mismatch");
         }
 
         // Now try decryption again and re-init using the same parameters
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/tools/jhsdb/HeapDumpTestWithActiveProcess.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,31 @@
+/*
+ * 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  8230731 8001227 8231635 8231634 8196969
+ * @requires vm.hasSAandCanAttach
+ * @library /test/lib
+ * @compile JShellHeapDumpTest.java
+ * @run main/timeout=240 JShellHeapDumpTest nosleep
+ */
--- a/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/jdk/sun/tools/jhsdb/JShellHeapDumpTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -48,7 +48,8 @@
 
 public class JShellHeapDumpTest {
 
-    protected static Process jShellProcess;
+    static Process jShellProcess;
+    static boolean doSleep = true; // By default do a short sleep when app starts up
 
     public static void launch(String expectedMessage, List<String> toolArgs)
         throws IOException {
@@ -141,13 +142,23 @@
 
         // Give jshell a chance to fully start up. This makes SA more stable for the jmap dump.
         try {
-            Thread.sleep(2000);
+            if (doSleep) {
+                Thread.sleep(2000);
+            }
         } catch (Exception e) {
         }
     }
 
     public static void main(String[] args) throws Exception {
-
+        if (args.length == 1) {
+            if (args[0].equals("nosleep")) {
+                doSleep = false;
+            } else {
+                throw new RuntimeException("Invalid arg: " + args[0]);
+            }
+        } else if (args.length != 0) {
+            throw new RuntimeException("Too many args: " + args.length);
+        }
         testHeapDump();
 
         // The test throws RuntimeException on error.
--- a/test/jtreg-ext/requires/VMProps.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/jtreg-ext/requires/VMProps.java	Thu Oct 10 10:57:42 2019 -0400
@@ -305,6 +305,7 @@
      */
     protected void vmOptFinalFlags(SafeMap map) {
         vmOptFinalFlag(map, "ClassUnloading");
+        vmOptFinalFlag(map, "ClassUnloadingWithConcurrentMark");
         vmOptFinalFlag(map, "UseCompressedOops");
         vmOptFinalFlag(map, "EnableJVMCI");
         vmOptFinalFlag(map, "EliminateAllocations");
--- a/test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/langtools/jdk/javadoc/doclet/testMemberInheritance/TestMemberInheritance.java	Thu Oct 10 10:57:42 2019 -0400
@@ -24,7 +24,7 @@
 /*
  * @test
  * @bug 4638588 4635809 6256068 6270645 8025633 8026567 8162363 8175200
- *      8192850 8182765
+ *      8192850 8182765 8220217
  * @summary Test to make sure that members are inherited properly in the Javadoc.
  *          Verify that inheritance labels are correct.
  * @author jamieh
@@ -47,7 +47,7 @@
     public void test() {
         javadoc("-d", "out",
                 "-sourcepath", testSrc,
-                "pkg", "diamond", "inheritDist", "pkg1");
+                "pkg", "diamond", "inheritDist", "pkg1", "pkg2");
         checkExit(Exit.OK);
 
         checkOutput("pkg/SubClass.html", true,
@@ -104,5 +104,27 @@
                 + "<code><a href=\"Interface.html#between(java.time.chrono.ChronoLocalDate"
                 + ",java.time.chrono.ChronoLocalDate)\">between</a></code>"
         );
+
+        checkOutput("pkg2/DocumentedNonGenericChild.html", true,
+                "<section class=\"description\">\n<hr>\n"
+                + "<pre>public abstract class <span class=\"typeNameLabel\">"
+                + "DocumentedNonGenericChild</span>\n"
+                + "extends java.lang.Object</pre>\n"
+                + "</section>");
+
+        checkOutput("pkg2/DocumentedNonGenericChild.html", true,
+                "<td class=\"colFirst\"><code>protected abstract java.lang.String</code></td>\n"
+                + "<th class=\"colSecond\" scope=\"row\"><code><span class=\"memberNameLink\">"
+                + "<a href=\"#parentMethod()\">parentMethod</a></span>()</code></th>\n"
+                + "<td class=\"colLast\">\n"
+                + "<div class=\"block\">Returns some value.</div>\n"
+                + "</td>\n");
+
+        checkOutput("pkg2/DocumentedNonGenericChild.html", true,
+                "<h3><a id=\"parentMethod()\">parentMethod</a></h3>\n"
+                + "<div class=\"memberSignature\"><span class=\"modifiers\">protected abstract</span>"
+                + "&nbsp;<span class=\"returnType\">java.lang.String</span>&nbsp;"
+                + "<span class=\"memberName\">parentMethod</span>()</div>");
+
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testMemberInheritance/pkg2/DocumentedNonGenericChild.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,28 @@
+/*
+ * 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 pkg2;
+
+public abstract class DocumentedNonGenericChild extends UndocumentedGenericParent<String> {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/jdk/javadoc/doclet/testMemberInheritance/pkg2/UndocumentedGenericParent.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,33 @@
+/*
+ * 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 pkg2;
+
+abstract class UndocumentedGenericParent<T> {
+    /**
+     * Returns some value.
+     *
+     * @return some value
+     */
+    protected abstract String parentMethod();
+}
--- a/test/langtools/tools/javac/lib/DPrinter.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/langtools/tools/javac/lib/DPrinter.java	Thu Oct 10 10:57:42 2019 -0400
@@ -437,7 +437,8 @@
         Scope scope = (Scope) getField(e, e.getClass(), "scope");
         return "(" + sym.name + ":" + sym
                 + ",shdw:" + entryToString(callMethod(e, e.getClass(), "next"), table, true)
-                + ",sibl:" + entryToString(getField(e, e.getClass(), "sibling"), table, true)
+                + ",nextSibling:" + entryToString(getField(e, e.getClass(), "nextSibling"), table, true)
+                + ",prevSibling:" + entryToString(getField(e, e.getClass(), "prevSibling"), table, true)
                 + ((sym.owner != scope.owner)
                     ? (",BOGUS[" + sym.owner + "," + scope.owner + "]")
                     : "")
--- a/test/langtools/tools/javac/scope/RemoveSymbolUnitTest.java	Wed Oct 09 10:58:20 2019 -0400
+++ b/test/langtools/tools/javac/scope/RemoveSymbolUnitTest.java	Thu Oct 10 10:57:42 2019 -0400
@@ -33,8 +33,13 @@
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Scope.*;
+import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.file.JavacFileManager;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 
 public class RemoveSymbolUnitTest {
 
@@ -63,36 +68,66 @@
 
         // Try enter and remove in different shuffled combinations.
         // working with fresh scope each time.
-        WriteableScope cs = WriteableScope.create(clazz);
-        cs.enter(v);
-        cs.enter(m);
+        WriteableScope cs = writeableScope(clazz, v, m);
         cs.remove(v);
         Symbol s = cs.findFirst(hasNext);
         if (s != m)
             throw new AssertionError("Wrong symbol");
 
-        cs = WriteableScope.create(clazz);
-        cs.enter(m);
-        cs.enter(v);
+        cs = writeableScope(clazz, m, v);
         cs.remove(v);
         s = cs.findFirst(hasNext);
         if (s != m)
             throw new AssertionError("Wrong symbol");
 
-        cs = WriteableScope.create(clazz);
-        cs.enter(v);
-        cs.enter(m);
+        cs = writeableScope(clazz, v, m);
         cs.remove(m);
         s = cs.findFirst(hasNext);
         if (s != v)
             throw new AssertionError("Wrong symbol");
 
-        cs = WriteableScope.create(clazz);
+        cs = writeableScope(clazz);
         cs.enter(m);
         cs.enter(v);
         cs.remove(m);
         s = cs.findFirst(hasNext);
         if (s != v)
             throw new AssertionError("Wrong symbol");
+
+        // Test multiple removals in the same scope.
+        VarSymbol v1 = new VarSymbol(0, names.fromString("name1"), Type.noType, clazz);
+        VarSymbol v2 = new VarSymbol(0, names.fromString("name2"), Type.noType, clazz);
+        VarSymbol v3 = new VarSymbol(0, names.fromString("name3"), Type.noType, clazz);
+        VarSymbol v4 = new VarSymbol(0, names.fromString("name4"), Type.noType, clazz);
+
+        cs = writeableScope(clazz, v1, v2, v3, v4);
+        cs.remove(v2);
+        assertRemainingSymbols(cs, v1, v3, v4);
+        cs.remove(v3);
+        assertRemainingSymbols(cs, v1, v4);
+        cs.remove(v1);
+        assertRemainingSymbols(cs, v4);
+        cs.remove(v4);
+        assertRemainingSymbols(cs);
+    }
+
+    private WriteableScope writeableScope(ClassSymbol classSymbol, Symbol... symbols) {
+        WriteableScope cs = WriteableScope.create(classSymbol);
+        for (Symbol symbol : symbols) {
+            cs.enter(symbol);
+        }
+        return cs;
+    }
+
+    private void assertRemainingSymbols(WriteableScope cs, Symbol... symbols) {
+      List<Symbol> expectedSymbols = Arrays.asList(symbols);
+      List<Symbol> actualSymbols = new ArrayList<>();
+      cs.getSymbols().forEach(symbol -> actualSymbols.add(symbol));
+      // The symbols are stored in reverse order
+      Collections.reverse(actualSymbols);
+      if (!actualSymbols.equals(expectedSymbols)) {
+          throw new AssertionError(
+              String.format("Wrong symbols: %s. Expected %s", actualSymbols, expectedSymbols));
+      }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/security/GetContext.java	Thu Oct 10 10:57:42 2019 -0400
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.openjdk.bench.java.security;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.State;
+
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring AccessController.getContext
+ */
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public abstract class GetContext {
+
+    public static class Top extends GetContext {
+
+        @Benchmark
+        public AccessControlContext testNonPriv() {
+            return AccessController.getContext();
+        }
+
+        @Benchmark
+        public AccessControlContext testPriv() {
+            PrivilegedAction<AccessControlContext> pa = () -> AccessController.getContext();
+            return AccessController.doPrivileged(pa);
+        }
+    }
+
+    public static class Deep extends GetContext {
+
+        @Param({"2", "50"})
+        int depth;
+
+        private AccessControlContext recurse(int depth) {
+            if (depth > 0) {
+                return recurse(depth - 1);
+            } else {
+                return AccessController.getContext();
+            }
+        }
+
+        @Benchmark
+        public AccessControlContext testNonPrivRecurse() {
+            return recurse(depth);
+        }
+
+        @Benchmark
+        public AccessControlContext testPrivInline() {
+            PrivilegedAction<AccessControlContext> pa = () -> recurse(depth);
+            return AccessController.doPrivileged(pa);
+        }
+    }
+}