Merge JDK-8200758-branch
authorherrick
Wed, 28 Aug 2019 11:58:56 -0400
branchJDK-8200758-branch
changeset 57912 2faaa38c86a4
parent 57911 f052c884af39 (current diff)
parent 57906 e17f768b3b71 (diff)
child 57951 37e70d4679df
Merge
make/common/Modules.gmk
src/hotspot/os_cpu/linux_aarch64/gc/z/zBackingFile_linux_aarch64.cpp
src/hotspot/os_cpu/linux_aarch64/gc/z/zBackingFile_linux_aarch64.hpp
src/hotspot/os_cpu/linux_aarch64/gc/z/zBackingPath_linux_aarch64.cpp
src/hotspot/os_cpu/linux_aarch64/gc/z/zBackingPath_linux_aarch64.hpp
src/hotspot/os_cpu/linux_aarch64/gc/z/zPhysicalMemoryBacking_linux_aarch64.cpp
src/hotspot/os_cpu/linux_aarch64/gc/z/zPhysicalMemoryBacking_linux_aarch64.hpp
src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.cpp
src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.hpp
src/hotspot/os_cpu/linux_x86/gc/z/zBackingPath_linux_x86.cpp
src/hotspot/os_cpu/linux_x86/gc/z/zBackingPath_linux_x86.hpp
src/hotspot/os_cpu/linux_x86/gc/z/zPhysicalMemoryBacking_linux_x86.cpp
src/hotspot/os_cpu/linux_x86/gc/z/zPhysicalMemoryBacking_linux_x86.hpp
src/hotspot/share/classfile/sharedPathsMiscInfo.cpp
src/hotspot/share/classfile/sharedPathsMiscInfo.hpp
src/hotspot/share/oops/markOop.cpp
src/hotspot/share/oops/markOop.hpp
src/hotspot/share/oops/markOop.inline.hpp
test/hotspot/gtest/oops/test_markOop.cpp
test/jdk/java/net/Socket/reset/Test.java
test/jdk/javax/xml/jaxp/testng/validation/jdk8037819/BasicTest1.java
--- a/.hgtags	Wed Aug 28 11:52:20 2019 -0400
+++ b/.hgtags	Wed Aug 28 11:58:56 2019 -0400
@@ -582,3 +582,4 @@
 9c250a7600e12bdb1e611835250af3204d4aa152 jdk-13+33
 18f189e69b29f8215a3500b875127ed4fb2d977a jdk-14+9
 ececb6dae777e622abda42c705fd984a42f46b5a jdk-14+10
+bf4c808a4488025a415f867e54c8b088417e08a0 jdk-14+11
--- a/doc/building.html	Wed Aug 28 11:52:20 2019 -0400
+++ b/doc/building.html	Wed Aug 28 11:58:56 2019 -0400
@@ -572,6 +572,7 @@
 <li><code>CONF_CHECK</code></li>
 <li><code>COMPARE_BUILD</code></li>
 <li><code>JDK_FILTER</code></li>
+<li><code>SPEC_FILTER</code></li>
 </ul>
 <h2 id="running-tests">Running Tests</h2>
 <p>Most of the JDK tests are using the <a href="http://openjdk.java.net/jtreg">JTReg</a> test framework. Make sure that your configuration knows where to find your installation of JTReg. If this is not picked up automatically, use the <code>--with-jtreg=&lt;path to jtreg home&gt;</code> option to point to the JTReg framework. Note that this option should point to the JTReg home, i.e. the top directory, containing <code>lib/jtreg.jar</code> etc.</p>
--- a/doc/testing.html	Wed Aug 28 11:52:20 2019 -0400
+++ b/doc/testing.html	Wed Aug 28 11:58:56 2019 -0400
@@ -54,7 +54,7 @@
 $ make test-jdk_lang JTREG=&quot;JOBS=8&quot;
 $ make test TEST=jdk_lang
 $ make test-only TEST=&quot;gtest:LogTagSet gtest:LogTagSetDescriptions&quot; GTEST=&quot;REPEAT=-1&quot;
-$ make test TEST=&quot;hotspot:hotspot_gc&quot; JTREG=&quot;JOBS=1;TIMEOUT=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug&quot;
+$ make test TEST=&quot;hotspot:hotspot_gc&quot; JTREG=&quot;JOBS=1;TIMEOUT_FACTOR=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug&quot;
 $ make test TEST=&quot;jtreg:test/hotspot:hotspot_gc test/hotspot/jtreg/native_sanity/JniVersion.java&quot;
 $ make test TEST=&quot;micro:java.lang.reflect&quot; MICRO=&quot;FORK=1;WARMUP_ITER=2&quot;
 $ make exploded-test TEST=tier2</code></pre>
@@ -103,9 +103,9 @@
 <p>Additional work data is stored in <code>build/$BUILD/test-support/$TEST_ID</code>. For some frameworks, this directory might contain information that is useful in determining the cause of a failed test.</p>
 <h2 id="test-suite-control">Test suite control</h2>
 <p>It is possible to control various aspects of the test suites using make control variables.</p>
-<p>These variables use a keyword=value approach to allow multiple values to be set. So, for instance, <code>JTREG=&quot;JOBS=1;TIMEOUT=8&quot;</code> will set the JTReg concurrency level to 1 and the timeout factor to 8. This is equivalent to setting <code>JTREG_JOBS=1 JTREG_TIMEOUT=8</code>, but using the keyword format means that the <code>JTREG</code> variable is parsed and verified for correctness, so <code>JTREG=&quot;TMIEOUT=8&quot;</code> would give an error, while <code>JTREG_TMIEOUT=8</code> would just pass unnoticed.</p>
+<p>These variables use a keyword=value approach to allow multiple values to be set. So, for instance, <code>JTREG=&quot;JOBS=1;TIMEOUT_FACTOR=8&quot;</code> will set the JTReg concurrency level to 1 and the timeout factor to 8. This is equivalent to setting <code>JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8</code>, but using the keyword format means that the <code>JTREG</code> variable is parsed and verified for correctness, so <code>JTREG=&quot;TMIEOUT_FACTOR=8&quot;</code> would give an error, while <code>JTREG_TMIEOUT_FACTOR=8</code> would just pass unnoticed.</p>
 <p>To separate multiple keyword=value pairs, use <code>;</code> (semicolon). Since the shell normally eats <code>;</code>, the recommended usage is to write the assignment inside qoutes, e.g. <code>JTREG=&quot;...;...&quot;</code>. This will also make sure spaces are preserved, as in <code>JTREG=&quot;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug&quot;</code>.</p>
-<p>(Other ways are possible, e.g. using backslash: <code>JTREG=JOBS=1\;TIMEOUT=8</code>. Also, as a special technique, the string <code>%20</code> will be replaced with space for certain options, e.g. <code>JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug</code>. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)</p>
+<p>(Other ways are possible, e.g. using backslash: <code>JTREG=JOBS=1\;TIMEOUT_FACTOR=8</code>. Also, as a special technique, the string <code>%20</code> will be replaced with space for certain options, e.g. <code>JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug</code>. This can be useful if you have layers of scripts and have trouble getting proper quoting of command line arguments through.)</p>
 <p>As far as possible, the names of the keywords have been standardized between test suites.</p>
 <h3 id="general-keywords-test_opts">General keywords (TEST_OPTS)</h3>
 <p>Some keywords are valid across different test suites. If you want to run tests from multiple test suites, or just don't want to care which test suite specific control variable to use, then you can use the general TEST_OPTS control variable.</p>
--- a/doc/testing.md	Wed Aug 28 11:52:20 2019 -0400
+++ b/doc/testing.md	Wed Aug 28 11:58:56 2019 -0400
@@ -23,7 +23,7 @@
     $ make test-jdk_lang JTREG="JOBS=8"
     $ make test TEST=jdk_lang
     $ make test-only TEST="gtest:LogTagSet gtest:LogTagSetDescriptions" GTEST="REPEAT=-1"
-    $ make test TEST="hotspot:hotspot_gc" JTREG="JOBS=1;TIMEOUT=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
+    $ make test TEST="hotspot:hotspot_gc" JTREG="JOBS=1;TIMEOUT_FACTOR=8;VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"
     $ make test TEST="jtreg:test/hotspot:hotspot_gc test/hotspot/jtreg/native_sanity/JniVersion.java"
     $ make test TEST="micro:java.lang.reflect" MICRO="FORK=1;WARMUP_ITER=2"
     $ make exploded-test TEST=tier2
@@ -180,11 +180,11 @@
 variables.
 
 These variables use a keyword=value approach to allow multiple values to be
-set. So, for instance, `JTREG="JOBS=1;TIMEOUT=8"` will set the JTReg
+set. So, for instance, `JTREG="JOBS=1;TIMEOUT_FACTOR=8"` will set the JTReg
 concurrency level to 1 and the timeout factor to 8. This is equivalent to
-setting `JTREG_JOBS=1 JTREG_TIMEOUT=8`, but using the keyword format means that
+setting `JTREG_JOBS=1 JTREG_TIMEOUT_FACTOR=8`, but using the keyword format means that
 the `JTREG` variable is parsed and verified for correctness, so
-`JTREG="TMIEOUT=8"` would give an error, while `JTREG_TMIEOUT=8` would just
+`JTREG="TMIEOUT_FACTOR=8"` would give an error, while `JTREG_TMIEOUT_FACTOR=8` would just
 pass unnoticed.
 
 To separate multiple keyword=value pairs, use `;` (semicolon). Since the shell
@@ -192,7 +192,7 @@
 qoutes, e.g. `JTREG="...;..."`. This will also make sure spaces are preserved,
 as in `JTREG="VM_OPTIONS=-XshowSettings -Xlog:gc+ref=debug"`.
 
-(Other ways are possible, e.g. using backslash: `JTREG=JOBS=1\;TIMEOUT=8`.
+(Other ways are possible, e.g. using backslash: `JTREG=JOBS=1\;TIMEOUT_FACTOR=8`.
 Also, as a special technique, the string `%20` will be replaced with space for
 certain options, e.g. `JTREG=VM_OPTIONS=-XshowSettings%20-Xlog:gc+ref=debug`.
 This can be useful if you have layers of scripts and have trouble getting
--- a/make/common/Modules.gmk	Wed Aug 28 11:52:20 2019 -0400
+++ b/make/common/Modules.gmk	Wed Aug 28 11:58:56 2019 -0400
@@ -64,6 +64,7 @@
     jdk.management.jfr \
     jdk.management.agent \
     jdk.net \
+    jdk.nio.mapmode \
     jdk.sctp \
     jdk.unsupported \
     #
--- a/make/jdk/src/classes/build/tools/classlist/HelloClasslist.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/make/jdk/src/classes/build/tools/classlist/HelloClasslist.java	Wed Aug 28 11:58:56 2019 -0400
@@ -87,6 +87,7 @@
         String CICI   = "string" + args.length + "string" + args.length;
         String CJ     = "string" + System.currentTimeMillis();
         String JC     = System.currentTimeMillis() + "string";
+        String CD     = "string" + (args.length/2.0);
         String CJC    = "string" + System.currentTimeMillis() + "string";
         String CJCJ   = "string" + System.currentTimeMillis() + "string" + System.currentTimeMillis();
         String CJCJC  = "string" + System.currentTimeMillis() + "string" + System.currentTimeMillis() + "string";
--- a/src/hotspot/cpu/aarch64/aarch64.ad	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/aarch64.ad	Wed Aug 28 11:58:56 2019 -0400
@@ -2185,17 +2185,21 @@
 //=============================================================================
 
 const bool Matcher::match_rule_supported(int opcode) {
-
+  if (!has_match_rule(opcode))
+    return false;
+
+  bool ret_value = true;
   switch (opcode) {
-  default:
-    break;
+    case Op_CacheWB:
+    case Op_CacheWBPreSync:
+    case Op_CacheWBPostSync:
+      if (!VM_Version::supports_data_cache_line_flush()) {
+        ret_value = false;
+      }
+      break;
   }
 
-  if (!has_match_rule(opcode)) {
-    return false;
-  }
-
-  return true;  // Per default match rules are supported.
+  return ret_value; // Per default match rules are supported.
 }
 
 const bool Matcher::match_rule_supported_vector(int opcode, int vlen) {
@@ -3565,7 +3569,7 @@
     // Store a non-null value into the box to avoid looking like a re-entrant
     // lock. The fast-path monitor unlock code checks for
     // markWord::monitor_value so use markWord::unused_mark which has the
-    // relevant bit set, and also matches ObjectSynchronizer::slow_enter.
+    // relevant bit set, and also matches ObjectSynchronizer::enter.
     __ mov(tmp, (address)markWord::unused_mark().value());
     __ str(tmp, Address(box, BasicLock::displaced_header_offset_in_bytes()));
 
@@ -7769,6 +7773,47 @@
 
 //  ---------------- end of volatile loads and stores ----------------
 
+instruct cacheWB(indirect addr)
+%{
+  predicate(VM_Version::supports_data_cache_line_flush());
+  match(CacheWB addr);
+
+  ins_cost(100);
+  format %{"cache wb $addr" %}
+  ins_encode %{
+    assert($addr->index_position() < 0, "should be");
+    assert($addr$$disp == 0, "should be");
+    __ cache_wb(Address($addr$$base$$Register, 0));
+  %}
+  ins_pipe(pipe_slow); // XXX
+%}
+
+instruct cacheWBPreSync()
+%{
+  predicate(VM_Version::supports_data_cache_line_flush());
+  match(CacheWBPreSync);
+
+  ins_cost(100);
+  format %{"cache wb presync" %}
+  ins_encode %{
+    __ cache_wbsync(true);
+  %}
+  ins_pipe(pipe_slow); // XXX
+%}
+
+instruct cacheWBPostSync()
+%{
+  predicate(VM_Version::supports_data_cache_line_flush());
+  match(CacheWBPostSync);
+
+  ins_cost(100);
+  format %{"cache wb postsync" %}
+  ins_encode %{
+    __ cache_wbsync(false);
+  %}
+  ins_pipe(pipe_slow); // XXX
+%}
+
 // ============================================================================
 // BSWAP Instructions
 
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1058,12 +1058,13 @@
   //            op1    CRn    CRm    op2
   // IC IVAU     3      7      5      1
   // DC CVAC     3      7      10     1
+  // DC CVAP     3      7      12     1
   // DC CVAU     3      7      11     1
   // DC CIVAC    3      7      14     1
   // DC ZVA      3      7      4      1
   // So only deal with the CRm field.
   enum icache_maintenance {IVAU = 0b0101};
-  enum dcache_maintenance {CVAC = 0b1010, CVAU = 0b1011, CIVAC = 0b1110, ZVA = 0b100};
+  enum dcache_maintenance {CVAC = 0b1010, CVAP = 0b1100, CVAU = 0b1011, CIVAC = 0b1110, ZVA = 0b100};
 
   void dc(dcache_maintenance cm, Register Rt) {
     sys(0b011, 0b0111, cm, 0b001, Rt);
--- a/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/c1_MacroAssembler_aarch64.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -30,7 +30,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "interpreter/interpreter.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/basicLock.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/cpu/aarch64/frame_aarch64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/frame_aarch64.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,7 +27,7 @@
 #include "interpreter/interpreter.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/methodHandles.hpp"
--- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2015, 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
--- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -32,7 +32,7 @@
 #include "interpreter/interpreterRuntime.hpp"
 #include "logging/log.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/methodData.hpp"
 #include "prims/jvmtiExport.hpp"
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -5833,3 +5833,25 @@
 
   pop(saved_regs, sp);
 }
+
+void MacroAssembler::cache_wb(Address line) {
+  assert(line.getMode() == Address::base_plus_offset, "mode should be base_plus_offset");
+  assert(line.index() == noreg, "index should be noreg");
+  assert(line.offset() == 0, "offset should be 0");
+  // would like to assert this
+  // assert(line._ext.shift == 0, "shift should be zero");
+  if (VM_Version::supports_dcpop()) {
+    // writeback using clear virtual address to point of persistence
+    dc(Assembler::CVAP, line.base());
+  } else {
+    // no need to generate anything as Unsafe.writebackMemory should
+    // never invoke this stub
+  }
+}
+
+void MacroAssembler::cache_wbsync(bool is_pre) {
+  // we only need a barrier post sync
+  if (!is_pre) {
+    membar(Assembler::AnyAny);
+  }
+}
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1344,6 +1344,9 @@
       spill(tmp1, true, dst_offset+8);
     }
   }
+
+  void cache_wb(Address line);
+  void cache_wbsync(bool is_pre);
 };
 
 #ifdef ASSERT
--- a/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/stubGenerator_aarch64.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -2350,6 +2350,44 @@
     return start;
   }
 
+  address generate_data_cache_writeback() {
+    const Register line        = c_rarg0;  // address of line to write back
+
+    __ align(CodeEntryAlignment);
+
+    StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback");
+
+    address start = __ pc();
+    __ enter();
+    __ cache_wb(Address(line, 0));
+    __ leave();
+    __ ret(lr);
+
+    return start;
+  }
+
+  address generate_data_cache_writeback_sync() {
+    const Register is_pre     = c_rarg0;  // pre or post sync
+
+    __ align(CodeEntryAlignment);
+
+    StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback_sync");
+
+    // pre wbsync is a no-op
+    // post wbsync translates to an sfence
+
+    Label skip;
+    address start = __ pc();
+    __ enter();
+    __ cbnz(is_pre, skip);
+    __ cache_wbsync(false);
+    __ bind(skip);
+    __ leave();
+    __ ret(lr);
+
+    return start;
+  }
+
   void generate_arraycopy_stubs() {
     address entry;
     address entry_jbyte_arraycopy;
@@ -5739,6 +5777,10 @@
       StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks();
     }
 
+    // data cache line writeback
+    StubRoutines::_data_cache_writeback = generate_data_cache_writeback();
+    StubRoutines::_data_cache_writeback_sync = generate_data_cache_writeback_sync();
+
     if (UseAESIntrinsics) {
       StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
       StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock();
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2015, Red Hat Inc. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 #include "asm/macroAssembler.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/java.hpp"
+#include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "utilities/macros.hpp"
 #include "vm_version_aarch64.hpp"
@@ -67,6 +68,7 @@
 int VM_Version::_variant;
 int VM_Version::_revision;
 int VM_Version::_stepping;
+bool VM_Version::_dcpop;
 VM_Version::PsrInfo VM_Version::_psr_info   = { 0, };
 
 static BufferBlob* stub_blob;
@@ -167,7 +169,8 @@
 
   int cpu_lines = 0;
   if (FILE *f = fopen("/proc/cpuinfo", "r")) {
-    char buf[128], *p;
+    // need a large buffer as the flags line may include lots of text
+    char buf[1024], *p;
     while (fgets(buf, sizeof (buf), f) != NULL) {
       if ((p = strchr(buf, ':')) != NULL) {
         long v = strtol(p+1, NULL, 0);
@@ -181,12 +184,25 @@
           _model = v;
         } else if (strncmp(buf, "CPU revision", sizeof "CPU revision" - 1) == 0) {
           _revision = v;
+        } else if (strncmp(buf, "flags", sizeof("flags") - 1) == 0) {
+          if (strstr(p+1, "dcpop")) {
+            _dcpop = true;
+          }
         }
       }
     }
     fclose(f);
   }
 
+  if (os::supports_map_sync()) {
+    // if dcpop is available publish data cache line flush size via
+    // generic field, otherwise let if default to zero thereby
+    // disabling writeback
+    if (_dcpop) {
+      _data_cache_line_flush_size = dcache_line;
+    }
+  }
+
   // Enable vendor specific features
 
   // Ampere eMAG
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
   static int _variant;
   static int _revision;
   static int _stepping;
-
+  static bool _dcpop;
   struct PsrInfo {
     uint32_t dczid_el0;
     uint32_t ctr_el0;
@@ -106,6 +106,7 @@
   static int cpu_model2()                     { return _model2; }
   static int cpu_variant()                    { return _variant; }
   static int cpu_revision()                   { return _revision; }
+  static bool supports_dcpop()                { return _dcpop; }
   static ByteSize dczid_el0_offset() { return byte_offset_of(PsrInfo, dczid_el0); }
   static ByteSize ctr_el0_offset()   { return byte_offset_of(PsrInfo, ctr_el0); }
   static bool is_zva_enabled() {
--- a/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -29,7 +29,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "interpreter/interpreter.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/basicLock.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/cpu/arm/frame_arm.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/arm/frame_arm.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,7 +26,7 @@
 #include "interpreter/interpreter.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/frame.inline.hpp"
--- a/src/hotspot/cpu/arm/interp_masm_arm.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/arm/interp_masm_arm.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -34,7 +34,7 @@
 #include "interpreter/interpreterRuntime.hpp"
 #include "logging/log.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/methodData.hpp"
 #include "prims/jvmtiExport.hpp"
--- a/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/ppc/c1_MacroAssembler_ppc.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -31,7 +31,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "interpreter/interpreter.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/basicLock.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/cpu/ppc/frame_ppc.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/ppc/frame_ppc.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,7 +27,7 @@
 #include "interpreter/interpreter.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/frame.inline.hpp"
--- a/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/ppc/interp_masm_ppc_64.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -2265,7 +2265,7 @@
   cmpdi(CCR0, Rcounters, 0);
   bne(CCR0, has_counters);
   call_VM(noreg, CAST_FROM_FN_PTR(address,
-                                  InterpreterRuntime::build_method_counters), method, false);
+                                  InterpreterRuntime::build_method_counters), method);
   ld(Rcounters, in_bytes(Method::method_counters_offset()), method);
   cmpdi(CCR0, Rcounters, 0);
   beq(CCR0, skip); // No MethodCounters, OutOfMemory.
--- a/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/s390/c1_MacroAssembler_s390.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -31,7 +31,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "interpreter/interpreter.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/basicLock.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/cpu/s390/frame_s390.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/s390/frame_s390.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,7 +27,7 @@
 #include "interpreter/interpreter.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/hotspot/cpu/s390/interp_masm_s390.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/s390/interp_masm_s390.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -33,7 +33,7 @@
 #include "interpreter/interpreter.hpp"
 #include "interpreter/interpreterRuntime.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/basicLock.hpp"
@@ -1914,7 +1914,7 @@
   load_and_test_long(Rcounters, Address(Rmethod, Method::method_counters_offset()));
   z_brnz(has_counters);
 
-  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters), Rmethod, false);
+  call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters), Rmethod);
   z_ltgr(Rcounters, Z_RET); // Runtime call returns MethodCounters object.
   z_brz(skip); // No MethodCounters, out of memory.
 
--- a/src/hotspot/cpu/sparc/c1_MacroAssembler_sparc.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/sparc/c1_MacroAssembler_sparc.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -30,7 +30,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "interpreter/interpreter.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/basicLock.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/cpu/sparc/frame_sparc.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/sparc/frame_sparc.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,7 +27,7 @@
 #include "interpreter/interpreter.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/methodHandles.hpp"
--- a/src/hotspot/cpu/sparc/interp_masm_sparc.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/sparc/interp_masm_sparc.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -29,7 +29,7 @@
 #include "interpreter/interpreterRuntime.hpp"
 #include "logging/log.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/methodData.hpp"
 #include "oops/method.hpp"
 #include "oops/methodCounters.hpp"
--- a/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/sparc/macroAssembler_sparc.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -2607,8 +2607,8 @@
 // -   Successful Stack-lock: box->dhw == mark.
 //     box->dhw must contain the displaced mark word value
 // -   Failure -- icc.ZFlag == 0 and box->dhw is undefined.
-//     The slow-path fast_enter() and slow_enter() operators
-//     are responsible for setting box->dhw = NonZero (typically markWord::unused_mark()).
+//     The slow-path enter() is responsible for setting
+//     box->dhw = NonZero (typically markWord::unused_mark()).
 // -   Biased: box->dhw is undefined
 //
 // SPARC refworkload performance - specifically jetstream and scimark - are
--- a/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1833,7 +1833,7 @@
     // Read the header and build a mask to get its hash field.  Give up if the object is not unlocked.
     // We depend on hash_mask being at most 32 bits and avoid the use of
     // hash_mask_in_place because it could be larger than 32 bits in a 64-bit
-    // vm: see markOop.hpp.
+    // vm: see markWord.hpp.
     __ ld_ptr(obj_reg, oopDesc::mark_offset_in_bytes(), header);
     __ sethi(markWord::hash_mask, mask);
     __ btst(markWord::unlocked_value, header);
--- a/src/hotspot/cpu/x86/assembler_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/assembler_x86.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -2274,6 +2274,14 @@
   emit_int8((unsigned char)0xF0);
 }
 
+// Emit sfence instruction
+void Assembler::sfence() {
+  NOT_LP64(assert(VM_Version::supports_sse2(), "unsupported");)
+  emit_int8(0x0F);
+  emit_int8((unsigned char)0xAE);
+  emit_int8((unsigned char)0xF8);
+}
+
 void Assembler::mov(Register dst, Register src) {
   LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src));
 }
@@ -8617,12 +8625,45 @@
 }
 
 void Assembler::clflush(Address adr) {
+  assert(VM_Version::supports_clflush(), "should do");
   prefix(adr);
   emit_int8(0x0F);
   emit_int8((unsigned char)0xAE);
   emit_operand(rdi, adr);
 }
 
+void Assembler::clflushopt(Address adr) {
+  assert(VM_Version::supports_clflushopt(), "should do!");
+  // adr should be base reg only with no index or offset
+  assert(adr.index() == noreg, "index should be noreg");
+  assert(adr.scale() == Address::no_scale, "scale should be no_scale");
+  assert(adr.disp() == 0, "displacement should be 0");
+  // instruction prefix is 0x66
+  emit_int8(0x66);
+  prefix(adr);
+  // opcode family is 0x0f 0xAE
+  emit_int8(0x0F);
+  emit_int8((unsigned char)0xAE);
+  // extended opcode byte is 7 == rdi
+  emit_operand(rdi, adr);
+}
+
+void Assembler::clwb(Address adr) {
+  assert(VM_Version::supports_clwb(), "should do!");
+  // adr should be base reg only with no index or offset
+  assert(adr.index() == noreg, "index should be noreg");
+  assert(adr.scale() == Address::no_scale, "scale should be no_scale");
+  assert(adr.disp() == 0, "displacement should be 0");
+  // instruction prefix is 0x66
+  emit_int8(0x66);
+  prefix(adr);
+  // opcode family is 0x0f 0xAE
+  emit_int8(0x0F);
+  emit_int8((unsigned char)0xAE);
+  // extended opcode byte is 6 == rsi
+  emit_operand(rsi, adr);
+}
+
 void Assembler::cmovq(Condition cc, Register dst, Register src) {
   int encode = prefixq_and_encode(dst->encoding(), src->encoding());
   emit_int8(0x0F);
--- a/src/hotspot/cpu/x86/assembler_x86.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/assembler_x86.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1028,6 +1028,8 @@
   void cld();
 
   void clflush(Address adr);
+  void clflushopt(Address adr);
+  void clwb(Address adr);
 
   void cmovl(Condition cc, Register dst, Register src);
   void cmovl(Condition cc, Register dst, Address src);
@@ -1404,6 +1406,7 @@
   }
 
   void mfence();
+  void sfence();
 
   // Moves
 
--- a/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/c1_MacroAssembler_x86.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -31,7 +31,7 @@
 #include "gc/shared/collectedHeap.hpp"
 #include "interpreter/interpreter.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/basicLock.hpp"
 #include "runtime/biasedLocking.hpp"
 #include "runtime/os.hpp"
--- a/src/hotspot/cpu/x86/frame_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/frame_x86.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,7 +26,7 @@
 #include "interpreter/interpreter.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/methodHandles.hpp"
--- a/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/gc/shenandoah/shenandoahBarrierSetAssembler_x86.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -934,7 +934,7 @@
   StubCodeMark mark(cgen, "StubRoutines", "shenandoah_lrb");
   address start = __ pc();
 
-  Label resolve_oop, slow_path, done;
+  Label resolve_oop, slow_path;
 
   // We use RDI, which also serves as argument register for slow call.
   // RAX always holds the src object ptr, except after the slow call,
@@ -971,7 +971,6 @@
   // At this point, tmp2 contains the decoded forwarding pointer.
   __ mov(rax, tmp2);
 
-  __ bind(done);
   __ pop(tmp2);
   __ pop(tmp1);
   __ ret(0);
@@ -992,9 +991,14 @@
   __ push(r14);
   __ push(r15);
 #endif
-
+  __ push(rbp);
+  __ movptr(rbp, rsp);
+  __ andptr(rsp, -StackAlignmentInBytes);
+  __ push_FPU_state();
   __ call_VM_leaf(CAST_FROM_FN_PTR(address, ShenandoahRuntime::load_reference_barrier), rax);
-
+  __ pop_FPU_state();
+  __ movptr(rsp, rbp);
+  __ pop(rbp);
 #ifdef _LP64
   __ pop(r15);
   __ pop(r14);
--- a/src/hotspot/cpu/x86/interp_masm_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/interp_masm_x86.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -28,7 +28,7 @@
 #include "interpreter/interpreterRuntime.hpp"
 #include "logging/log.hpp"
 #include "oops/arrayOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/methodData.hpp"
 #include "oops/method.hpp"
 #include "prims/jvmtiExport.hpp"
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Wed Aug 28 11:58:56 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
@@ -1620,8 +1620,8 @@
 // See also: cmpFastLock and cmpFastUnlock.
 //
 // What follows is a specialized inline transliteration of the code
-// in slow_enter() and slow_exit().  If we're concerned about I$ bloat
-// another option would be to emit TrySlowEnter and TrySlowExit methods
+// in enter() and exit(). If we're concerned about I$ bloat another
+// option would be to emit TrySlowEnter and TrySlowExit methods
 // at startup-time.  These methods would accept arguments as
 // (rax,=Obj, rbx=Self, rcx=box, rdx=Scratch) and return success-failure
 // indications in the icc.ZFlag.  Fast_Lock and Fast_Unlock would simply
@@ -9905,6 +9905,47 @@
   bind(done);
 }
 
+#ifdef _LP64
+void MacroAssembler::cache_wb(Address line)
+{
+  // 64 bit cpus always support clflush
+  assert(VM_Version::supports_clflush(), "clflush should be available");
+  bool optimized = VM_Version::supports_clflushopt();
+  bool no_evict = VM_Version::supports_clwb();
+
+  // prefer clwb (writeback without evict) otherwise
+  // prefer clflushopt (potentially parallel writeback with evict)
+  // otherwise fallback on clflush (serial writeback with evict)
+
+  if (optimized) {
+    if (no_evict) {
+      clwb(line);
+    } else {
+      clflushopt(line);
+    }
+  } else {
+    // no need for fence when using CLFLUSH
+    clflush(line);
+  }
+}
+
+void MacroAssembler::cache_wbsync(bool is_pre)
+{
+  assert(VM_Version::supports_clflush(), "clflush should be available");
+  bool optimized = VM_Version::supports_clflushopt();
+  bool no_evict = VM_Version::supports_clwb();
+
+  // pick the correct implementation
+
+  if (!is_pre && (optimized || no_evict)) {
+    // need an sfence for post flush when using clflushopt or clwb
+    // otherwise no no need for any synchroniaztion
+
+    sfence();
+  }
+}
+#endif // _LP64
+
 Assembler::Condition MacroAssembler::negate_condition(Assembler::Condition cond) {
   switch (cond) {
     // Note some conditions are synonyms for others
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1801,6 +1801,10 @@
   void byte_array_inflate(Register src, Register dst, Register len,
                           XMMRegister tmp1, Register tmp2);
 
+#ifdef _LP64
+  void cache_wb(Address line);
+  void cache_wbsync(bool is_pre);
+#endif // _LP64
 };
 
 /**
--- a/src/hotspot/cpu/x86/sharedRuntime_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -72,7 +72,7 @@
 #ifdef _LP64
   // Read the header and build a mask to get its hash field.
   // Depend on hash_mask being at most 32 bits and avoid the use of hash_mask_in_place
-  // because it could be larger than 32 bits in a 64-bit vm. See markOop.hpp.
+  // because it could be larger than 32 bits in a 64-bit vm. See markWord.hpp.
   __ shrptr(result, markWord::hash_shift);
   __ andptr(result, markWord::hash_mask);
 #else
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -2909,6 +2909,45 @@
     return start;
   }
 
+  address generate_data_cache_writeback() {
+    const Register src        = c_rarg0;  // source address
+
+    __ align(CodeEntryAlignment);
+
+    StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback");
+
+    address start = __ pc();
+    __ enter();
+    __ cache_wb(Address(src, 0));
+    __ leave();
+    __ ret(0);
+
+    return start;
+  }
+
+  address generate_data_cache_writeback_sync() {
+    const Register is_pre    = c_rarg0;  // pre or post sync
+
+    __ align(CodeEntryAlignment);
+
+    StubCodeMark mark(this, "StubRoutines", "_data_cache_writeback_sync");
+
+    // pre wbsync is a no-op
+    // post wbsync translates to an sfence
+
+    Label skip;
+    address start = __ pc();
+    __ enter();
+    __ cmpl(is_pre, 0);
+    __ jcc(Assembler::notEqual, skip);
+    __ cache_wbsync(false);
+    __ bind(skip);
+    __ leave();
+    __ ret(0);
+
+    return start;
+  }
+
   void generate_arraycopy_stubs() {
     address entry;
     address entry_jbyte_arraycopy;
@@ -5998,6 +6037,10 @@
     // support for verify_oop (must happen after universe_init)
     StubRoutines::_verify_oop_subroutine_entry = generate_verify_oop();
 
+    // data cache line writeback
+    StubRoutines::_data_cache_writeback = generate_data_cache_writeback();
+    StubRoutines::_data_cache_writeback_sync = generate_data_cache_writeback_sync();
+
     // arraycopy stubs used by compilers
     generate_arraycopy_stubs();
 
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -35,6 +35,7 @@
 #include "utilities/virtualizationSupport.hpp"
 #include "vm_version_x86.hpp"
 
+#include OS_HEADER_INLINE(os)
 
 int VM_Version::_cpu;
 int VM_Version::_model;
@@ -608,6 +609,16 @@
   guarantee(_cpuid_info.std_cpuid1_ebx.bits.clflush_size == 8, "such clflush size is not supported");
 #endif
 
+#ifdef _LP64
+  // assigning this field effectively enables Unsafe.writebackMemory()
+  // by initing UnsafeConstant.DATA_CACHE_LINE_FLUSH_SIZE to non-zero
+  // that is only implemented on x86_64 and only if the OS plays ball
+  if (os::supports_map_sync()) {
+    // publish data cache line flush size to generic field, otherwise
+    // let if default to zero thereby disabling writeback
+    _data_cache_line_flush_size = _cpuid_info.std_cpuid1_ebx.bits.clflush_size * 8;
+  }
+#endif
   // If the OS doesn't support SSE, we can't use this feature even if the HW does
   if (!os::supports_sse())
     _features &= ~(CPU_SSE|CPU_SSE2|CPU_SSE3|CPU_SSSE3|CPU_SSE4A|CPU_SSE4_1|CPU_SSE4_2);
--- a/src/hotspot/cpu/x86/vm_version_x86.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/vm_version_x86.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,6 +25,7 @@
 #ifndef CPU_X86_VM_VERSION_X86_HPP
 #define CPU_X86_VM_VERSION_X86_HPP
 
+#include "memory/universe.hpp"
 #include "runtime/globals_extension.hpp"
 #include "runtime/vm_version.hpp"
 
@@ -218,7 +219,10 @@
                avx512dq : 1,
                         : 1,
                     adx : 1,
-                        : 6,
+                        : 3,
+             clflushopt : 1,
+                   clwb : 1,
+                        : 1,
                avx512pf : 1,
                avx512er : 1,
                avx512cd : 1,
@@ -338,7 +342,11 @@
 #define CPU_VAES ((uint64_t)UCONST64(0x8000000000))    // Vector AES instructions
 #define CPU_VNNI ((uint64_t)UCONST64(0x10000000000))   // Vector Neural Network Instructions
 
-  enum Extended_Family {
+#define CPU_FLUSH ((uint64_t)UCONST64(0x20000000000))  // flush instruction
+#define CPU_FLUSHOPT ((uint64_t)UCONST64(0x40000000000)) // flushopt instruction
+#define CPU_CLWB ((uint64_t)UCONST64(0x80000000000))   // clwb instruction
+
+enum Extended_Family {
     // AMD
     CPU_FAMILY_AMD_11H       = 0x11,
     // ZX
@@ -495,6 +503,14 @@
       result |= CPU_CX8;
     if (_cpuid_info.std_cpuid1_edx.bits.cmov != 0)
       result |= CPU_CMOV;
+    if (_cpuid_info.std_cpuid1_edx.bits.clflush != 0)
+      result |= CPU_FLUSH;
+#ifdef _LP64
+    // clflush should always be available on x86_64
+    // if not we are in real trouble because we rely on it
+    // to flush the code cache.
+    assert ((result & CPU_FLUSH) != 0, "clflush should be available");
+#endif
     if (_cpuid_info.std_cpuid1_edx.bits.fxsr != 0 || (is_amd_family() &&
         _cpuid_info.ext_cpuid1_edx.bits.fxsr != 0))
       result |= CPU_FXSR;
@@ -575,6 +591,8 @@
       result |= CPU_SHA;
     if (_cpuid_info.std_cpuid1_ecx.bits.fma != 0)
       result |= CPU_FMA;
+    if (_cpuid_info.sef_cpuid7_ebx.bits.clflushopt != 0)
+      result |= CPU_FLUSHOPT;
 
     // AMD|Hygon features.
     if (is_amd_family()) {
@@ -594,6 +612,9 @@
       if (_cpuid_info.ext_cpuid1_ecx.bits.misalignsse != 0) {
         result |= CPU_3DNOW_PREFETCH;
       }
+      if (_cpuid_info.sef_cpuid7_ebx.bits.clwb != 0) {
+        result |= CPU_CLWB;
+      }
     }
 
     // ZX features.
@@ -941,6 +962,44 @@
     return LP64_ONLY(true) NOT_LP64(false); // not implemented on x86_32
   }
 
+  // there are several insns to force cache line sync to memory which
+  // we can use to ensure mapped non-volatile memory is up to date with
+  // pending in-cache changes.
+  //
+  // 64 bit cpus always support clflush which writes back and evicts
+  // on 32 bit cpus support is recorded via a feature flag
+  //
+  // clflushopt is optional and acts like clflush except it does
+  // not synchronize with other memory ops. it needs a preceding
+  // and trailing StoreStore fence
+  //
+  // clwb is an optional, intel-specific instruction optional which
+  // writes back without evicting the line. it also does not
+  // synchronize with other memory ops. so, it also needs a preceding
+  // and trailing StoreStore fence.
+
+#ifdef _LP64
+  static bool supports_clflush() {
+    // clflush should always be available on x86_64
+    // if not we are in real trouble because we rely on it
+    // to flush the code cache.
+    // Unfortunately, Assembler::clflush is currently called as part
+    // of generation of the code cache flush routine. This happens
+    // under Universe::init before the processor features are set
+    // up. Assembler::flush calls this routine to check that clflush
+    // is allowed. So, we give the caller a free pass if Universe init
+    // is still in progress.
+    assert ((!Universe::is_fully_initialized() || (_features & CPU_FLUSH) != 0), "clflush should be available");
+    return true;
+  }
+  static bool supports_clflushopt() { return ((_features & CPU_FLUSHOPT) != 0); }
+  static bool supports_clwb() { return ((_features & CPU_CLWB) != 0); }
+#else
+  static bool supports_clflush() { return  ((_features & CPU_FLUSH) != 0); }
+  static bool supports_clflushopt() { return false; }
+  static bool supports_clwb() { return false; }
+#endif // _LP64
+
   // support functions for virtualization detection
  private:
   static void check_virt_cpuid(uint32_t idx, uint32_t *regs);
--- a/src/hotspot/cpu/x86/x86.ad	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/x86.ad	Wed Aug 28 11:58:56 2019 -0400
@@ -1478,6 +1478,13 @@
         ret_value = false;
       break;
 #endif
+    case Op_CacheWB:
+    case Op_CacheWBPreSync:
+    case Op_CacheWBPostSync:
+      if (!VM_Version::supports_data_cache_line_flush()) {
+        ret_value = false;
+      }
+      break;
   }
 
   return ret_value;  // Per default match rules are supported.
--- a/src/hotspot/cpu/x86/x86_64.ad	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/x86/x86_64.ad	Wed Aug 28 11:58:56 2019 -0400
@@ -6565,6 +6565,47 @@
   ins_pipe(pipe_slow); // XXX
 %}
 
+instruct cacheWB(indirect addr)
+%{
+  predicate(VM_Version::supports_data_cache_line_flush());
+  match(CacheWB addr);
+
+  ins_cost(100);
+  format %{"cache wb $addr" %}
+  ins_encode %{
+    assert($addr->index_position() < 0, "should be");
+    assert($addr$$disp == 0, "should be");
+    __ cache_wb(Address($addr$$base$$Register, 0));
+  %}
+  ins_pipe(pipe_slow); // XXX
+%}
+
+instruct cacheWBPreSync()
+%{
+  predicate(VM_Version::supports_data_cache_line_flush());
+  match(CacheWBPreSync);
+
+  ins_cost(100);
+  format %{"cache wb presync" %}
+  ins_encode %{
+    __ cache_wbsync(true);
+  %}
+  ins_pipe(pipe_slow); // XXX
+%}
+
+instruct cacheWBPostSync()
+%{
+  predicate(VM_Version::supports_data_cache_line_flush());
+  match(CacheWBPostSync);
+
+  ins_cost(100);
+  format %{"cache wb postsync" %}
+  ins_encode %{
+    __ cache_wbsync(false);
+  %}
+  ins_pipe(pipe_slow); // XXX
+%}
+
 //----------BSWAP Instructions-------------------------------------------------
 instruct bytes_reverse_int(rRegI dst) %{
   match(Set dst (ReverseBytesI dst));
--- a/src/hotspot/cpu/zero/frame_zero.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/zero/frame_zero.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -29,7 +29,7 @@
 #include "interpreter/interpreterRuntime.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/frame.inline.hpp"
--- a/src/hotspot/cpu/zero/globalDefinitions_zero.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/zero/globalDefinitions_zero.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -30,6 +30,8 @@
 #define SUPPORTS_NATIVE_CX8
 #endif
 
+#define THREAD_LOCAL_POLL
+
 #include <ffi.h>
 
 // Indicates whether the C calling conventions require that
--- a/src/hotspot/cpu/zero/globals_zero.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/cpu/zero/globals_zero.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -76,7 +76,7 @@
 // No performance work done here yet.
 define_pd_global(bool, CompactStrings, false);
 
-define_pd_global(bool, ThreadLocalHandshakes, false);
+define_pd_global(bool, ThreadLocalHandshakes, true);
 
 #define ARCH_FLAGS(develop, \
                    product, \
--- a/src/hotspot/os/aix/os_aix.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/os/aix/os_aix.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -4338,3 +4338,7 @@
   time_t t2 = get_mtime(file2);
   return t1 - t2;
 }
+
+bool os::supports_map_sync() {
+  return false;
+}
--- a/src/hotspot/os/bsd/os_bsd.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/os/bsd/os_bsd.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -3803,6 +3803,10 @@
   return n;
 }
 
+bool os::supports_map_sync() {
+  return false;
+}
+
 #ifndef PRODUCT
 void TestReserveMemorySpecial_test() {
   // No tests available for this platform
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/linux/gc/z/zBackingFile_linux.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,574 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zArray.inline.hpp"
+#include "gc/z/zBackingFile_linux.hpp"
+#include "gc/z/zBackingPath_linux.hpp"
+#include "gc/z/zErrno.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zLargePages.inline.hpp"
+#include "gc/z/zSyscall_linux.hpp"
+#include "logging/log.hpp"
+#include "runtime/init.hpp"
+#include "runtime/os.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+//
+// Support for building on older Linux systems
+//
+
+// memfd_create(2) flags
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC                      0x0001U
+#endif
+#ifndef MFD_HUGETLB
+#define MFD_HUGETLB                      0x0004U
+#endif
+
+// open(2) flags
+#ifndef O_CLOEXEC
+#define O_CLOEXEC                        02000000
+#endif
+#ifndef O_TMPFILE
+#define O_TMPFILE                        (020000000 | O_DIRECTORY)
+#endif
+
+// fallocate(2) flags
+#ifndef FALLOC_FL_KEEP_SIZE
+#define FALLOC_FL_KEEP_SIZE              0x01
+#endif
+#ifndef FALLOC_FL_PUNCH_HOLE
+#define FALLOC_FL_PUNCH_HOLE             0x02
+#endif
+
+// Filesystem types, see statfs(2)
+#ifndef TMPFS_MAGIC
+#define TMPFS_MAGIC                      0x01021994
+#endif
+#ifndef HUGETLBFS_MAGIC
+#define HUGETLBFS_MAGIC                  0x958458f6
+#endif
+
+// Filesystem names
+#define ZFILESYSTEM_TMPFS                "tmpfs"
+#define ZFILESYSTEM_HUGETLBFS            "hugetlbfs"
+
+// Sysfs file for transparent huge page on tmpfs
+#define ZFILENAME_SHMEM_ENABLED          "/sys/kernel/mm/transparent_hugepage/shmem_enabled"
+
+// Java heap filename
+#define ZFILENAME_HEAP                   "java_heap"
+
+// Preferred tmpfs mount points, ordered by priority
+static const char* z_preferred_tmpfs_mountpoints[] = {
+  "/dev/shm",
+  "/run/shm",
+  NULL
+};
+
+// Preferred hugetlbfs mount points, ordered by priority
+static const char* z_preferred_hugetlbfs_mountpoints[] = {
+  "/dev/hugepages",
+  "/hugepages",
+  NULL
+};
+
+static int z_fallocate_hugetlbfs_attempts = 3;
+static bool z_fallocate_supported = true;
+
+ZBackingFile::ZBackingFile() :
+    _fd(-1),
+    _size(0),
+    _filesystem(0),
+    _block_size(0),
+    _available(0),
+    _initialized(false) {
+
+  // Create backing file
+  _fd = create_fd(ZFILENAME_HEAP);
+  if (_fd == -1) {
+    return;
+  }
+
+  // Get filesystem statistics
+  struct statfs buf;
+  if (fstatfs(_fd, &buf) == -1) {
+    ZErrno err;
+    log_error(gc)("Failed to determine filesystem type for backing file (%s)", err.to_string());
+    return;
+  }
+
+  _filesystem = buf.f_type;
+  _block_size = buf.f_bsize;
+  _available = buf.f_bavail * _block_size;
+
+  // Make sure we're on a supported filesystem
+  if (!is_tmpfs() && !is_hugetlbfs()) {
+    log_error(gc)("Backing file must be located on a %s or a %s filesystem",
+                  ZFILESYSTEM_TMPFS, ZFILESYSTEM_HUGETLBFS);
+    return;
+  }
+
+  // Make sure the filesystem type matches requested large page type
+  if (ZLargePages::is_transparent() && !is_tmpfs()) {
+    log_error(gc)("-XX:+UseTransparentHugePages can only be enable when using a %s filesystem",
+                  ZFILESYSTEM_TMPFS);
+    return;
+  }
+
+  if (ZLargePages::is_transparent() && !tmpfs_supports_transparent_huge_pages()) {
+    log_error(gc)("-XX:+UseTransparentHugePages on a %s filesystem not supported by kernel",
+                  ZFILESYSTEM_TMPFS);
+    return;
+  }
+
+  if (ZLargePages::is_explicit() && !is_hugetlbfs()) {
+    log_error(gc)("-XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled "
+                  "when using a %s filesystem", ZFILESYSTEM_HUGETLBFS);
+    return;
+  }
+
+  if (!ZLargePages::is_explicit() && is_hugetlbfs()) {
+    log_error(gc)("-XX:+UseLargePages must be enabled when using a %s filesystem",
+                  ZFILESYSTEM_HUGETLBFS);
+    return;
+  }
+
+  const size_t expected_block_size = is_tmpfs() ? os::vm_page_size() : os::large_page_size();
+  if (expected_block_size != _block_size) {
+    log_error(gc)("%s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT ")",
+                  is_tmpfs() ? ZFILESYSTEM_TMPFS : ZFILESYSTEM_HUGETLBFS, _block_size, expected_block_size);
+    return;
+  }
+
+  // Successfully initialized
+  _initialized = true;
+}
+
+int ZBackingFile::create_mem_fd(const char* name) const {
+  // Create file name
+  char filename[PATH_MAX];
+  snprintf(filename, sizeof(filename), "%s%s", name, ZLargePages::is_explicit() ? ".hugetlb" : "");
+
+  // Create file
+  const int extra_flags = ZLargePages::is_explicit() ? MFD_HUGETLB : 0;
+  const int fd = ZSyscall::memfd_create(filename, MFD_CLOEXEC | extra_flags);
+  if (fd == -1) {
+    ZErrno err;
+    log_debug(gc, init)("Failed to create memfd file (%s)",
+                        ((ZLargePages::is_explicit() && err == EINVAL) ? "Hugepages not supported" : err.to_string()));
+    return -1;
+  }
+
+  log_info(gc, init)("Heap backed by file: /memfd:%s", filename);
+
+  return fd;
+}
+
+int ZBackingFile::create_file_fd(const char* name) const {
+  const char* const filesystem = ZLargePages::is_explicit()
+                                 ? ZFILESYSTEM_HUGETLBFS
+                                 : ZFILESYSTEM_TMPFS;
+  const char** const preferred_mountpoints = ZLargePages::is_explicit()
+                                             ? z_preferred_hugetlbfs_mountpoints
+                                             : z_preferred_tmpfs_mountpoints;
+
+  // Find mountpoint
+  ZBackingPath path(filesystem, preferred_mountpoints);
+  if (path.get() == NULL) {
+    log_error(gc)("Use -XX:ZPath to specify the path to a %s filesystem", filesystem);
+    return -1;
+  }
+
+  // Try to create an anonymous file using the O_TMPFILE flag. Note that this
+  // flag requires kernel >= 3.11. If this fails we fall back to open/unlink.
+  const int fd_anon = os::open(path.get(), O_TMPFILE|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
+  if (fd_anon == -1) {
+    ZErrno err;
+    log_debug(gc, init)("Failed to create anonymous file in %s (%s)", path.get(),
+                        (err == EINVAL ? "Not supported" : err.to_string()));
+  } else {
+    // Get inode number for anonymous file
+    struct stat stat_buf;
+    if (fstat(fd_anon, &stat_buf) == -1) {
+      ZErrno err;
+      log_error(gc)("Failed to determine inode number for anonymous file (%s)", err.to_string());
+      return -1;
+    }
+
+    log_info(gc, init)("Heap backed by file: %s/#" UINT64_FORMAT, path.get(), (uint64_t)stat_buf.st_ino);
+
+    return fd_anon;
+  }
+
+  log_debug(gc, init)("Falling back to open/unlink");
+
+  // Create file name
+  char filename[PATH_MAX];
+  snprintf(filename, sizeof(filename), "%s/%s.%d", path.get(), name, os::current_process_id());
+
+  // Create file
+  const int fd = os::open(filename, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
+  if (fd == -1) {
+    ZErrno err;
+    log_error(gc)("Failed to create file %s (%s)", filename, err.to_string());
+    return -1;
+  }
+
+  // Unlink file
+  if (unlink(filename) == -1) {
+    ZErrno err;
+    log_error(gc)("Failed to unlink file %s (%s)", filename, err.to_string());
+    return -1;
+  }
+
+  log_info(gc, init)("Heap backed by file: %s", filename);
+
+  return fd;
+}
+
+int ZBackingFile::create_fd(const char* name) const {
+  if (ZPath == NULL) {
+    // If the path is not explicitly specified, then we first try to create a memfd file
+    // instead of looking for a tmpfd/hugetlbfs mount point. Note that memfd_create() might
+    // not be supported at all (requires kernel >= 3.17), or it might not support large
+    // pages (requires kernel >= 4.14). If memfd_create() fails, then we try to create a
+    // file on an accessible tmpfs or hugetlbfs mount point.
+    const int fd = create_mem_fd(name);
+    if (fd != -1) {
+      return fd;
+    }
+
+    log_debug(gc, init)("Falling back to searching for an accessible mount point");
+  }
+
+  return create_file_fd(name);
+}
+
+bool ZBackingFile::is_initialized() const {
+  return _initialized;
+}
+
+int ZBackingFile::fd() const {
+  return _fd;
+}
+
+size_t ZBackingFile::size() const {
+  return _size;
+}
+
+size_t ZBackingFile::available() const {
+  return _available;
+}
+
+bool ZBackingFile::is_tmpfs() const {
+  return _filesystem == TMPFS_MAGIC;
+}
+
+bool ZBackingFile::is_hugetlbfs() const {
+  return _filesystem == HUGETLBFS_MAGIC;
+}
+
+bool ZBackingFile::tmpfs_supports_transparent_huge_pages() const {
+  // If the shmem_enabled file exists and is readable then we
+  // know the kernel supports transparent huge pages for tmpfs.
+  return access(ZFILENAME_SHMEM_ENABLED, R_OK) == 0;
+}
+
+ZErrno ZBackingFile::fallocate_compat_ftruncate(size_t size) const {
+  while (ftruncate(_fd, size) == -1) {
+    if (errno != EINTR) {
+      // Failed
+      return errno;
+    }
+  }
+
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::fallocate_compat_mmap(size_t offset, size_t length, bool touch) const {
+  // On hugetlbfs, mapping a file segment will fail immediately, without
+  // the need to touch the mapped pages first, if there aren't enough huge
+  // pages available to back the mapping.
+  void* const addr = mmap(0, length, PROT_READ|PROT_WRITE, MAP_SHARED, _fd, offset);
+  if (addr == MAP_FAILED) {
+    // Failed
+    return errno;
+  }
+
+  // Once mapped, the huge pages are only reserved. We need to touch them
+  // to associate them with the file segment. Note that we can not punch
+  // hole in file segments which only have reserved pages.
+  if (touch) {
+    char* const start = (char*)addr;
+    char* const end = start + length;
+    os::pretouch_memory(start, end, _block_size);
+  }
+
+  // Unmap again. From now on, the huge pages that were mapped are allocated
+  // to this file. There's no risk in getting SIGBUS when touching them.
+  if (munmap(addr, length) == -1) {
+    // Failed
+    return errno;
+  }
+
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::fallocate_compat_pwrite(size_t offset, size_t length) const {
+  uint8_t data = 0;
+
+  // Allocate backing memory by writing to each block
+  for (size_t pos = offset; pos < offset + length; pos += _block_size) {
+    if (pwrite(_fd, &data, sizeof(data), pos) == -1) {
+      // Failed
+      return errno;
+    }
+  }
+
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::fallocate_fill_hole_compat(size_t offset, size_t length) {
+  // fallocate(2) is only supported by tmpfs since Linux 3.5, and by hugetlbfs
+  // since Linux 4.3. When fallocate(2) is not supported we emulate it using
+  // ftruncate/pwrite (for tmpfs) or ftruncate/mmap/munmap (for hugetlbfs).
+
+  const size_t end = offset + length;
+  if (end > _size) {
+    // Increase file size
+    const ZErrno err = fallocate_compat_ftruncate(end);
+    if (err) {
+      // Failed
+      return err;
+    }
+  }
+
+  // Allocate backing memory
+  const ZErrno err = is_hugetlbfs() ? fallocate_compat_mmap(offset, length, false /* touch */)
+                                    : fallocate_compat_pwrite(offset, length);
+  if (err) {
+    if (end > _size) {
+      // Restore file size
+      fallocate_compat_ftruncate(_size);
+    }
+
+    // Failed
+    return err;
+  }
+
+  if (end > _size) {
+    // Record new file size
+    _size = end;
+  }
+
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::fallocate_fill_hole_syscall(size_t offset, size_t length) {
+  const int mode = 0; // Allocate
+  const int res = ZSyscall::fallocate(_fd, mode, offset, length);
+  if (res == -1) {
+    // Failed
+    return errno;
+  }
+
+  const size_t end = offset + length;
+  if (end > _size) {
+    // Record new file size
+    _size = end;
+  }
+
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::fallocate_fill_hole(size_t offset, size_t length) {
+  // Using compat mode is more efficient when allocating space on hugetlbfs.
+  // Note that allocating huge pages this way will only reserve them, and not
+  // associate them with segments of the file. We must guarantee that we at
+  // some point touch these segments, otherwise we can not punch hole in them.
+  if (z_fallocate_supported && !is_hugetlbfs()) {
+     const ZErrno err = fallocate_fill_hole_syscall(offset, length);
+     if (!err) {
+       // Success
+       return 0;
+     }
+
+     if (err != ENOSYS && err != EOPNOTSUPP) {
+       // Failed
+       return err;
+     }
+
+     // Not supported
+     log_debug(gc)("Falling back to fallocate() compatibility mode");
+     z_fallocate_supported = false;
+  }
+
+  return fallocate_fill_hole_compat(offset, length);
+}
+
+ZErrno ZBackingFile::fallocate_punch_hole(size_t offset, size_t length) {
+  if (is_hugetlbfs()) {
+    // We can only punch hole in pages that have been touched. Non-touched
+    // pages are only reserved, and not associated with any specific file
+    // segment. We don't know which pages have been previously touched, so
+    // we always touch them here to guarantee that we can punch hole.
+    const ZErrno err = fallocate_compat_mmap(offset, length, true /* touch */);
+    if (err) {
+      // Failed
+      return err;
+    }
+  }
+
+  const int mode = FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE;
+  if (ZSyscall::fallocate(_fd, mode, offset, length) == -1) {
+    // Failed
+    return errno;
+  }
+
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::split_and_fallocate(bool punch_hole, size_t offset, size_t length) {
+  // Try first half
+  const size_t offset0 = offset;
+  const size_t length0 = align_up(length / 2, _block_size);
+  const ZErrno err0 = fallocate(punch_hole, offset0, length0);
+  if (err0) {
+    return err0;
+  }
+
+  // Try second half
+  const size_t offset1 = offset0 + length0;
+  const size_t length1 = length - length0;
+  const ZErrno err1 = fallocate(punch_hole, offset1, length1);
+  if (err1) {
+    return err1;
+  }
+
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::fallocate(bool punch_hole, size_t offset, size_t length) {
+  assert(is_aligned(offset, _block_size), "Invalid offset");
+  assert(is_aligned(length, _block_size), "Invalid length");
+
+  const ZErrno err = punch_hole ? fallocate_punch_hole(offset, length) : fallocate_fill_hole(offset, length);
+  if (err == EINTR && length > _block_size) {
+    // Calling fallocate(2) with a large length can take a long time to
+    // complete. When running profilers, such as VTune, this syscall will
+    // be constantly interrupted by signals. Expanding the file in smaller
+    // steps avoids this problem.
+    return split_and_fallocate(punch_hole, offset, length);
+  }
+
+  return err;
+}
+
+bool ZBackingFile::commit_inner(size_t offset, size_t length) {
+  log_trace(gc, heap)("Committing memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
+                      offset / M, (offset + length) / M, length / M);
+
+retry:
+  const ZErrno err = fallocate(false /* punch_hole */, offset, length);
+  if (err) {
+    if (err == ENOSPC && !is_init_completed() && is_hugetlbfs() && z_fallocate_hugetlbfs_attempts-- > 0) {
+      // If we fail to allocate during initialization, due to lack of space on
+      // the hugetlbfs filesystem, then we wait and retry a few times before
+      // giving up. Otherwise there is a risk that running JVMs back-to-back
+      // will fail, since there is a delay between process termination and the
+      // huge pages owned by that process being returned to the huge page pool
+      // and made available for new allocations.
+      log_debug(gc, init)("Failed to commit memory (%s), retrying", err.to_string());
+
+      // Wait and retry in one second, in the hope that huge pages will be
+      // available by then.
+      sleep(1);
+      goto retry;
+    }
+
+    // Failed
+    log_error(gc)("Failed to commit memory (%s)", err.to_string());
+    return false;
+  }
+
+  // Success
+  return true;
+}
+
+size_t ZBackingFile::commit(size_t offset, size_t length) {
+  // Try to commit the whole region
+  if (commit_inner(offset, length)) {
+    // Success
+    return length;
+  }
+
+  // Failed, try to commit as much as possible
+  size_t start = offset;
+  size_t end = offset + length;
+
+  for (;;) {
+    length = align_down((end - start) / 2, ZGranuleSize);
+    if (length < ZGranuleSize) {
+      // Done, don't commit more
+      return start - offset;
+    }
+
+    if (commit_inner(start, length)) {
+      // Success, try commit more
+      start += length;
+    } else {
+      // Failed, try commit less
+      end -= length;
+    }
+  }
+}
+
+size_t ZBackingFile::uncommit(size_t offset, size_t length) {
+  log_trace(gc, heap)("Uncommitting memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
+                      offset / M, (offset + length) / M, length / M);
+
+  const ZErrno err = fallocate(true /* punch_hole */, offset, length);
+  if (err) {
+    log_error(gc)("Failed to uncommit memory (%s)", err.to_string());
+    return 0;
+  }
+
+  return length;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/linux/gc/z/zBackingFile_linux.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,73 @@
+/*
+ * 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
+ * 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 OS_LINUX_GC_Z_ZBACKINGFILE_LINUX_HPP
+#define OS_LINUX_GC_Z_ZBACKINGFILE_LINUX_HPP
+
+#include "memory/allocation.hpp"
+
+class ZErrno;
+
+class ZBackingFile {
+private:
+  int      _fd;
+  size_t   _size;
+  uint64_t _filesystem;
+  size_t   _block_size;
+  size_t   _available;
+  bool     _initialized;
+
+  int create_mem_fd(const char* name) const;
+  int create_file_fd(const char* name) const;
+  int create_fd(const char* name) const;
+
+  bool is_tmpfs() const;
+  bool is_hugetlbfs() const;
+  bool tmpfs_supports_transparent_huge_pages() const;
+
+  ZErrno fallocate_compat_ftruncate(size_t size) const;
+  ZErrno fallocate_compat_mmap(size_t offset, size_t length, bool reserve_only) const;
+  ZErrno fallocate_compat_pwrite(size_t offset, size_t length) const;
+  ZErrno fallocate_fill_hole_compat(size_t offset, size_t length);
+  ZErrno fallocate_fill_hole_syscall(size_t offset, size_t length);
+  ZErrno fallocate_fill_hole(size_t offset, size_t length);
+  ZErrno fallocate_punch_hole(size_t offset, size_t length);
+  ZErrno split_and_fallocate(bool punch_hole, size_t offset, size_t length);
+  ZErrno fallocate(bool punch_hole, size_t offset, size_t length);
+
+  bool commit_inner(size_t offset, size_t length);
+
+public:
+  ZBackingFile();
+
+  bool is_initialized() const;
+
+  int fd() const;
+  size_t size() const;
+  size_t available() const;
+
+  size_t commit(size_t offset, size_t length);
+  size_t uncommit(size_t offset, size_t length);
+};
+
+#endif // OS_LINUX_GC_Z_ZBACKINGFILE_LINUX_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/linux/gc/z/zBackingPath_linux.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zArray.inline.hpp"
+#include "gc/z/zBackingPath_linux.hpp"
+#include "gc/z/zErrno.hpp"
+#include "logging/log.hpp"
+
+#include <stdio.h>
+#include <unistd.h>
+
+// Mount information, see proc(5) for more details.
+#define PROC_SELF_MOUNTINFO        "/proc/self/mountinfo"
+
+ZBackingPath::ZBackingPath(const char* filesystem, const char** preferred_mountpoints) {
+  if (ZPath != NULL) {
+    // Use specified path
+    _path = strdup(ZPath);
+  } else {
+    // Find suitable path
+    _path = find_mountpoint(filesystem, preferred_mountpoints);
+  }
+}
+
+ZBackingPath::~ZBackingPath() {
+  free(_path);
+  _path = NULL;
+}
+
+char* ZBackingPath::get_mountpoint(const char* line, const char* filesystem) const {
+  char* line_mountpoint = NULL;
+  char* line_filesystem = NULL;
+
+  // Parse line and return a newly allocated string containing the mount point if
+  // the line contains a matching filesystem and the mount point is accessible by
+  // the current user.
+  if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-]- %ms", &line_mountpoint, &line_filesystem) != 2 ||
+      strcmp(line_filesystem, filesystem) != 0 ||
+      access(line_mountpoint, R_OK|W_OK|X_OK) != 0) {
+    // Not a matching or accessible filesystem
+    free(line_mountpoint);
+    line_mountpoint = NULL;
+  }
+
+  free(line_filesystem);
+
+  return line_mountpoint;
+}
+
+void ZBackingPath::get_mountpoints(const char* filesystem, ZArray<char*>* mountpoints) const {
+  FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r");
+  if (fd == NULL) {
+    ZErrno err;
+    log_error(gc)("Failed to open %s: %s", PROC_SELF_MOUNTINFO, err.to_string());
+    return;
+  }
+
+  char* line = NULL;
+  size_t length = 0;
+
+  while (getline(&line, &length, fd) != -1) {
+    char* const mountpoint = get_mountpoint(line, filesystem);
+    if (mountpoint != NULL) {
+      mountpoints->add(mountpoint);
+    }
+  }
+
+  free(line);
+  fclose(fd);
+}
+
+void ZBackingPath::free_mountpoints(ZArray<char*>* mountpoints) const {
+  ZArrayIterator<char*> iter(mountpoints);
+  for (char* mountpoint; iter.next(&mountpoint);) {
+    free(mountpoint);
+  }
+  mountpoints->clear();
+}
+
+char* ZBackingPath::find_preferred_mountpoint(const char* filesystem,
+                                              ZArray<char*>* mountpoints,
+                                              const char** preferred_mountpoints) const {
+  // Find preferred mount point
+  ZArrayIterator<char*> iter1(mountpoints);
+  for (char* mountpoint; iter1.next(&mountpoint);) {
+    for (const char** preferred = preferred_mountpoints; *preferred != NULL; preferred++) {
+      if (!strcmp(mountpoint, *preferred)) {
+        // Preferred mount point found
+        return strdup(mountpoint);
+      }
+    }
+  }
+
+  // Preferred mount point not found
+  log_error(gc)("More than one %s filesystem found:", filesystem);
+  ZArrayIterator<char*> iter2(mountpoints);
+  for (char* mountpoint; iter2.next(&mountpoint);) {
+    log_error(gc)("  %s", mountpoint);
+  }
+
+  return NULL;
+}
+
+char* ZBackingPath::find_mountpoint(const char* filesystem, const char** preferred_mountpoints) const {
+  char* path = NULL;
+  ZArray<char*> mountpoints;
+
+  get_mountpoints(filesystem, &mountpoints);
+
+  if (mountpoints.size() == 0) {
+    // No mount point found
+    log_error(gc)("Failed to find an accessible %s filesystem", filesystem);
+  } else if (mountpoints.size() == 1) {
+    // One mount point found
+    path = strdup(mountpoints.at(0));
+  } else {
+    // More than one mount point found
+    path = find_preferred_mountpoint(filesystem, &mountpoints, preferred_mountpoints);
+  }
+
+  free_mountpoints(&mountpoints);
+
+  return path;
+}
+
+const char* ZBackingPath::get() const {
+  return _path;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/linux/gc/z/zBackingPath_linux.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 OS_LINUX_GC_Z_ZBACKINGPATH_LINUX_HPP
+#define OS_LINUX_GC_Z_ZBACKINGPATH_LINUX_HPP
+
+#include "gc/z/zArray.hpp"
+#include "memory/allocation.hpp"
+
+class ZBackingPath : public StackObj {
+private:
+  char* _path;
+
+  char* get_mountpoint(const char* line,
+                       const char* filesystem) const;
+  void get_mountpoints(const char* filesystem,
+                       ZArray<char*>* mountpoints) const;
+  void free_mountpoints(ZArray<char*>* mountpoints) const;
+  char* find_preferred_mountpoint(const char* filesystem,
+                                  ZArray<char*>* mountpoints,
+                                  const char** preferred_mountpoints) const;
+  char* find_mountpoint(const char* filesystem,
+                        const char** preferred_mountpoints) const;
+
+public:
+  ZBackingPath(const char* filesystem, const char** preferred_mountpoints);
+  ~ZBackingPath();
+
+  const char* get() const;
+};
+
+#endif // OS_LINUX_GC_Z_ZBACKINGPATH_LINUX_HPP
--- a/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -24,6 +24,7 @@
 #include "gc/z/zErrno.hpp"
 #include "gc/z/zCPU.hpp"
 #include "gc/z/zNUMA.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/os.hpp"
 #include "utilities/debug.hpp"
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,333 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zAddress.inline.hpp"
+#include "gc/z/zErrno.hpp"
+#include "gc/z/zGlobals.hpp"
+#include "gc/z/zLargePages.inline.hpp"
+#include "gc/z/zMemory.hpp"
+#include "gc/z/zNUMA.hpp"
+#include "gc/z/zPhysicalMemory.inline.hpp"
+#include "gc/z/zPhysicalMemoryBacking_linux.hpp"
+#include "logging/log.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/init.hpp"
+#include "runtime/os.hpp"
+#include "utilities/align.hpp"
+#include "utilities/debug.hpp"
+
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+//
+// Support for building on older Linux systems
+//
+
+// madvise(2) flags
+#ifndef MADV_HUGEPAGE
+#define MADV_HUGEPAGE                        14
+#endif
+
+// Proc file entry for max map mount
+#define ZFILENAME_PROC_MAX_MAP_COUNT         "/proc/sys/vm/max_map_count"
+
+bool ZPhysicalMemoryBacking::is_initialized() const {
+  return _file.is_initialized();
+}
+
+void ZPhysicalMemoryBacking::warn_available_space(size_t max) const {
+  // Note that the available space on a tmpfs or a hugetlbfs filesystem
+  // will be zero if no size limit was specified when it was mounted.
+  const size_t available = _file.available();
+  if (available == 0) {
+    // No size limit set, skip check
+    log_info(gc, init)("Available space on backing filesystem: N/A");
+    return;
+  }
+
+  log_info(gc, init)("Available space on backing filesystem: " SIZE_FORMAT "M", available / M);
+
+  // Warn if the filesystem doesn't currently have enough space available to hold
+  // the max heap size. The max heap size will be capped if we later hit this limit
+  // when trying to expand the heap.
+  if (available < max) {
+    log_warning(gc)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****");
+    log_warning(gc)("Not enough space available on the backing filesystem to hold the current max Java heap");
+    log_warning(gc)("size (" SIZE_FORMAT "M). Please adjust the size of the backing filesystem accordingly "
+                    "(available", max / M);
+    log_warning(gc)("space is currently " SIZE_FORMAT "M). Continuing execution with the current filesystem "
+                    "size could", available / M);
+    log_warning(gc)("lead to a premature OutOfMemoryError being thrown, due to failure to map memory.");
+  }
+}
+
+void ZPhysicalMemoryBacking::warn_max_map_count(size_t max) const {
+  const char* const filename = ZFILENAME_PROC_MAX_MAP_COUNT;
+  FILE* const file = fopen(filename, "r");
+  if (file == NULL) {
+    // Failed to open file, skip check
+    log_debug(gc, init)("Failed to open %s", filename);
+    return;
+  }
+
+  size_t actual_max_map_count = 0;
+  const int result = fscanf(file, SIZE_FORMAT, &actual_max_map_count);
+  fclose(file);
+  if (result != 1) {
+    // Failed to read file, skip check
+    log_debug(gc, init)("Failed to read %s", filename);
+    return;
+  }
+
+  // The required max map count is impossible to calculate exactly since subsystems
+  // other than ZGC are also creating memory mappings, and we have no control over that.
+  // However, ZGC tends to create the most mappings and dominate the total count.
+  // In the worst cases, ZGC will map each granule three times, i.e. once per heap view.
+  // We speculate that we need another 20% to allow for non-ZGC subsystems to map memory.
+  const size_t required_max_map_count = (max / ZGranuleSize) * 3 * 1.2;
+  if (actual_max_map_count < required_max_map_count) {
+    log_warning(gc)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****");
+    log_warning(gc)("The system limit on number of memory mappings per process might be too low for the given");
+    log_warning(gc)("max Java heap size (" SIZE_FORMAT "M). Please adjust %s to allow for at",
+                    max / M, filename);
+    log_warning(gc)("least " SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT "). Continuing execution "
+                    "with the current", required_max_map_count, actual_max_map_count);
+    log_warning(gc)("limit could lead to a fatal error, due to failure to map memory.");
+  }
+}
+
+void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
+  // Warn if available space is too low
+  warn_available_space(max);
+
+  // Warn if max map count is too low
+  warn_max_map_count(max);
+}
+
+bool ZPhysicalMemoryBacking::supports_uncommit() {
+  assert(!is_init_completed(), "Invalid state");
+  assert(_file.size() >= ZGranuleSize, "Invalid size");
+
+  // Test if uncommit is supported by uncommitting and then re-committing a granule
+  return commit(uncommit(ZGranuleSize)) == ZGranuleSize;
+}
+
+size_t ZPhysicalMemoryBacking::commit(size_t size) {
+  size_t committed = 0;
+
+  // Fill holes in the backing file
+  while (committed < size) {
+    size_t allocated = 0;
+    const size_t remaining = size - committed;
+    const uintptr_t start = _uncommitted.alloc_from_front_at_most(remaining, &allocated);
+    if (start == UINTPTR_MAX) {
+      // No holes to commit
+      break;
+    }
+
+    // Try commit hole
+    const size_t filled = _file.commit(start, allocated);
+    if (filled > 0) {
+      // Successful or partialy successful
+      _committed.free(start, filled);
+      committed += filled;
+    }
+    if (filled < allocated) {
+      // Failed or partialy failed
+      _uncommitted.free(start + filled, allocated - filled);
+      return committed;
+    }
+  }
+
+  // Expand backing file
+  if (committed < size) {
+    const size_t remaining = size - committed;
+    const uintptr_t start = _file.size();
+    const size_t expanded = _file.commit(start, remaining);
+    if (expanded > 0) {
+      // Successful or partialy successful
+      _committed.free(start, expanded);
+      committed += expanded;
+    }
+  }
+
+  return committed;
+}
+
+size_t ZPhysicalMemoryBacking::uncommit(size_t size) {
+  size_t uncommitted = 0;
+
+  // Punch holes in backing file
+  while (uncommitted < size) {
+    size_t allocated = 0;
+    const size_t remaining = size - uncommitted;
+    const uintptr_t start = _committed.alloc_from_back_at_most(remaining, &allocated);
+    assert(start != UINTPTR_MAX, "Allocation should never fail");
+
+    // Try punch hole
+    const size_t punched = _file.uncommit(start, allocated);
+    if (punched > 0) {
+      // Successful or partialy successful
+      _uncommitted.free(start, punched);
+      uncommitted += punched;
+    }
+    if (punched < allocated) {
+      // Failed or partialy failed
+      _committed.free(start + punched, allocated - punched);
+      return uncommitted;
+    }
+  }
+
+  return uncommitted;
+}
+
+ZPhysicalMemory ZPhysicalMemoryBacking::alloc(size_t size) {
+  assert(is_aligned(size, ZGranuleSize), "Invalid size");
+
+  ZPhysicalMemory pmem;
+
+  // Allocate segments
+  for (size_t allocated = 0; allocated < size; allocated += ZGranuleSize) {
+    const uintptr_t start = _committed.alloc_from_front(ZGranuleSize);
+    assert(start != UINTPTR_MAX, "Allocation should never fail");
+    pmem.add_segment(ZPhysicalMemorySegment(start, ZGranuleSize));
+  }
+
+  return pmem;
+}
+
+void ZPhysicalMemoryBacking::free(const ZPhysicalMemory& pmem) {
+  const size_t nsegments = pmem.nsegments();
+
+  // Free segments
+  for (size_t i = 0; i < nsegments; i++) {
+    const ZPhysicalMemorySegment& segment = pmem.segment(i);
+    _committed.free(segment.start(), segment.size());
+  }
+}
+
+void ZPhysicalMemoryBacking::map_failed(ZErrno err) const {
+  if (err == ENOMEM) {
+    fatal("Failed to map memory. Please check the system limit on number of "
+          "memory mappings allowed per process (see %s)", ZFILENAME_PROC_MAX_MAP_COUNT);
+  } else {
+    fatal("Failed to map memory (%s)", err.to_string());
+  }
+}
+
+void ZPhysicalMemoryBacking::advise_view(uintptr_t addr, size_t size, int advice) const {
+  if (madvise((void*)addr, size, advice) == -1) {
+    ZErrno err;
+    log_error(gc)("Failed to advise on memory (advice %d, %s)", advice, err.to_string());
+  }
+}
+
+void ZPhysicalMemoryBacking::pretouch_view(uintptr_t addr, size_t size) const {
+  const size_t page_size = ZLargePages::is_explicit() ? os::large_page_size() : os::vm_page_size();
+  os::pretouch_memory((void*)addr, (void*)(addr + size), page_size);
+}
+
+void ZPhysicalMemoryBacking::map_view(const ZPhysicalMemory& pmem, uintptr_t addr, bool pretouch) const {
+  const size_t nsegments = pmem.nsegments();
+  size_t size = 0;
+
+  // Map segments
+  for (size_t i = 0; i < nsegments; i++) {
+    const ZPhysicalMemorySegment& segment = pmem.segment(i);
+    const uintptr_t segment_addr = addr + size;
+    const void* const res = mmap((void*)segment_addr, segment.size(), PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, _file.fd(), segment.start());
+    if (res == MAP_FAILED) {
+      ZErrno err;
+      map_failed(err);
+    }
+
+    size += segment.size();
+  }
+
+  // Advise on use of transparent huge pages before touching it
+  if (ZLargePages::is_transparent()) {
+    advise_view(addr, size, MADV_HUGEPAGE);
+  }
+
+  // NUMA interleave memory before touching it
+  ZNUMA::memory_interleave(addr, size);
+
+  // Pre-touch memory
+  if (pretouch) {
+    pretouch_view(addr, size);
+  }
+}
+
+void ZPhysicalMemoryBacking::unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const {
+  // Note that we must keep the address space reservation intact and just detach
+  // the backing memory. For this reason we map a new anonymous, non-accessible
+  // and non-reserved page over the mapping instead of actually unmapping.
+  const void* const res = mmap((void*)addr, pmem.size(), PROT_NONE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
+  if (res == MAP_FAILED) {
+    ZErrno err;
+    map_failed(err);
+  }
+}
+
+uintptr_t ZPhysicalMemoryBacking::nmt_address(uintptr_t offset) const {
+  // From an NMT point of view we treat the first heap view (marked0) as committed
+  return ZAddress::marked0(offset);
+}
+
+void ZPhysicalMemoryBacking::map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
+  if (ZVerifyViews) {
+    // Map good view
+    map_view(pmem, ZAddress::good(offset), AlwaysPreTouch);
+  } else {
+    // Map all views
+    map_view(pmem, ZAddress::marked0(offset), AlwaysPreTouch);
+    map_view(pmem, ZAddress::marked1(offset), AlwaysPreTouch);
+    map_view(pmem, ZAddress::remapped(offset), AlwaysPreTouch);
+  }
+}
+
+void ZPhysicalMemoryBacking::unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
+  if (ZVerifyViews) {
+    // Unmap good view
+    unmap_view(pmem, ZAddress::good(offset));
+  } else {
+    // Unmap all views
+    unmap_view(pmem, ZAddress::marked0(offset));
+    unmap_view(pmem, ZAddress::marked1(offset));
+    unmap_view(pmem, ZAddress::remapped(offset));
+  }
+}
+
+void ZPhysicalMemoryBacking::debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
+  // Map good view
+  assert(ZVerifyViews, "Should be enabled");
+  map_view(pmem, ZAddress::good(offset), false /* pretouch */);
+}
+
+void ZPhysicalMemoryBacking::debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
+  // Unmap good view
+  assert(ZVerifyViews, "Should be enabled");
+  unmap_view(pmem, ZAddress::good(offset));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/linux/gc/z/zPhysicalMemoryBacking_linux.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,70 @@
+/*
+ * 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
+ * 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 OS_LINUX_GC_Z_ZPHYSICALMEMORYBACKING_LINUX_HPP
+#define OS_LINUX_GC_Z_ZPHYSICALMEMORYBACKING_LINUX_HPP
+
+#include "gc/z/zBackingFile_linux.hpp"
+#include "gc/z/zMemory.hpp"
+
+class ZErrno;
+class ZPhysicalMemory;
+
+class ZPhysicalMemoryBacking {
+private:
+  ZBackingFile   _file;
+  ZMemoryManager _committed;
+  ZMemoryManager _uncommitted;
+
+  void warn_available_space(size_t max) const;
+  void warn_max_map_count(size_t max) const;
+
+  void map_failed(ZErrno err) const;
+
+  void advise_view(uintptr_t addr, size_t size, int advice) const;
+  void pretouch_view(uintptr_t addr, size_t size) const;
+  void map_view(const ZPhysicalMemory& pmem, uintptr_t addr, bool pretouch) const;
+  void unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const;
+
+public:
+  bool is_initialized() const;
+
+  void warn_commit_limits(size_t max) const;
+  bool supports_uncommit();
+
+  size_t commit(size_t size);
+  size_t uncommit(size_t size);
+
+  ZPhysicalMemory alloc(size_t size);
+  void free(const ZPhysicalMemory& pmem);
+
+  uintptr_t nmt_address(uintptr_t offset) const;
+
+  void map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+  void unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+
+  void debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+  void debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+};
+
+#endif // OS_LINUX_GC_Z_ZPHYSICALMEMORYBACKING_LINUX_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/linux/gc/z/zSyscall_linux.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,36 @@
+/*
+ * 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 "gc/z/zSyscall_linux.hpp"
+#include OS_CPU_HEADER(gc/z/zSyscall)
+
+#include <unistd.h>
+
+int ZSyscall::memfd_create(const char *name, unsigned int flags) {
+  return syscall(SYS_memfd_create, name, flags);
+}
+
+int ZSyscall::fallocate(int fd, int mode, size_t offset, size_t length) {
+  return syscall(SYS_fallocate, fd, mode, offset, length);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os/linux/gc/z/zSyscall_linux.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,35 @@
+/*
+ * 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 OS_LINUX_GC_Z_ZSYSCALL_LINUX_HPP
+#define OS_LINUX_GC_Z_ZSYSCALL_LINUX_HPP
+
+#include "memory/allocation.hpp"
+
+class ZSyscall : public AllStatic {
+public:
+  static int memfd_create(const char *name, unsigned int flags);
+  static int fallocate(int fd, int mode, size_t offset, size_t length);
+};
+
+#endif // OS_LINUX_GC_Z_ZSYSCALL_LINUX_HPP
--- a/src/hotspot/os/linux/osContainer_linux.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/os/linux/osContainer_linux.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,6 +27,7 @@
 #include <errno.h>
 #include "utilities/globalDefinitions.hpp"
 #include "memory/allocation.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/os.hpp"
 #include "logging/log.hpp"
 #include "osContainer_linux.hpp"
@@ -673,4 +674,3 @@
 
   return shares;
 }
-
--- a/src/hotspot/os/linux/os_linux.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/os/linux/os_linux.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -6185,6 +6185,10 @@
   return diff;
 }
 
+bool os::supports_map_sync() {
+  return true;
+}
+
 /////////////// Unit tests ///////////////
 
 #ifndef PRODUCT
--- a/src/hotspot/os/solaris/os_solaris.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/os/solaris/os_solaris.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1597,6 +1597,10 @@
     char*         name;         // String representation
   } arch_t;
 
+#ifndef EM_AARCH64
+  #define EM_AARCH64    183               /* ARM AARCH64 */
+#endif
+
   static const arch_t arch_array[]={
     {EM_386,         EM_386,     ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
     {EM_486,         EM_386,     ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
@@ -5380,6 +5384,10 @@
   return strlen(buffer);
 }
 
+bool os::supports_map_sync() {
+  return false;
+}
+
 #ifndef PRODUCT
 void TestReserveMemorySpecial_test() {
   // No tests available for this platform
--- a/src/hotspot/os/windows/os_windows.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/os/windows/os_windows.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -5803,3 +5803,7 @@
   os::os_exception_wrapper((java_call_t)call_wrapper_dummy,
                            NULL, NULL, NULL, NULL);
 }
+
+bool os::supports_map_sync() {
+  return false;
+}
--- a/src/hotspot/os_cpu/linux_aarch64/gc/z/zBackingFile_linux_aarch64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,590 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "gc/z/zArray.inline.hpp"
-#include "gc/z/zBackingFile_linux_aarch64.hpp"
-#include "gc/z/zBackingPath_linux_aarch64.hpp"
-#include "gc/z/zErrno.hpp"
-#include "gc/z/zGlobals.hpp"
-#include "gc/z/zLargePages.inline.hpp"
-#include "logging/log.hpp"
-#include "runtime/init.hpp"
-#include "runtime/os.hpp"
-#include "utilities/align.hpp"
-#include "utilities/debug.hpp"
-
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-//
-// Support for building on older Linux systems
-//
-
-// System calls
-#ifndef SYS_fallocate
-#define SYS_fallocate                    47
-#endif
-#ifndef SYS_memfd_create
-#define SYS_memfd_create                 279
-#endif
-
-// memfd_create(2) flags
-#ifndef MFD_CLOEXEC
-#define MFD_CLOEXEC                      0x0001U
-#endif
-#ifndef MFD_HUGETLB
-#define MFD_HUGETLB                      0x0004U
-#endif
-
-// open(2) flags
-#ifndef O_CLOEXEC
-#define O_CLOEXEC                        02000000
-#endif
-#ifndef O_TMPFILE
-#define O_TMPFILE                        (020000000 | O_DIRECTORY)
-#endif
-
-// fallocate(2) flags
-#ifndef FALLOC_FL_KEEP_SIZE
-#define FALLOC_FL_KEEP_SIZE              0x01
-#endif
-#ifndef FALLOC_FL_PUNCH_HOLE
-#define FALLOC_FL_PUNCH_HOLE             0x02
-#endif
-
-// Filesystem types, see statfs(2)
-#ifndef TMPFS_MAGIC
-#define TMPFS_MAGIC                      0x01021994
-#endif
-#ifndef HUGETLBFS_MAGIC
-#define HUGETLBFS_MAGIC                  0x958458f6
-#endif
-
-// Filesystem names
-#define ZFILESYSTEM_TMPFS                "tmpfs"
-#define ZFILESYSTEM_HUGETLBFS            "hugetlbfs"
-
-// Sysfs file for transparent huge page on tmpfs
-#define ZFILENAME_SHMEM_ENABLED          "/sys/kernel/mm/transparent_hugepage/shmem_enabled"
-
-// Java heap filename
-#define ZFILENAME_HEAP                   "java_heap"
-
-// Preferred tmpfs mount points, ordered by priority
-static const char* z_preferred_tmpfs_mountpoints[] = {
-  "/dev/shm",
-  "/run/shm",
-  NULL
-};
-
-// Preferred hugetlbfs mount points, ordered by priority
-static const char* z_preferred_hugetlbfs_mountpoints[] = {
-  "/dev/hugepages",
-  "/hugepages",
-  NULL
-};
-
-static int z_fallocate_hugetlbfs_attempts = 3;
-static bool z_fallocate_supported = true;
-
-static int z_fallocate(int fd, int mode, size_t offset, size_t length) {
-  return syscall(SYS_fallocate, fd, mode, offset, length);
-}
-
-static int z_memfd_create(const char *name, unsigned int flags) {
-  return syscall(SYS_memfd_create, name, flags);
-}
-
-ZBackingFile::ZBackingFile() :
-    _fd(-1),
-    _size(0),
-    _filesystem(0),
-    _block_size(0),
-    _available(0),
-    _initialized(false) {
-
-  // Create backing file
-  _fd = create_fd(ZFILENAME_HEAP);
-  if (_fd == -1) {
-    return;
-  }
-
-  // Get filesystem statistics
-  struct statfs buf;
-  if (fstatfs(_fd, &buf) == -1) {
-    ZErrno err;
-    log_error(gc)("Failed to determine filesystem type for backing file (%s)", err.to_string());
-    return;
-  }
-
-  _filesystem = buf.f_type;
-  _block_size = buf.f_bsize;
-  _available = buf.f_bavail * _block_size;
-
-  // Make sure we're on a supported filesystem
-  if (!is_tmpfs() && !is_hugetlbfs()) {
-    log_error(gc)("Backing file must be located on a %s or a %s filesystem",
-                  ZFILESYSTEM_TMPFS, ZFILESYSTEM_HUGETLBFS);
-    return;
-  }
-
-  // Make sure the filesystem type matches requested large page type
-  if (ZLargePages::is_transparent() && !is_tmpfs()) {
-    log_error(gc)("-XX:+UseTransparentHugePages can only be enable when using a %s filesystem",
-                  ZFILESYSTEM_TMPFS);
-    return;
-  }
-
-  if (ZLargePages::is_transparent() && !tmpfs_supports_transparent_huge_pages()) {
-    log_error(gc)("-XX:+UseTransparentHugePages on a %s filesystem not supported by kernel",
-                  ZFILESYSTEM_TMPFS);
-    return;
-  }
-
-  if (ZLargePages::is_explicit() && !is_hugetlbfs()) {
-    log_error(gc)("-XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled "
-                  "when using a %s filesystem", ZFILESYSTEM_HUGETLBFS);
-    return;
-  }
-
-  if (!ZLargePages::is_explicit() && is_hugetlbfs()) {
-    log_error(gc)("-XX:+UseLargePages must be enabled when using a %s filesystem",
-                  ZFILESYSTEM_HUGETLBFS);
-    return;
-  }
-
-  const size_t expected_block_size = is_tmpfs() ? os::vm_page_size() : os::large_page_size();
-  if (expected_block_size != _block_size) {
-    log_error(gc)("%s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT ")",
-                  is_tmpfs() ? ZFILESYSTEM_TMPFS : ZFILESYSTEM_HUGETLBFS, _block_size, expected_block_size);
-    return;
-  }
-
-  // Successfully initialized
-  _initialized = true;
-}
-
-int ZBackingFile::create_mem_fd(const char* name) const {
-  // Create file name
-  char filename[PATH_MAX];
-  snprintf(filename, sizeof(filename), "%s%s", name, ZLargePages::is_explicit() ? ".hugetlb" : "");
-
-  // Create file
-  const int extra_flags = ZLargePages::is_explicit() ? MFD_HUGETLB : 0;
-  const int fd = z_memfd_create(filename, MFD_CLOEXEC | extra_flags);
-  if (fd == -1) {
-    ZErrno err;
-    log_debug(gc, init)("Failed to create memfd file (%s)",
-                        ((ZLargePages::is_explicit() && err == EINVAL) ? "Hugepages not supported" : err.to_string()));
-    return -1;
-  }
-
-  log_info(gc, init)("Heap backed by file: /memfd:%s", filename);
-
-  return fd;
-}
-
-int ZBackingFile::create_file_fd(const char* name) const {
-  const char* const filesystem = ZLargePages::is_explicit()
-                                 ? ZFILESYSTEM_HUGETLBFS
-                                 : ZFILESYSTEM_TMPFS;
-  const char** const preferred_mountpoints = ZLargePages::is_explicit()
-                                             ? z_preferred_hugetlbfs_mountpoints
-                                             : z_preferred_tmpfs_mountpoints;
-
-  // Find mountpoint
-  ZBackingPath path(filesystem, preferred_mountpoints);
-  if (path.get() == NULL) {
-    log_error(gc)("Use -XX:ZPath to specify the path to a %s filesystem", filesystem);
-    return -1;
-  }
-
-  // Try to create an anonymous file using the O_TMPFILE flag. Note that this
-  // flag requires kernel >= 3.11. If this fails we fall back to open/unlink.
-  const int fd_anon = os::open(path.get(), O_TMPFILE|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
-  if (fd_anon == -1) {
-    ZErrno err;
-    log_debug(gc, init)("Failed to create anonymous file in %s (%s)", path.get(),
-                        (err == EINVAL ? "Not supported" : err.to_string()));
-  } else {
-    // Get inode number for anonymous file
-    struct stat stat_buf;
-    if (fstat(fd_anon, &stat_buf) == -1) {
-      ZErrno err;
-      log_error(gc)("Failed to determine inode number for anonymous file (%s)", err.to_string());
-      return -1;
-    }
-
-    log_info(gc, init)("Heap backed by file: %s/#" UINT64_FORMAT, path.get(), (uint64_t)stat_buf.st_ino);
-
-    return fd_anon;
-  }
-
-  log_debug(gc, init)("Falling back to open/unlink");
-
-  // Create file name
-  char filename[PATH_MAX];
-  snprintf(filename, sizeof(filename), "%s/%s.%d", path.get(), name, os::current_process_id());
-
-  // Create file
-  const int fd = os::open(filename, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
-  if (fd == -1) {
-    ZErrno err;
-    log_error(gc)("Failed to create file %s (%s)", filename, err.to_string());
-    return -1;
-  }
-
-  // Unlink file
-  if (unlink(filename) == -1) {
-    ZErrno err;
-    log_error(gc)("Failed to unlink file %s (%s)", filename, err.to_string());
-    return -1;
-  }
-
-  log_info(gc, init)("Heap backed by file: %s", filename);
-
-  return fd;
-}
-
-int ZBackingFile::create_fd(const char* name) const {
-  if (ZPath == NULL) {
-    // If the path is not explicitly specified, then we first try to create a memfd file
-    // instead of looking for a tmpfd/hugetlbfs mount point. Note that memfd_create() might
-    // not be supported at all (requires kernel >= 3.17), or it might not support large
-    // pages (requires kernel >= 4.14). If memfd_create() fails, then we try to create a
-    // file on an accessible tmpfs or hugetlbfs mount point.
-    const int fd = create_mem_fd(name);
-    if (fd != -1) {
-      return fd;
-    }
-
-    log_debug(gc, init)("Falling back to searching for an accessible mount point");
-  }
-
-  return create_file_fd(name);
-}
-
-bool ZBackingFile::is_initialized() const {
-  return _initialized;
-}
-
-int ZBackingFile::fd() const {
-  return _fd;
-}
-
-size_t ZBackingFile::size() const {
-  return _size;
-}
-
-size_t ZBackingFile::available() const {
-  return _available;
-}
-
-bool ZBackingFile::is_tmpfs() const {
-  return _filesystem == TMPFS_MAGIC;
-}
-
-bool ZBackingFile::is_hugetlbfs() const {
-  return _filesystem == HUGETLBFS_MAGIC;
-}
-
-bool ZBackingFile::tmpfs_supports_transparent_huge_pages() const {
-  // If the shmem_enabled file exists and is readable then we
-  // know the kernel supports transparent huge pages for tmpfs.
-  return access(ZFILENAME_SHMEM_ENABLED, R_OK) == 0;
-}
-
-ZErrno ZBackingFile::fallocate_compat_ftruncate(size_t size) const {
-  while (ftruncate(_fd, size) == -1) {
-    if (errno != EINTR) {
-      // Failed
-      return errno;
-    }
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate_compat_mmap(size_t offset, size_t length, bool touch) const {
-  // On hugetlbfs, mapping a file segment will fail immediately, without
-  // the need to touch the mapped pages first, if there aren't enough huge
-  // pages available to back the mapping.
-  void* const addr = mmap(0, length, PROT_READ|PROT_WRITE, MAP_SHARED, _fd, offset);
-  if (addr == MAP_FAILED) {
-    // Failed
-    return errno;
-  }
-
-  // Once mapped, the huge pages are only reserved. We need to touch them
-  // to associate them with the file segment. Note that we can not punch
-  // hole in file segments which only have reserved pages.
-  if (touch) {
-    char* const start = (char*)addr;
-    char* const end = start + length;
-    os::pretouch_memory(start, end, _block_size);
-  }
-
-  // Unmap again. From now on, the huge pages that were mapped are allocated
-  // to this file. There's no risk in getting SIGBUS when touching them.
-  if (munmap(addr, length) == -1) {
-    // Failed
-    return errno;
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate_compat_pwrite(size_t offset, size_t length) const {
-  uint8_t data = 0;
-
-  // Allocate backing memory by writing to each block
-  for (size_t pos = offset; pos < offset + length; pos += _block_size) {
-    if (pwrite(_fd, &data, sizeof(data), pos) == -1) {
-      // Failed
-      return errno;
-    }
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate_fill_hole_compat(size_t offset, size_t length) {
-  // fallocate(2) is only supported by tmpfs since Linux 3.5, and by hugetlbfs
-  // since Linux 4.3. When fallocate(2) is not supported we emulate it using
-  // ftruncate/pwrite (for tmpfs) or ftruncate/mmap/munmap (for hugetlbfs).
-
-  const size_t end = offset + length;
-  if (end > _size) {
-    // Increase file size
-    const ZErrno err = fallocate_compat_ftruncate(end);
-    if (err) {
-      // Failed
-      return err;
-    }
-  }
-
-  // Allocate backing memory
-  const ZErrno err = is_hugetlbfs() ? fallocate_compat_mmap(offset, length, false /* touch */)
-                                    : fallocate_compat_pwrite(offset, length);
-  if (err) {
-    if (end > _size) {
-      // Restore file size
-      fallocate_compat_ftruncate(_size);
-    }
-
-    // Failed
-    return err;
-  }
-
-  if (end > _size) {
-    // Record new file size
-    _size = end;
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate_fill_hole_syscall(size_t offset, size_t length) {
-  const int mode = 0; // Allocate
-  const int res = z_fallocate(_fd, mode, offset, length);
-  if (res == -1) {
-    // Failed
-    return errno;
-  }
-
-  const size_t end = offset + length;
-  if (end > _size) {
-    // Record new file size
-    _size = end;
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate_fill_hole(size_t offset, size_t length) {
-  // Using compat mode is more efficient when allocating space on hugetlbfs.
-  // Note that allocating huge pages this way will only reserve them, and not
-  // associate them with segments of the file. We must guarantee that we at
-  // some point touch these segments, otherwise we can not punch hole in them.
-  if (z_fallocate_supported && !is_hugetlbfs()) {
-     const ZErrno err = fallocate_fill_hole_syscall(offset, length);
-     if (!err) {
-       // Success
-       return 0;
-     }
-
-     if (err != ENOSYS && err != EOPNOTSUPP) {
-       // Failed
-       return err;
-     }
-
-     // Not supported
-     log_debug(gc)("Falling back to fallocate() compatibility mode");
-     z_fallocate_supported = false;
-  }
-
-  return fallocate_fill_hole_compat(offset, length);
-}
-
-ZErrno ZBackingFile::fallocate_punch_hole(size_t offset, size_t length) {
-  if (is_hugetlbfs()) {
-    // We can only punch hole in pages that have been touched. Non-touched
-    // pages are only reserved, and not associated with any specific file
-    // segment. We don't know which pages have been previously touched, so
-    // we always touch them here to guarantee that we can punch hole.
-    const ZErrno err = fallocate_compat_mmap(offset, length, true /* touch */);
-    if (err) {
-      // Failed
-      return err;
-    }
-  }
-
-  const int mode = FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE;
-  if (z_fallocate(_fd, mode, offset, length) == -1) {
-    // Failed
-    return errno;
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::split_and_fallocate(bool punch_hole, size_t offset, size_t length) {
-  // Try first half
-  const size_t offset0 = offset;
-  const size_t length0 = align_up(length / 2, _block_size);
-  const ZErrno err0 = fallocate(punch_hole, offset0, length0);
-  if (err0) {
-    return err0;
-  }
-
-  // Try second half
-  const size_t offset1 = offset0 + length0;
-  const size_t length1 = length - length0;
-  const ZErrno err1 = fallocate(punch_hole, offset1, length1);
-  if (err1) {
-    return err1;
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate(bool punch_hole, size_t offset, size_t length) {
-  assert(is_aligned(offset, _block_size), "Invalid offset");
-  assert(is_aligned(length, _block_size), "Invalid length");
-
-  const ZErrno err = punch_hole ? fallocate_punch_hole(offset, length) : fallocate_fill_hole(offset, length);
-  if (err == EINTR && length > _block_size) {
-    // Calling fallocate(2) with a large length can take a long time to
-    // complete. When running profilers, such as VTune, this syscall will
-    // be constantly interrupted by signals. Expanding the file in smaller
-    // steps avoids this problem.
-    return split_and_fallocate(punch_hole, offset, length);
-  }
-
-  return err;
-}
-
-bool ZBackingFile::commit_inner(size_t offset, size_t length) {
-  log_trace(gc, heap)("Committing memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
-                      offset / M, (offset + length) / M, length / M);
-
-retry:
-  const ZErrno err = fallocate(false /* punch_hole */, offset, length);
-  if (err) {
-    if (err == ENOSPC && !is_init_completed() && is_hugetlbfs() && z_fallocate_hugetlbfs_attempts-- > 0) {
-      // If we fail to allocate during initialization, due to lack of space on
-      // the hugetlbfs filesystem, then we wait and retry a few times before
-      // giving up. Otherwise there is a risk that running JVMs back-to-back
-      // will fail, since there is a delay between process termination and the
-      // huge pages owned by that process being returned to the huge page pool
-      // and made available for new allocations.
-      log_debug(gc, init)("Failed to commit memory (%s), retrying", err.to_string());
-
-      // Wait and retry in one second, in the hope that huge pages will be
-      // available by then.
-      sleep(1);
-      goto retry;
-    }
-
-    // Failed
-    log_error(gc)("Failed to commit memory (%s)", err.to_string());
-    return false;
-  }
-
-  // Success
-  return true;
-}
-
-size_t ZBackingFile::commit(size_t offset, size_t length) {
-  // Try to commit the whole region
-  if (commit_inner(offset, length)) {
-    // Success
-    return length;
-  }
-
-  // Failed, try to commit as much as possible
-  size_t start = offset;
-  size_t end = offset + length;
-
-  for (;;) {
-    length = align_down((end - start) / 2, ZGranuleSize);
-    if (length < ZGranuleSize) {
-      // Done, don't commit more
-      return start - offset;
-    }
-
-    if (commit_inner(start, length)) {
-      // Success, try commit more
-      start += length;
-    } else {
-      // Failed, try commit less
-      end -= length;
-    }
-  }
-}
-
-size_t ZBackingFile::uncommit(size_t offset, size_t length) {
-  log_trace(gc, heap)("Uncommitting memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
-                      offset / M, (offset + length) / M, length / M);
-
-  const ZErrno err = fallocate(true /* punch_hole */, offset, length);
-  if (err) {
-    log_error(gc)("Failed to uncommit memory (%s)", err.to_string());
-    return 0;
-  }
-
-  return length;
-}
--- a/src/hotspot/os_cpu/linux_aarch64/gc/z/zBackingFile_linux_aarch64.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * 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
- * 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 OS_CPU_LINUX_AARCH64_GC_Z_ZBACKINGFILE_LINUX_AARCH64_HPP
-#define OS_CPU_LINUX_AARCH64_GC_Z_ZBACKINGFILE_LINUX_AARCH64_HPP
-
-#include "memory/allocation.hpp"
-
-class ZErrno;
-
-class ZBackingFile {
-private:
-  int      _fd;
-  size_t   _size;
-  uint64_t _filesystem;
-  size_t   _block_size;
-  size_t   _available;
-  bool     _initialized;
-
-  int create_mem_fd(const char* name) const;
-  int create_file_fd(const char* name) const;
-  int create_fd(const char* name) const;
-
-  bool is_tmpfs() const;
-  bool is_hugetlbfs() const;
-  bool tmpfs_supports_transparent_huge_pages() const;
-
-  ZErrno fallocate_compat_ftruncate(size_t size) const;
-  ZErrno fallocate_compat_mmap(size_t offset, size_t length, bool reserve_only) const;
-  ZErrno fallocate_compat_pwrite(size_t offset, size_t length) const;
-  ZErrno fallocate_fill_hole_compat(size_t offset, size_t length);
-  ZErrno fallocate_fill_hole_syscall(size_t offset, size_t length);
-  ZErrno fallocate_fill_hole(size_t offset, size_t length);
-  ZErrno fallocate_punch_hole(size_t offset, size_t length);
-  ZErrno split_and_fallocate(bool punch_hole, size_t offset, size_t length);
-  ZErrno fallocate(bool punch_hole, size_t offset, size_t length);
-
-  bool commit_inner(size_t offset, size_t length);
-
-public:
-  ZBackingFile();
-
-  bool is_initialized() const;
-
-  int fd() const;
-  size_t size() const;
-  size_t available() const;
-
-  size_t commit(size_t offset, size_t length);
-  size_t uncommit(size_t offset, size_t length);
-};
-
-#endif // OS_CPU_LINUX_AARCH64_GC_Z_ZBACKINGFILE_LINUX_AARCH64_HPP
--- a/src/hotspot/os_cpu/linux_aarch64/gc/z/zBackingPath_linux_aarch64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "gc/z/zArray.inline.hpp"
-#include "zBackingPath_linux_aarch64.hpp"
-#include "gc/z/zErrno.hpp"
-#include "logging/log.hpp"
-
-#include <stdio.h>
-#include <unistd.h>
-
-// Mount information, see proc(5) for more details.
-#define PROC_SELF_MOUNTINFO        "/proc/self/mountinfo"
-
-ZBackingPath::ZBackingPath(const char* filesystem, const char** preferred_mountpoints) {
-  if (ZPath != NULL) {
-    // Use specified path
-    _path = strdup(ZPath);
-  } else {
-    // Find suitable path
-    _path = find_mountpoint(filesystem, preferred_mountpoints);
-  }
-}
-
-ZBackingPath::~ZBackingPath() {
-  free(_path);
-  _path = NULL;
-}
-
-char* ZBackingPath::get_mountpoint(const char* line, const char* filesystem) const {
-  char* line_mountpoint = NULL;
-  char* line_filesystem = NULL;
-
-  // Parse line and return a newly allocated string containing the mount point if
-  // the line contains a matching filesystem and the mount point is accessible by
-  // the current user.
-  if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-]- %ms", &line_mountpoint, &line_filesystem) != 2 ||
-      strcmp(line_filesystem, filesystem) != 0 ||
-      access(line_mountpoint, R_OK|W_OK|X_OK) != 0) {
-    // Not a matching or accessible filesystem
-    free(line_mountpoint);
-    line_mountpoint = NULL;
-  }
-
-  free(line_filesystem);
-
-  return line_mountpoint;
-}
-
-void ZBackingPath::get_mountpoints(const char* filesystem, ZArray<char*>* mountpoints) const {
-  FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r");
-  if (fd == NULL) {
-    ZErrno err;
-    log_error(gc)("Failed to open %s: %s", PROC_SELF_MOUNTINFO, err.to_string());
-    return;
-  }
-
-  char* line = NULL;
-  size_t length = 0;
-
-  while (getline(&line, &length, fd) != -1) {
-    char* const mountpoint = get_mountpoint(line, filesystem);
-    if (mountpoint != NULL) {
-      mountpoints->add(mountpoint);
-    }
-  }
-
-  free(line);
-  fclose(fd);
-}
-
-void ZBackingPath::free_mountpoints(ZArray<char*>* mountpoints) const {
-  ZArrayIterator<char*> iter(mountpoints);
-  for (char* mountpoint; iter.next(&mountpoint);) {
-    free(mountpoint);
-  }
-  mountpoints->clear();
-}
-
-char* ZBackingPath::find_preferred_mountpoint(const char* filesystem,
-                                              ZArray<char*>* mountpoints,
-                                              const char** preferred_mountpoints) const {
-  // Find preferred mount point
-  ZArrayIterator<char*> iter1(mountpoints);
-  for (char* mountpoint; iter1.next(&mountpoint);) {
-    for (const char** preferred = preferred_mountpoints; *preferred != NULL; preferred++) {
-      if (!strcmp(mountpoint, *preferred)) {
-        // Preferred mount point found
-        return strdup(mountpoint);
-      }
-    }
-  }
-
-  // Preferred mount point not found
-  log_error(gc)("More than one %s filesystem found:", filesystem);
-  ZArrayIterator<char*> iter2(mountpoints);
-  for (char* mountpoint; iter2.next(&mountpoint);) {
-    log_error(gc)("  %s", mountpoint);
-  }
-
-  return NULL;
-}
-
-char* ZBackingPath::find_mountpoint(const char* filesystem, const char** preferred_mountpoints) const {
-  char* path = NULL;
-  ZArray<char*> mountpoints;
-
-  get_mountpoints(filesystem, &mountpoints);
-
-  if (mountpoints.size() == 0) {
-    // No mount point found
-    log_error(gc)("Failed to find an accessible %s filesystem", filesystem);
-  } else if (mountpoints.size() == 1) {
-    // One mount point found
-    path = strdup(mountpoints.at(0));
-  } else {
-    // More than one mount point found
-    path = find_preferred_mountpoint(filesystem, &mountpoints, preferred_mountpoints);
-  }
-
-  free_mountpoints(&mountpoints);
-
-  return path;
-}
-
-const char* ZBackingPath::get() const {
-  return _path;
-}
--- a/src/hotspot/os_cpu/linux_aarch64/gc/z/zBackingPath_linux_aarch64.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 OS_CPU_LINUX_AARCH64_GC_Z_ZBACKINGPATH_LINUX_AARCH64_HPP
-#define OS_CPU_LINUX_AARCH64_GC_Z_ZBACKINGPATH_LINUX_AARCH64_HPP
-
-#include "gc/z/zArray.hpp"
-#include "memory/allocation.hpp"
-
-class ZBackingPath : public StackObj {
-private:
-  char* _path;
-
-  char* get_mountpoint(const char* line,
-                       const char* filesystem) const;
-  void get_mountpoints(const char* filesystem,
-                       ZArray<char*>* mountpoints) const;
-  void free_mountpoints(ZArray<char*>* mountpoints) const;
-  char* find_preferred_mountpoint(const char* filesystem,
-                                  ZArray<char*>* mountpoints,
-                                  const char** preferred_mountpoints) const;
-  char* find_mountpoint(const char* filesystem,
-                        const char** preferred_mountpoints) const;
-
-public:
-  ZBackingPath(const char* filesystem, const char** preferred_mountpoints);
-  ~ZBackingPath();
-
-  const char* get() const;
-};
-
-#endif // OS_CPU_LINUX_AARCH64_GC_Z_ZBACKINGPATH_LINUX_AARCH64_HPP
--- a/src/hotspot/os_cpu/linux_aarch64/gc/z/zPhysicalMemoryBacking_linux_aarch64.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "gc/z/zAddress.inline.hpp"
-#include "gc/z/zBackingFile_linux_aarch64.hpp"
-#include "gc/z/zErrno.hpp"
-#include "gc/z/zGlobals.hpp"
-#include "gc/z/zLargePages.inline.hpp"
-#include "gc/z/zMemory.hpp"
-#include "gc/z/zNUMA.hpp"
-#include "gc/z/zPhysicalMemory.inline.hpp"
-#include "gc/z/zPhysicalMemoryBacking_linux_aarch64.hpp"
-#include "logging/log.hpp"
-#include "runtime/init.hpp"
-#include "runtime/os.hpp"
-#include "utilities/align.hpp"
-#include "utilities/debug.hpp"
-
-#include <stdio.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-
-//
-// Support for building on older Linux systems
-//
-
-// madvise(2) flags
-#ifndef MADV_HUGEPAGE
-#define MADV_HUGEPAGE                        14
-#endif
-
-// Proc file entry for max map mount
-#define ZFILENAME_PROC_MAX_MAP_COUNT         "/proc/sys/vm/max_map_count"
-
-bool ZPhysicalMemoryBacking::is_initialized() const {
-  return _file.is_initialized();
-}
-
-void ZPhysicalMemoryBacking::warn_available_space(size_t max) const {
-  // Note that the available space on a tmpfs or a hugetlbfs filesystem
-  // will be zero if no size limit was specified when it was mounted.
-  const size_t available = _file.available();
-  if (available == 0) {
-    // No size limit set, skip check
-    log_info(gc, init)("Available space on backing filesystem: N/A");
-    return;
-  }
-
-  log_info(gc, init)("Available space on backing filesystem: " SIZE_FORMAT "M", available / M);
-
-  // Warn if the filesystem doesn't currently have enough space available to hold
-  // the max heap size. The max heap size will be capped if we later hit this limit
-  // when trying to expand the heap.
-  if (available < max) {
-    log_warning(gc)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****");
-    log_warning(gc)("Not enough space available on the backing filesystem to hold the current max Java heap");
-    log_warning(gc)("size (" SIZE_FORMAT "M). Please adjust the size of the backing filesystem accordingly "
-                    "(available", max / M);
-    log_warning(gc)("space is currently " SIZE_FORMAT "M). Continuing execution with the current filesystem "
-                    "size could", available / M);
-    log_warning(gc)("lead to a premature OutOfMemoryError being thrown, due to failure to map memory.");
-  }
-}
-
-void ZPhysicalMemoryBacking::warn_max_map_count(size_t max) const {
-  const char* const filename = ZFILENAME_PROC_MAX_MAP_COUNT;
-  FILE* const file = fopen(filename, "r");
-  if (file == NULL) {
-    // Failed to open file, skip check
-    log_debug(gc, init)("Failed to open %s", filename);
-    return;
-  }
-
-  size_t actual_max_map_count = 0;
-  const int result = fscanf(file, SIZE_FORMAT, &actual_max_map_count);
-  fclose(file);
-  if (result != 1) {
-    // Failed to read file, skip check
-    log_debug(gc, init)("Failed to read %s", filename);
-    return;
-  }
-
-  // The required max map count is impossible to calculate exactly since subsystems
-  // other than ZGC are also creating memory mappings, and we have no control over that.
-  // However, ZGC tends to create the most mappings and dominate the total count.
-  // In the worst cases, ZGC will map each granule three times, i.e. once per heap view.
-  // We speculate that we need another 20% to allow for non-ZGC subsystems to map memory.
-  const size_t required_max_map_count = (max / ZGranuleSize) * 3 * 1.2;
-  if (actual_max_map_count < required_max_map_count) {
-    log_warning(gc)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****");
-    log_warning(gc)("The system limit on number of memory mappings per process might be too low for the given");
-    log_warning(gc)("max Java heap size (" SIZE_FORMAT "M). Please adjust %s to allow for at",
-                    max / M, filename);
-    log_warning(gc)("least " SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT "). Continuing execution "
-                    "with the current", required_max_map_count, actual_max_map_count);
-    log_warning(gc)("limit could lead to a fatal error, due to failure to map memory.");
-  }
-}
-
-void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
-  // Warn if available space is too low
-  warn_available_space(max);
-
-  // Warn if max map count is too low
-  warn_max_map_count(max);
-}
-
-bool ZPhysicalMemoryBacking::supports_uncommit() {
-  assert(!is_init_completed(), "Invalid state");
-  assert(_file.size() >= ZGranuleSize, "Invalid size");
-
-  // Test if uncommit is supported by uncommitting and then re-committing a granule
-  return commit(uncommit(ZGranuleSize)) == ZGranuleSize;
-}
-
-size_t ZPhysicalMemoryBacking::commit(size_t size) {
-  size_t committed = 0;
-
-  // Fill holes in the backing file
-  while (committed < size) {
-    size_t allocated = 0;
-    const size_t remaining = size - committed;
-    const uintptr_t start = _uncommitted.alloc_from_front_at_most(remaining, &allocated);
-    if (start == UINTPTR_MAX) {
-      // No holes to commit
-      break;
-    }
-
-    // Try commit hole
-    const size_t filled = _file.commit(start, allocated);
-    if (filled > 0) {
-      // Successful or partialy successful
-      _committed.free(start, filled);
-      committed += filled;
-    }
-    if (filled < allocated) {
-      // Failed or partialy failed
-      _uncommitted.free(start + filled, allocated - filled);
-      return committed;
-    }
-  }
-
-  // Expand backing file
-  if (committed < size) {
-    const size_t remaining = size - committed;
-    const uintptr_t start = _file.size();
-    const size_t expanded = _file.commit(start, remaining);
-    if (expanded > 0) {
-      // Successful or partialy successful
-      _committed.free(start, expanded);
-      committed += expanded;
-    }
-  }
-
-  return committed;
-}
-
-size_t ZPhysicalMemoryBacking::uncommit(size_t size) {
-  size_t uncommitted = 0;
-
-  // Punch holes in backing file
-  while (uncommitted < size) {
-    size_t allocated = 0;
-    const size_t remaining = size - uncommitted;
-    const uintptr_t start = _committed.alloc_from_back_at_most(remaining, &allocated);
-    assert(start != UINTPTR_MAX, "Allocation should never fail");
-
-    // Try punch hole
-    const size_t punched = _file.uncommit(start, allocated);
-    if (punched > 0) {
-      // Successful or partialy successful
-      _uncommitted.free(start, punched);
-      uncommitted += punched;
-    }
-    if (punched < allocated) {
-      // Failed or partialy failed
-      _committed.free(start + punched, allocated - punched);
-      return uncommitted;
-    }
-  }
-
-  return uncommitted;
-}
-
-ZPhysicalMemory ZPhysicalMemoryBacking::alloc(size_t size) {
-  assert(is_aligned(size, ZGranuleSize), "Invalid size");
-
-  ZPhysicalMemory pmem;
-
-  // Allocate segments
-  for (size_t allocated = 0; allocated < size; allocated += ZGranuleSize) {
-    const uintptr_t start = _committed.alloc_from_front(ZGranuleSize);
-    assert(start != UINTPTR_MAX, "Allocation should never fail");
-    pmem.add_segment(ZPhysicalMemorySegment(start, ZGranuleSize));
-  }
-
-  return pmem;
-}
-
-void ZPhysicalMemoryBacking::free(const ZPhysicalMemory& pmem) {
-  const size_t nsegments = pmem.nsegments();
-
-  // Free segments
-  for (size_t i = 0; i < nsegments; i++) {
-    const ZPhysicalMemorySegment& segment = pmem.segment(i);
-    _committed.free(segment.start(), segment.size());
-  }
-}
-
-void ZPhysicalMemoryBacking::map_failed(ZErrno err) const {
-  if (err == ENOMEM) {
-    fatal("Failed to map memory. Please check the system limit on number of "
-          "memory mappings allowed per process (see %s)", ZFILENAME_PROC_MAX_MAP_COUNT);
-  } else {
-    fatal("Failed to map memory (%s)", err.to_string());
-  }
-}
-
-void ZPhysicalMemoryBacking::advise_view(uintptr_t addr, size_t size, int advice) const {
-  if (madvise((void*)addr, size, advice) == -1) {
-    ZErrno err;
-    log_error(gc)("Failed to advise on memory (advice %d, %s)", advice, err.to_string());
-  }
-}
-
-void ZPhysicalMemoryBacking::pretouch_view(uintptr_t addr, size_t size) const {
-  const size_t page_size = ZLargePages::is_explicit() ? os::large_page_size() : os::vm_page_size();
-  os::pretouch_memory((void*)addr, (void*)(addr + size), page_size);
-}
-
-void ZPhysicalMemoryBacking::map_view(const ZPhysicalMemory& pmem, uintptr_t addr, bool pretouch) const {
-  const size_t nsegments = pmem.nsegments();
-  size_t size = 0;
-
-  // Map segments
-  for (size_t i = 0; i < nsegments; i++) {
-    const ZPhysicalMemorySegment& segment = pmem.segment(i);
-    const uintptr_t segment_addr = addr + size;
-    const void* const res = mmap((void*)segment_addr, segment.size(), PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, _file.fd(), segment.start());
-    if (res == MAP_FAILED) {
-      ZErrno err;
-      map_failed(err);
-    }
-
-    size += segment.size();
-  }
-
-  // Advise on use of transparent huge pages before touching it
-  if (ZLargePages::is_transparent()) {
-    advise_view(addr, size, MADV_HUGEPAGE);
-  }
-
-  // NUMA interleave memory before touching it
-  ZNUMA::memory_interleave(addr, size);
-
-  // Pre-touch memory
-  if (pretouch) {
-    pretouch_view(addr, size);
-  }
-}
-
-void ZPhysicalMemoryBacking::unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const {
-  // Note that we must keep the address space reservation intact and just detach
-  // the backing memory. For this reason we map a new anonymous, non-accessible
-  // and non-reserved page over the mapping instead of actually unmapping.
-  const void* const res = mmap((void*)addr, pmem.size(), PROT_NONE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
-  if (res == MAP_FAILED) {
-    ZErrno err;
-    map_failed(err);
-  }
-}
-
-uintptr_t ZPhysicalMemoryBacking::nmt_address(uintptr_t offset) const {
-  // From an NMT point of view we treat the first heap view (marked0) as committed
-  return ZAddress::marked0(offset);
-}
-
-void ZPhysicalMemoryBacking::map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
-  if (ZVerifyViews) {
-    // Map good view
-    map_view(pmem, ZAddress::good(offset), AlwaysPreTouch);
-  } else {
-    // Map all views
-    map_view(pmem, ZAddress::marked0(offset), AlwaysPreTouch);
-    map_view(pmem, ZAddress::marked1(offset), AlwaysPreTouch);
-    map_view(pmem, ZAddress::remapped(offset), AlwaysPreTouch);
-  }
-}
-
-void ZPhysicalMemoryBacking::unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
-  if (ZVerifyViews) {
-    // Unmap good view
-    unmap_view(pmem, ZAddress::good(offset));
-  } else {
-    // Unmap all views
-    unmap_view(pmem, ZAddress::marked0(offset));
-    unmap_view(pmem, ZAddress::marked1(offset));
-    unmap_view(pmem, ZAddress::remapped(offset));
-  }
-}
-
-void ZPhysicalMemoryBacking::debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
-  // Map good view
-  assert(ZVerifyViews, "Should be enabled");
-  map_view(pmem, ZAddress::good(offset), false /* pretouch */);
-}
-
-void ZPhysicalMemoryBacking::debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
-  // Unmap good view
-  assert(ZVerifyViews, "Should be enabled");
-  unmap_view(pmem, ZAddress::good(offset));
-}
--- a/src/hotspot/os_cpu/linux_aarch64/gc/z/zPhysicalMemoryBacking_linux_aarch64.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * 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
- * 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 OS_CPU_LINUX_AARCH64_GC_Z_ZPHYSICALMEMORYBACKING_LINUX_AARCH64_HPP
-#define OS_CPU_LINUX_AARCH64_GC_Z_ZPHYSICALMEMORYBACKING_LINUX_AARCH64_HPP
-
-#include "gc/z/zBackingFile_linux_aarch64.hpp"
-#include "gc/z/zMemory.hpp"
-
-class ZErrno;
-class ZPhysicalMemory;
-
-class ZPhysicalMemoryBacking {
-private:
-  ZBackingFile   _file;
-  ZMemoryManager _committed;
-  ZMemoryManager _uncommitted;
-
-  void warn_available_space(size_t max) const;
-  void warn_max_map_count(size_t max) const;
-
-  void map_failed(ZErrno err) const;
-
-  void advise_view(uintptr_t addr, size_t size, int advice) const;
-  void pretouch_view(uintptr_t addr, size_t size) const;
-  void map_view(const ZPhysicalMemory& pmem, uintptr_t addr, bool pretouch) const;
-  void unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const;
-
-public:
-  bool is_initialized() const;
-
-  void warn_commit_limits(size_t max) const;
-  bool supports_uncommit();
-
-  size_t commit(size_t size);
-  size_t uncommit(size_t size);
-
-  ZPhysicalMemory alloc(size_t size);
-  void free(const ZPhysicalMemory& pmem);
-
-  uintptr_t nmt_address(uintptr_t offset) const;
-
-  void map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
-  void unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
-
-  void debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
-  void debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
-};
-
-#endif // OS_CPU_LINUX_AARCH64_GC_Z_ZPHYSICALMEMORYBACKING_LINUX_AARCH64_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_aarch64/gc/z/zSyscall_linux_aarch64.hpp	Wed Aug 28 11:58:56 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.
+ */
+
+#ifndef OS_CPU_LINUX_AARCH64_GC_Z_ZSYSCALL_LINUX_AARCH64_HPP
+#define OS_CPU_LINUX_AARCH64_GC_Z_ZSYSCALL_LINUX_AARCH64_HPP
+
+#include <sys/syscall.h>
+
+//
+// Support for building on older Linux systems
+//
+
+#ifndef SYS_memfd_create
+#define SYS_memfd_create     279
+#endif
+#ifndef SYS_fallocate
+#define SYS_fallocate        47
+#endif
+
+#endif // OS_CPU_LINUX_AARCH64_GC_Z_ZSYSCALL_LINUX_AARCH64_HPP
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,590 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "gc/z/zArray.inline.hpp"
-#include "gc/z/zBackingFile_linux_x86.hpp"
-#include "gc/z/zBackingPath_linux_x86.hpp"
-#include "gc/z/zErrno.hpp"
-#include "gc/z/zGlobals.hpp"
-#include "gc/z/zLargePages.inline.hpp"
-#include "logging/log.hpp"
-#include "runtime/init.hpp"
-#include "runtime/os.hpp"
-#include "utilities/align.hpp"
-#include "utilities/debug.hpp"
-
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-//
-// Support for building on older Linux systems
-//
-
-// System calls
-#ifndef SYS_fallocate
-#define SYS_fallocate                    285
-#endif
-#ifndef SYS_memfd_create
-#define SYS_memfd_create                 319
-#endif
-
-// memfd_create(2) flags
-#ifndef MFD_CLOEXEC
-#define MFD_CLOEXEC                      0x0001U
-#endif
-#ifndef MFD_HUGETLB
-#define MFD_HUGETLB                      0x0004U
-#endif
-
-// open(2) flags
-#ifndef O_CLOEXEC
-#define O_CLOEXEC                        02000000
-#endif
-#ifndef O_TMPFILE
-#define O_TMPFILE                        (020000000 | O_DIRECTORY)
-#endif
-
-// fallocate(2) flags
-#ifndef FALLOC_FL_KEEP_SIZE
-#define FALLOC_FL_KEEP_SIZE              0x01
-#endif
-#ifndef FALLOC_FL_PUNCH_HOLE
-#define FALLOC_FL_PUNCH_HOLE             0x02
-#endif
-
-// Filesystem types, see statfs(2)
-#ifndef TMPFS_MAGIC
-#define TMPFS_MAGIC                      0x01021994
-#endif
-#ifndef HUGETLBFS_MAGIC
-#define HUGETLBFS_MAGIC                  0x958458f6
-#endif
-
-// Filesystem names
-#define ZFILESYSTEM_TMPFS                "tmpfs"
-#define ZFILESYSTEM_HUGETLBFS            "hugetlbfs"
-
-// Sysfs file for transparent huge page on tmpfs
-#define ZFILENAME_SHMEM_ENABLED          "/sys/kernel/mm/transparent_hugepage/shmem_enabled"
-
-// Java heap filename
-#define ZFILENAME_HEAP                   "java_heap"
-
-// Preferred tmpfs mount points, ordered by priority
-static const char* z_preferred_tmpfs_mountpoints[] = {
-  "/dev/shm",
-  "/run/shm",
-  NULL
-};
-
-// Preferred hugetlbfs mount points, ordered by priority
-static const char* z_preferred_hugetlbfs_mountpoints[] = {
-  "/dev/hugepages",
-  "/hugepages",
-  NULL
-};
-
-static int z_fallocate_hugetlbfs_attempts = 3;
-static bool z_fallocate_supported = true;
-
-static int z_fallocate(int fd, int mode, size_t offset, size_t length) {
-  return syscall(SYS_fallocate, fd, mode, offset, length);
-}
-
-static int z_memfd_create(const char *name, unsigned int flags) {
-  return syscall(SYS_memfd_create, name, flags);
-}
-
-ZBackingFile::ZBackingFile() :
-    _fd(-1),
-    _size(0),
-    _filesystem(0),
-    _block_size(0),
-    _available(0),
-    _initialized(false) {
-
-  // Create backing file
-  _fd = create_fd(ZFILENAME_HEAP);
-  if (_fd == -1) {
-    return;
-  }
-
-  // Get filesystem statistics
-  struct statfs buf;
-  if (fstatfs(_fd, &buf) == -1) {
-    ZErrno err;
-    log_error(gc)("Failed to determine filesystem type for backing file (%s)", err.to_string());
-    return;
-  }
-
-  _filesystem = buf.f_type;
-  _block_size = buf.f_bsize;
-  _available = buf.f_bavail * _block_size;
-
-  // Make sure we're on a supported filesystem
-  if (!is_tmpfs() && !is_hugetlbfs()) {
-    log_error(gc)("Backing file must be located on a %s or a %s filesystem",
-                  ZFILESYSTEM_TMPFS, ZFILESYSTEM_HUGETLBFS);
-    return;
-  }
-
-  // Make sure the filesystem type matches requested large page type
-  if (ZLargePages::is_transparent() && !is_tmpfs()) {
-    log_error(gc)("-XX:+UseTransparentHugePages can only be enable when using a %s filesystem",
-                  ZFILESYSTEM_TMPFS);
-    return;
-  }
-
-  if (ZLargePages::is_transparent() && !tmpfs_supports_transparent_huge_pages()) {
-    log_error(gc)("-XX:+UseTransparentHugePages on a %s filesystem not supported by kernel",
-                  ZFILESYSTEM_TMPFS);
-    return;
-  }
-
-  if (ZLargePages::is_explicit() && !is_hugetlbfs()) {
-    log_error(gc)("-XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled "
-                  "when using a %s filesystem", ZFILESYSTEM_HUGETLBFS);
-    return;
-  }
-
-  if (!ZLargePages::is_explicit() && is_hugetlbfs()) {
-    log_error(gc)("-XX:+UseLargePages must be enabled when using a %s filesystem",
-                  ZFILESYSTEM_HUGETLBFS);
-    return;
-  }
-
-  const size_t expected_block_size = is_tmpfs() ? os::vm_page_size() : os::large_page_size();
-  if (expected_block_size != _block_size) {
-    log_error(gc)("%s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT ")",
-                  is_tmpfs() ? ZFILESYSTEM_TMPFS : ZFILESYSTEM_HUGETLBFS, _block_size, expected_block_size);
-    return;
-  }
-
-  // Successfully initialized
-  _initialized = true;
-}
-
-int ZBackingFile::create_mem_fd(const char* name) const {
-  // Create file name
-  char filename[PATH_MAX];
-  snprintf(filename, sizeof(filename), "%s%s", name, ZLargePages::is_explicit() ? ".hugetlb" : "");
-
-  // Create file
-  const int extra_flags = ZLargePages::is_explicit() ? MFD_HUGETLB : 0;
-  const int fd = z_memfd_create(filename, MFD_CLOEXEC | extra_flags);
-  if (fd == -1) {
-    ZErrno err;
-    log_debug(gc, init)("Failed to create memfd file (%s)",
-                        ((ZLargePages::is_explicit() && err == EINVAL) ? "Hugepages not supported" : err.to_string()));
-    return -1;
-  }
-
-  log_info(gc, init)("Heap backed by file: /memfd:%s", filename);
-
-  return fd;
-}
-
-int ZBackingFile::create_file_fd(const char* name) const {
-  const char* const filesystem = ZLargePages::is_explicit()
-                                 ? ZFILESYSTEM_HUGETLBFS
-                                 : ZFILESYSTEM_TMPFS;
-  const char** const preferred_mountpoints = ZLargePages::is_explicit()
-                                             ? z_preferred_hugetlbfs_mountpoints
-                                             : z_preferred_tmpfs_mountpoints;
-
-  // Find mountpoint
-  ZBackingPath path(filesystem, preferred_mountpoints);
-  if (path.get() == NULL) {
-    log_error(gc)("Use -XX:ZPath to specify the path to a %s filesystem", filesystem);
-    return -1;
-  }
-
-  // Try to create an anonymous file using the O_TMPFILE flag. Note that this
-  // flag requires kernel >= 3.11. If this fails we fall back to open/unlink.
-  const int fd_anon = os::open(path.get(), O_TMPFILE|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
-  if (fd_anon == -1) {
-    ZErrno err;
-    log_debug(gc, init)("Failed to create anonymous file in %s (%s)", path.get(),
-                        (err == EINVAL ? "Not supported" : err.to_string()));
-  } else {
-    // Get inode number for anonymous file
-    struct stat stat_buf;
-    if (fstat(fd_anon, &stat_buf) == -1) {
-      ZErrno err;
-      log_error(gc)("Failed to determine inode number for anonymous file (%s)", err.to_string());
-      return -1;
-    }
-
-    log_info(gc, init)("Heap backed by file: %s/#" UINT64_FORMAT, path.get(), (uint64_t)stat_buf.st_ino);
-
-    return fd_anon;
-  }
-
-  log_debug(gc, init)("Falling back to open/unlink");
-
-  // Create file name
-  char filename[PATH_MAX];
-  snprintf(filename, sizeof(filename), "%s/%s.%d", path.get(), name, os::current_process_id());
-
-  // Create file
-  const int fd = os::open(filename, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
-  if (fd == -1) {
-    ZErrno err;
-    log_error(gc)("Failed to create file %s (%s)", filename, err.to_string());
-    return -1;
-  }
-
-  // Unlink file
-  if (unlink(filename) == -1) {
-    ZErrno err;
-    log_error(gc)("Failed to unlink file %s (%s)", filename, err.to_string());
-    return -1;
-  }
-
-  log_info(gc, init)("Heap backed by file: %s", filename);
-
-  return fd;
-}
-
-int ZBackingFile::create_fd(const char* name) const {
-  if (ZPath == NULL) {
-    // If the path is not explicitly specified, then we first try to create a memfd file
-    // instead of looking for a tmpfd/hugetlbfs mount point. Note that memfd_create() might
-    // not be supported at all (requires kernel >= 3.17), or it might not support large
-    // pages (requires kernel >= 4.14). If memfd_create() fails, then we try to create a
-    // file on an accessible tmpfs or hugetlbfs mount point.
-    const int fd = create_mem_fd(name);
-    if (fd != -1) {
-      return fd;
-    }
-
-    log_debug(gc, init)("Falling back to searching for an accessible mount point");
-  }
-
-  return create_file_fd(name);
-}
-
-bool ZBackingFile::is_initialized() const {
-  return _initialized;
-}
-
-int ZBackingFile::fd() const {
-  return _fd;
-}
-
-size_t ZBackingFile::size() const {
-  return _size;
-}
-
-size_t ZBackingFile::available() const {
-  return _available;
-}
-
-bool ZBackingFile::is_tmpfs() const {
-  return _filesystem == TMPFS_MAGIC;
-}
-
-bool ZBackingFile::is_hugetlbfs() const {
-  return _filesystem == HUGETLBFS_MAGIC;
-}
-
-bool ZBackingFile::tmpfs_supports_transparent_huge_pages() const {
-  // If the shmem_enabled file exists and is readable then we
-  // know the kernel supports transparent huge pages for tmpfs.
-  return access(ZFILENAME_SHMEM_ENABLED, R_OK) == 0;
-}
-
-ZErrno ZBackingFile::fallocate_compat_ftruncate(size_t size) const {
-  while (ftruncate(_fd, size) == -1) {
-    if (errno != EINTR) {
-      // Failed
-      return errno;
-    }
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate_compat_mmap(size_t offset, size_t length, bool touch) const {
-  // On hugetlbfs, mapping a file segment will fail immediately, without
-  // the need to touch the mapped pages first, if there aren't enough huge
-  // pages available to back the mapping.
-  void* const addr = mmap(0, length, PROT_READ|PROT_WRITE, MAP_SHARED, _fd, offset);
-  if (addr == MAP_FAILED) {
-    // Failed
-    return errno;
-  }
-
-  // Once mapped, the huge pages are only reserved. We need to touch them
-  // to associate them with the file segment. Note that we can not punch
-  // hole in file segments which only have reserved pages.
-  if (touch) {
-    char* const start = (char*)addr;
-    char* const end = start + length;
-    os::pretouch_memory(start, end, _block_size);
-  }
-
-  // Unmap again. From now on, the huge pages that were mapped are allocated
-  // to this file. There's no risk in getting SIGBUS when touching them.
-  if (munmap(addr, length) == -1) {
-    // Failed
-    return errno;
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate_compat_pwrite(size_t offset, size_t length) const {
-  uint8_t data = 0;
-
-  // Allocate backing memory by writing to each block
-  for (size_t pos = offset; pos < offset + length; pos += _block_size) {
-    if (pwrite(_fd, &data, sizeof(data), pos) == -1) {
-      // Failed
-      return errno;
-    }
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate_fill_hole_compat(size_t offset, size_t length) {
-  // fallocate(2) is only supported by tmpfs since Linux 3.5, and by hugetlbfs
-  // since Linux 4.3. When fallocate(2) is not supported we emulate it using
-  // ftruncate/pwrite (for tmpfs) or ftruncate/mmap/munmap (for hugetlbfs).
-
-  const size_t end = offset + length;
-  if (end > _size) {
-    // Increase file size
-    const ZErrno err = fallocate_compat_ftruncate(end);
-    if (err) {
-      // Failed
-      return err;
-    }
-  }
-
-  // Allocate backing memory
-  const ZErrno err = is_hugetlbfs() ? fallocate_compat_mmap(offset, length, false /* touch */)
-                                    : fallocate_compat_pwrite(offset, length);
-  if (err) {
-    if (end > _size) {
-      // Restore file size
-      fallocate_compat_ftruncate(_size);
-    }
-
-    // Failed
-    return err;
-  }
-
-  if (end > _size) {
-    // Record new file size
-    _size = end;
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate_fill_hole_syscall(size_t offset, size_t length) {
-  const int mode = 0; // Allocate
-  const int res = z_fallocate(_fd, mode, offset, length);
-  if (res == -1) {
-    // Failed
-    return errno;
-  }
-
-  const size_t end = offset + length;
-  if (end > _size) {
-    // Record new file size
-    _size = end;
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate_fill_hole(size_t offset, size_t length) {
-  // Using compat mode is more efficient when allocating space on hugetlbfs.
-  // Note that allocating huge pages this way will only reserve them, and not
-  // associate them with segments of the file. We must guarantee that we at
-  // some point touch these segments, otherwise we can not punch hole in them.
-  if (z_fallocate_supported && !is_hugetlbfs()) {
-     const ZErrno err = fallocate_fill_hole_syscall(offset, length);
-     if (!err) {
-       // Success
-       return 0;
-     }
-
-     if (err != ENOSYS && err != EOPNOTSUPP) {
-       // Failed
-       return err;
-     }
-
-     // Not supported
-     log_debug(gc)("Falling back to fallocate() compatibility mode");
-     z_fallocate_supported = false;
-  }
-
-  return fallocate_fill_hole_compat(offset, length);
-}
-
-ZErrno ZBackingFile::fallocate_punch_hole(size_t offset, size_t length) {
-  if (is_hugetlbfs()) {
-    // We can only punch hole in pages that have been touched. Non-touched
-    // pages are only reserved, and not associated with any specific file
-    // segment. We don't know which pages have been previously touched, so
-    // we always touch them here to guarantee that we can punch hole.
-    const ZErrno err = fallocate_compat_mmap(offset, length, true /* touch */);
-    if (err) {
-      // Failed
-      return err;
-    }
-  }
-
-  const int mode = FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE;
-  if (z_fallocate(_fd, mode, offset, length) == -1) {
-    // Failed
-    return errno;
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::split_and_fallocate(bool punch_hole, size_t offset, size_t length) {
-  // Try first half
-  const size_t offset0 = offset;
-  const size_t length0 = align_up(length / 2, _block_size);
-  const ZErrno err0 = fallocate(punch_hole, offset0, length0);
-  if (err0) {
-    return err0;
-  }
-
-  // Try second half
-  const size_t offset1 = offset0 + length0;
-  const size_t length1 = length - length0;
-  const ZErrno err1 = fallocate(punch_hole, offset1, length1);
-  if (err1) {
-    return err1;
-  }
-
-  // Success
-  return 0;
-}
-
-ZErrno ZBackingFile::fallocate(bool punch_hole, size_t offset, size_t length) {
-  assert(is_aligned(offset, _block_size), "Invalid offset");
-  assert(is_aligned(length, _block_size), "Invalid length");
-
-  const ZErrno err = punch_hole ? fallocate_punch_hole(offset, length) : fallocate_fill_hole(offset, length);
-  if (err == EINTR && length > _block_size) {
-    // Calling fallocate(2) with a large length can take a long time to
-    // complete. When running profilers, such as VTune, this syscall will
-    // be constantly interrupted by signals. Expanding the file in smaller
-    // steps avoids this problem.
-    return split_and_fallocate(punch_hole, offset, length);
-  }
-
-  return err;
-}
-
-bool ZBackingFile::commit_inner(size_t offset, size_t length) {
-  log_trace(gc, heap)("Committing memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
-                      offset / M, (offset + length) / M, length / M);
-
-retry:
-  const ZErrno err = fallocate(false /* punch_hole */, offset, length);
-  if (err) {
-    if (err == ENOSPC && !is_init_completed() && is_hugetlbfs() && z_fallocate_hugetlbfs_attempts-- > 0) {
-      // If we fail to allocate during initialization, due to lack of space on
-      // the hugetlbfs filesystem, then we wait and retry a few times before
-      // giving up. Otherwise there is a risk that running JVMs back-to-back
-      // will fail, since there is a delay between process termination and the
-      // huge pages owned by that process being returned to the huge page pool
-      // and made available for new allocations.
-      log_debug(gc, init)("Failed to commit memory (%s), retrying", err.to_string());
-
-      // Wait and retry in one second, in the hope that huge pages will be
-      // available by then.
-      sleep(1);
-      goto retry;
-    }
-
-    // Failed
-    log_error(gc)("Failed to commit memory (%s)", err.to_string());
-    return false;
-  }
-
-  // Success
-  return true;
-}
-
-size_t ZBackingFile::commit(size_t offset, size_t length) {
-  // Try to commit the whole region
-  if (commit_inner(offset, length)) {
-    // Success
-    return length;
-  }
-
-  // Failed, try to commit as much as possible
-  size_t start = offset;
-  size_t end = offset + length;
-
-  for (;;) {
-    length = align_down((end - start) / 2, ZGranuleSize);
-    if (length < ZGranuleSize) {
-      // Done, don't commit more
-      return start - offset;
-    }
-
-    if (commit_inner(start, length)) {
-      // Success, try commit more
-      start += length;
-    } else {
-      // Failed, try commit less
-      end -= length;
-    }
-  }
-}
-
-size_t ZBackingFile::uncommit(size_t offset, size_t length) {
-  log_trace(gc, heap)("Uncommitting memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
-                      offset / M, (offset + length) / M, length / M);
-
-  const ZErrno err = fallocate(true /* punch_hole */, offset, length);
-  if (err) {
-    log_error(gc)("Failed to uncommit memory (%s)", err.to_string());
-    return 0;
-  }
-
-  return length;
-}
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/*
- * 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
- * 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 OS_CPU_LINUX_X86_GC_Z_ZBACKINGFILE_LINUX_X86_HPP
-#define OS_CPU_LINUX_X86_GC_Z_ZBACKINGFILE_LINUX_X86_HPP
-
-#include "memory/allocation.hpp"
-
-class ZErrno;
-
-class ZBackingFile {
-private:
-  int      _fd;
-  size_t   _size;
-  uint64_t _filesystem;
-  size_t   _block_size;
-  size_t   _available;
-  bool     _initialized;
-
-  int create_mem_fd(const char* name) const;
-  int create_file_fd(const char* name) const;
-  int create_fd(const char* name) const;
-
-  bool is_tmpfs() const;
-  bool is_hugetlbfs() const;
-  bool tmpfs_supports_transparent_huge_pages() const;
-
-  ZErrno fallocate_compat_ftruncate(size_t size) const;
-  ZErrno fallocate_compat_mmap(size_t offset, size_t length, bool reserve_only) const;
-  ZErrno fallocate_compat_pwrite(size_t offset, size_t length) const;
-  ZErrno fallocate_fill_hole_compat(size_t offset, size_t length);
-  ZErrno fallocate_fill_hole_syscall(size_t offset, size_t length);
-  ZErrno fallocate_fill_hole(size_t offset, size_t length);
-  ZErrno fallocate_punch_hole(size_t offset, size_t length);
-  ZErrno split_and_fallocate(bool punch_hole, size_t offset, size_t length);
-  ZErrno fallocate(bool punch_hole, size_t offset, size_t length);
-
-  bool commit_inner(size_t offset, size_t length);
-
-public:
-  ZBackingFile();
-
-  bool is_initialized() const;
-
-  int fd() const;
-  size_t size() const;
-  size_t available() const;
-
-  size_t commit(size_t offset, size_t length);
-  size_t uncommit(size_t offset, size_t length);
-};
-
-#endif // OS_CPU_LINUX_X86_GC_Z_ZBACKINGFILE_LINUX_X86_HPP
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zBackingPath_linux_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "gc/z/zArray.inline.hpp"
-#include "gc/z/zBackingPath_linux_x86.hpp"
-#include "gc/z/zErrno.hpp"
-#include "logging/log.hpp"
-
-#include <stdio.h>
-#include <unistd.h>
-
-// Mount information, see proc(5) for more details.
-#define PROC_SELF_MOUNTINFO        "/proc/self/mountinfo"
-
-ZBackingPath::ZBackingPath(const char* filesystem, const char** preferred_mountpoints) {
-  if (ZPath != NULL) {
-    // Use specified path
-    _path = strdup(ZPath);
-  } else {
-    // Find suitable path
-    _path = find_mountpoint(filesystem, preferred_mountpoints);
-  }
-}
-
-ZBackingPath::~ZBackingPath() {
-  free(_path);
-  _path = NULL;
-}
-
-char* ZBackingPath::get_mountpoint(const char* line, const char* filesystem) const {
-  char* line_mountpoint = NULL;
-  char* line_filesystem = NULL;
-
-  // Parse line and return a newly allocated string containing the mount point if
-  // the line contains a matching filesystem and the mount point is accessible by
-  // the current user.
-  if (sscanf(line, "%*u %*u %*u:%*u %*s %ms %*[^-]- %ms", &line_mountpoint, &line_filesystem) != 2 ||
-      strcmp(line_filesystem, filesystem) != 0 ||
-      access(line_mountpoint, R_OK|W_OK|X_OK) != 0) {
-    // Not a matching or accessible filesystem
-    free(line_mountpoint);
-    line_mountpoint = NULL;
-  }
-
-  free(line_filesystem);
-
-  return line_mountpoint;
-}
-
-void ZBackingPath::get_mountpoints(const char* filesystem, ZArray<char*>* mountpoints) const {
-  FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r");
-  if (fd == NULL) {
-    ZErrno err;
-    log_error(gc)("Failed to open %s: %s", PROC_SELF_MOUNTINFO, err.to_string());
-    return;
-  }
-
-  char* line = NULL;
-  size_t length = 0;
-
-  while (getline(&line, &length, fd) != -1) {
-    char* const mountpoint = get_mountpoint(line, filesystem);
-    if (mountpoint != NULL) {
-      mountpoints->add(mountpoint);
-    }
-  }
-
-  free(line);
-  fclose(fd);
-}
-
-void ZBackingPath::free_mountpoints(ZArray<char*>* mountpoints) const {
-  ZArrayIterator<char*> iter(mountpoints);
-  for (char* mountpoint; iter.next(&mountpoint);) {
-    free(mountpoint);
-  }
-  mountpoints->clear();
-}
-
-char* ZBackingPath::find_preferred_mountpoint(const char* filesystem,
-                                              ZArray<char*>* mountpoints,
-                                              const char** preferred_mountpoints) const {
-  // Find preferred mount point
-  ZArrayIterator<char*> iter1(mountpoints);
-  for (char* mountpoint; iter1.next(&mountpoint);) {
-    for (const char** preferred = preferred_mountpoints; *preferred != NULL; preferred++) {
-      if (!strcmp(mountpoint, *preferred)) {
-        // Preferred mount point found
-        return strdup(mountpoint);
-      }
-    }
-  }
-
-  // Preferred mount point not found
-  log_error(gc)("More than one %s filesystem found:", filesystem);
-  ZArrayIterator<char*> iter2(mountpoints);
-  for (char* mountpoint; iter2.next(&mountpoint);) {
-    log_error(gc)("  %s", mountpoint);
-  }
-
-  return NULL;
-}
-
-char* ZBackingPath::find_mountpoint(const char* filesystem, const char** preferred_mountpoints) const {
-  char* path = NULL;
-  ZArray<char*> mountpoints;
-
-  get_mountpoints(filesystem, &mountpoints);
-
-  if (mountpoints.size() == 0) {
-    // No mount point found
-    log_error(gc)("Failed to find an accessible %s filesystem", filesystem);
-  } else if (mountpoints.size() == 1) {
-    // One mount point found
-    path = strdup(mountpoints.at(0));
-  } else {
-    // More than one mount point found
-    path = find_preferred_mountpoint(filesystem, &mountpoints, preferred_mountpoints);
-  }
-
-  free_mountpoints(&mountpoints);
-
-  return path;
-}
-
-const char* ZBackingPath::get() const {
-  return _path;
-}
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zBackingPath_linux_x86.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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 OS_CPU_LINUX_X86_GC_Z_ZBACKINGPATH_LINUX_X86_HPP
-#define OS_CPU_LINUX_X86_GC_Z_ZBACKINGPATH_LINUX_X86_HPP
-
-#include "gc/z/zArray.hpp"
-#include "memory/allocation.hpp"
-
-class ZBackingPath : public StackObj {
-private:
-  char* _path;
-
-  char* get_mountpoint(const char* line,
-                       const char* filesystem) const;
-  void get_mountpoints(const char* filesystem,
-                       ZArray<char*>* mountpoints) const;
-  void free_mountpoints(ZArray<char*>* mountpoints) const;
-  char* find_preferred_mountpoint(const char* filesystem,
-                                  ZArray<char*>* mountpoints,
-                                  const char** preferred_mountpoints) const;
-  char* find_mountpoint(const char* filesystem,
-                        const char** preferred_mountpoints) const;
-
-public:
-  ZBackingPath(const char* filesystem, const char** preferred_mountpoints);
-  ~ZBackingPath();
-
-  const char* get() const;
-};
-
-#endif // OS_CPU_LINUX_X86_GC_Z_ZBACKINGPATH_LINUX_X86_HPP
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zPhysicalMemoryBacking_linux_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,333 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "gc/z/zAddress.inline.hpp"
-#include "gc/z/zBackingFile_linux_x86.hpp"
-#include "gc/z/zErrno.hpp"
-#include "gc/z/zGlobals.hpp"
-#include "gc/z/zLargePages.inline.hpp"
-#include "gc/z/zMemory.hpp"
-#include "gc/z/zNUMA.hpp"
-#include "gc/z/zPhysicalMemory.inline.hpp"
-#include "gc/z/zPhysicalMemoryBacking_linux_x86.hpp"
-#include "logging/log.hpp"
-#include "runtime/init.hpp"
-#include "runtime/os.hpp"
-#include "utilities/align.hpp"
-#include "utilities/debug.hpp"
-
-#include <stdio.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-
-//
-// Support for building on older Linux systems
-//
-
-// madvise(2) flags
-#ifndef MADV_HUGEPAGE
-#define MADV_HUGEPAGE                        14
-#endif
-
-// Proc file entry for max map mount
-#define ZFILENAME_PROC_MAX_MAP_COUNT         "/proc/sys/vm/max_map_count"
-
-bool ZPhysicalMemoryBacking::is_initialized() const {
-  return _file.is_initialized();
-}
-
-void ZPhysicalMemoryBacking::warn_available_space(size_t max) const {
-  // Note that the available space on a tmpfs or a hugetlbfs filesystem
-  // will be zero if no size limit was specified when it was mounted.
-  const size_t available = _file.available();
-  if (available == 0) {
-    // No size limit set, skip check
-    log_info(gc, init)("Available space on backing filesystem: N/A");
-    return;
-  }
-
-  log_info(gc, init)("Available space on backing filesystem: " SIZE_FORMAT "M", available / M);
-
-  // Warn if the filesystem doesn't currently have enough space available to hold
-  // the max heap size. The max heap size will be capped if we later hit this limit
-  // when trying to expand the heap.
-  if (available < max) {
-    log_warning(gc)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****");
-    log_warning(gc)("Not enough space available on the backing filesystem to hold the current max Java heap");
-    log_warning(gc)("size (" SIZE_FORMAT "M). Please adjust the size of the backing filesystem accordingly "
-                    "(available", max / M);
-    log_warning(gc)("space is currently " SIZE_FORMAT "M). Continuing execution with the current filesystem "
-                    "size could", available / M);
-    log_warning(gc)("lead to a premature OutOfMemoryError being thrown, due to failure to map memory.");
-  }
-}
-
-void ZPhysicalMemoryBacking::warn_max_map_count(size_t max) const {
-  const char* const filename = ZFILENAME_PROC_MAX_MAP_COUNT;
-  FILE* const file = fopen(filename, "r");
-  if (file == NULL) {
-    // Failed to open file, skip check
-    log_debug(gc, init)("Failed to open %s", filename);
-    return;
-  }
-
-  size_t actual_max_map_count = 0;
-  const int result = fscanf(file, SIZE_FORMAT, &actual_max_map_count);
-  fclose(file);
-  if (result != 1) {
-    // Failed to read file, skip check
-    log_debug(gc, init)("Failed to read %s", filename);
-    return;
-  }
-
-  // The required max map count is impossible to calculate exactly since subsystems
-  // other than ZGC are also creating memory mappings, and we have no control over that.
-  // However, ZGC tends to create the most mappings and dominate the total count.
-  // In the worst cases, ZGC will map each granule three times, i.e. once per heap view.
-  // We speculate that we need another 20% to allow for non-ZGC subsystems to map memory.
-  const size_t required_max_map_count = (max / ZGranuleSize) * 3 * 1.2;
-  if (actual_max_map_count < required_max_map_count) {
-    log_warning(gc)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****");
-    log_warning(gc)("The system limit on number of memory mappings per process might be too low for the given");
-    log_warning(gc)("max Java heap size (" SIZE_FORMAT "M). Please adjust %s to allow for at",
-                    max / M, filename);
-    log_warning(gc)("least " SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT "). Continuing execution "
-                    "with the current", required_max_map_count, actual_max_map_count);
-    log_warning(gc)("limit could lead to a fatal error, due to failure to map memory.");
-  }
-}
-
-void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
-  // Warn if available space is too low
-  warn_available_space(max);
-
-  // Warn if max map count is too low
-  warn_max_map_count(max);
-}
-
-bool ZPhysicalMemoryBacking::supports_uncommit() {
-  assert(!is_init_completed(), "Invalid state");
-  assert(_file.size() >= ZGranuleSize, "Invalid size");
-
-  // Test if uncommit is supported by uncommitting and then re-committing a granule
-  return commit(uncommit(ZGranuleSize)) == ZGranuleSize;
-}
-
-size_t ZPhysicalMemoryBacking::commit(size_t size) {
-  size_t committed = 0;
-
-  // Fill holes in the backing file
-  while (committed < size) {
-    size_t allocated = 0;
-    const size_t remaining = size - committed;
-    const uintptr_t start = _uncommitted.alloc_from_front_at_most(remaining, &allocated);
-    if (start == UINTPTR_MAX) {
-      // No holes to commit
-      break;
-    }
-
-    // Try commit hole
-    const size_t filled = _file.commit(start, allocated);
-    if (filled > 0) {
-      // Successful or partialy successful
-      _committed.free(start, filled);
-      committed += filled;
-    }
-    if (filled < allocated) {
-      // Failed or partialy failed
-      _uncommitted.free(start + filled, allocated - filled);
-      return committed;
-    }
-  }
-
-  // Expand backing file
-  if (committed < size) {
-    const size_t remaining = size - committed;
-    const uintptr_t start = _file.size();
-    const size_t expanded = _file.commit(start, remaining);
-    if (expanded > 0) {
-      // Successful or partialy successful
-      _committed.free(start, expanded);
-      committed += expanded;
-    }
-  }
-
-  return committed;
-}
-
-size_t ZPhysicalMemoryBacking::uncommit(size_t size) {
-  size_t uncommitted = 0;
-
-  // Punch holes in backing file
-  while (uncommitted < size) {
-    size_t allocated = 0;
-    const size_t remaining = size - uncommitted;
-    const uintptr_t start = _committed.alloc_from_back_at_most(remaining, &allocated);
-    assert(start != UINTPTR_MAX, "Allocation should never fail");
-
-    // Try punch hole
-    const size_t punched = _file.uncommit(start, allocated);
-    if (punched > 0) {
-      // Successful or partialy successful
-      _uncommitted.free(start, punched);
-      uncommitted += punched;
-    }
-    if (punched < allocated) {
-      // Failed or partialy failed
-      _committed.free(start + punched, allocated - punched);
-      return uncommitted;
-    }
-  }
-
-  return uncommitted;
-}
-
-ZPhysicalMemory ZPhysicalMemoryBacking::alloc(size_t size) {
-  assert(is_aligned(size, ZGranuleSize), "Invalid size");
-
-  ZPhysicalMemory pmem;
-
-  // Allocate segments
-  for (size_t allocated = 0; allocated < size; allocated += ZGranuleSize) {
-    const uintptr_t start = _committed.alloc_from_front(ZGranuleSize);
-    assert(start != UINTPTR_MAX, "Allocation should never fail");
-    pmem.add_segment(ZPhysicalMemorySegment(start, ZGranuleSize));
-  }
-
-  return pmem;
-}
-
-void ZPhysicalMemoryBacking::free(const ZPhysicalMemory& pmem) {
-  const size_t nsegments = pmem.nsegments();
-
-  // Free segments
-  for (size_t i = 0; i < nsegments; i++) {
-    const ZPhysicalMemorySegment& segment = pmem.segment(i);
-    _committed.free(segment.start(), segment.size());
-  }
-}
-
-void ZPhysicalMemoryBacking::map_failed(ZErrno err) const {
-  if (err == ENOMEM) {
-    fatal("Failed to map memory. Please check the system limit on number of "
-          "memory mappings allowed per process (see %s)", ZFILENAME_PROC_MAX_MAP_COUNT);
-  } else {
-    fatal("Failed to map memory (%s)", err.to_string());
-  }
-}
-
-void ZPhysicalMemoryBacking::advise_view(uintptr_t addr, size_t size, int advice) const {
-  if (madvise((void*)addr, size, advice) == -1) {
-    ZErrno err;
-    log_error(gc)("Failed to advise on memory (advice %d, %s)", advice, err.to_string());
-  }
-}
-
-void ZPhysicalMemoryBacking::pretouch_view(uintptr_t addr, size_t size) const {
-  const size_t page_size = ZLargePages::is_explicit() ? os::large_page_size() : os::vm_page_size();
-  os::pretouch_memory((void*)addr, (void*)(addr + size), page_size);
-}
-
-void ZPhysicalMemoryBacking::map_view(const ZPhysicalMemory& pmem, uintptr_t addr, bool pretouch) const {
-  const size_t nsegments = pmem.nsegments();
-  size_t size = 0;
-
-  // Map segments
-  for (size_t i = 0; i < nsegments; i++) {
-    const ZPhysicalMemorySegment& segment = pmem.segment(i);
-    const uintptr_t segment_addr = addr + size;
-    const void* const res = mmap((void*)segment_addr, segment.size(), PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, _file.fd(), segment.start());
-    if (res == MAP_FAILED) {
-      ZErrno err;
-      map_failed(err);
-    }
-
-    size += segment.size();
-  }
-
-  // Advise on use of transparent huge pages before touching it
-  if (ZLargePages::is_transparent()) {
-    advise_view(addr, size, MADV_HUGEPAGE);
-  }
-
-  // NUMA interleave memory before touching it
-  ZNUMA::memory_interleave(addr, size);
-
-  // Pre-touch memory
-  if (pretouch) {
-    pretouch_view(addr, size);
-  }
-}
-
-void ZPhysicalMemoryBacking::unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const {
-  // Note that we must keep the address space reservation intact and just detach
-  // the backing memory. For this reason we map a new anonymous, non-accessible
-  // and non-reserved page over the mapping instead of actually unmapping.
-  const void* const res = mmap((void*)addr, pmem.size(), PROT_NONE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
-  if (res == MAP_FAILED) {
-    ZErrno err;
-    map_failed(err);
-  }
-}
-
-uintptr_t ZPhysicalMemoryBacking::nmt_address(uintptr_t offset) const {
-  // From an NMT point of view we treat the first heap view (marked0) as committed
-  return ZAddress::marked0(offset);
-}
-
-void ZPhysicalMemoryBacking::map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
-  if (ZVerifyViews) {
-    // Map good view
-    map_view(pmem, ZAddress::good(offset), AlwaysPreTouch);
-  } else {
-    // Map all views
-    map_view(pmem, ZAddress::marked0(offset), AlwaysPreTouch);
-    map_view(pmem, ZAddress::marked1(offset), AlwaysPreTouch);
-    map_view(pmem, ZAddress::remapped(offset), AlwaysPreTouch);
-  }
-}
-
-void ZPhysicalMemoryBacking::unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
-  if (ZVerifyViews) {
-    // Unmap good view
-    unmap_view(pmem, ZAddress::good(offset));
-  } else {
-    // Unmap all views
-    unmap_view(pmem, ZAddress::marked0(offset));
-    unmap_view(pmem, ZAddress::marked1(offset));
-    unmap_view(pmem, ZAddress::remapped(offset));
-  }
-}
-
-void ZPhysicalMemoryBacking::debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
-  // Map good view
-  assert(ZVerifyViews, "Should be enabled");
-  map_view(pmem, ZAddress::good(offset), false /* pretouch */);
-}
-
-void ZPhysicalMemoryBacking::debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
-  // Unmap good view
-  assert(ZVerifyViews, "Should be enabled");
-  unmap_view(pmem, ZAddress::good(offset));
-}
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zPhysicalMemoryBacking_linux_x86.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * 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
- * 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 OS_CPU_LINUX_X86_GC_Z_ZPHYSICALMEMORYBACKING_LINUX_X86_HPP
-#define OS_CPU_LINUX_X86_GC_Z_ZPHYSICALMEMORYBACKING_LINUX_X86_HPP
-
-#include "gc/z/zBackingFile_linux_x86.hpp"
-#include "gc/z/zMemory.hpp"
-
-class ZErrno;
-class ZPhysicalMemory;
-
-class ZPhysicalMemoryBacking {
-private:
-  ZBackingFile   _file;
-  ZMemoryManager _committed;
-  ZMemoryManager _uncommitted;
-
-  void warn_available_space(size_t max) const;
-  void warn_max_map_count(size_t max) const;
-
-  void map_failed(ZErrno err) const;
-
-  void advise_view(uintptr_t addr, size_t size, int advice) const;
-  void pretouch_view(uintptr_t addr, size_t size) const;
-  void map_view(const ZPhysicalMemory& pmem, uintptr_t addr, bool pretouch) const;
-  void unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const;
-
-public:
-  bool is_initialized() const;
-
-  void warn_commit_limits(size_t max) const;
-  bool supports_uncommit();
-
-  size_t commit(size_t size);
-  size_t uncommit(size_t size);
-
-  ZPhysicalMemory alloc(size_t size);
-  void free(const ZPhysicalMemory& pmem);
-
-  uintptr_t nmt_address(uintptr_t offset) const;
-
-  void map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
-  void unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
-
-  void debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
-  void debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
-};
-
-#endif // OS_CPU_LINUX_X86_GC_Z_ZPHYSICALMEMORYBACKING_LINUX_X86_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zSyscall_linux_x86.hpp	Wed Aug 28 11:58:56 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.
+ */
+
+#ifndef OS_CPU_LINUX_X86_GC_Z_ZSYSCALL_LINUX_X86_HPP
+#define OS_CPU_LINUX_X86_GC_Z_ZSYSCALL_LINUX_X86_HPP
+
+#include <sys/syscall.h>
+
+//
+// Support for building on older Linux systems
+//
+
+#ifndef SYS_memfd_create
+#define SYS_memfd_create     319
+#endif
+#ifndef SYS_fallocate
+#define SYS_fallocate        285
+#endif
+
+#endif // OS_CPU_LINUX_X86_GC_Z_ZSYSCALL_LINUX_X86_HPP
--- a/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -541,7 +541,7 @@
         if (cb != NULL) {
           CompiledMethod* nm = cb->as_compiled_method_or_null();
           bool is_unsafe_arraycopy = thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc);
-          if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy)) {
+          if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) {
             address next_pc = Assembler::locate_next_instruction(pc);
             if (is_unsafe_arraycopy) {
               next_pc = UnsafeCopyMemory::page_error_continue_pc(pc);
--- a/src/hotspot/share/adlc/formssel.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/adlc/formssel.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -3518,6 +3518,12 @@
   int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
   if( strcmp(_opType,"PrefetchAllocation")==0 )
     return 1;
+  if( strcmp(_opType,"CacheWB")==0 )
+    return 1;
+  if( strcmp(_opType,"CacheWBPreSync")==0 )
+    return 1;
+  if( strcmp(_opType,"CacheWBPostSync")==0 )
+    return 1;
   if( _lChild ) {
     const char *opType = _lChild->_opType;
     for( int i=0; i<cnt; i++ )
--- a/src/hotspot/share/adlc/main.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/adlc/main.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -218,7 +218,7 @@
   AD.addInclude(AD._CPP_file, "gc/shared/collectedHeap.inline.hpp");
   AD.addInclude(AD._CPP_file, "oops/compiledICHolder.hpp");
   AD.addInclude(AD._CPP_file, "oops/compressedOops.hpp");
-  AD.addInclude(AD._CPP_file, "oops/markOop.hpp");
+  AD.addInclude(AD._CPP_file, "oops/markWord.hpp");
   AD.addInclude(AD._CPP_file, "oops/method.hpp");
   AD.addInclude(AD._CPP_file, "oops/oop.inline.hpp");
   AD.addInclude(AD._CPP_file, "opto/cfgnode.hpp");
--- a/src/hotspot/share/asm/codeBuffer.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/asm/codeBuffer.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1050,10 +1050,11 @@
   friend class CodeStrings;
   const char * _string;
   CodeString*  _next;
+  CodeString*  _prev;
   intptr_t     _offset;
 
   ~CodeString() {
-    assert(_next == NULL, "wrong interface for freeing list");
+    assert(_next == NULL && _prev == NULL, "wrong interface for freeing list");
     os::free((void*)_string);
   }
 
@@ -1061,7 +1062,7 @@
 
  public:
   CodeString(const char * string, intptr_t offset = -1)
-    : _next(NULL), _offset(offset) {
+    : _next(NULL), _prev(NULL), _offset(offset) {
     _string = os::strdup(string, mtCode);
   }
 
@@ -1069,7 +1070,12 @@
   intptr_t     offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset;  }
   CodeString* next()    const { return _next; }
 
-  void set_next(CodeString* next) { _next = next; }
+  void set_next(CodeString* next) {
+    _next = next;
+    if (next != NULL) {
+      next->_prev = this;
+    }
+  }
 
   CodeString* first_comment() {
     if (is_comment()) {
@@ -1097,12 +1103,9 @@
 
 // Convenience for add_comment.
 CodeString* CodeStrings::find_last(intptr_t offset) const {
-  CodeString* a = find(offset);
-  if (a != NULL) {
-    CodeString* c = NULL;
-    while (((c = a->next_comment()) != NULL) && (c->offset() == offset)) {
-      a = c;
-    }
+  CodeString* a = _strings_last;
+  while (a != NULL && !a->is_comment() && a->offset() > offset) {
+    a = a->_prev;
   }
   return a;
 }
@@ -1121,12 +1124,16 @@
     c->set_next(_strings);
     _strings = c;
   }
+  if (c->next() == NULL) {
+    _strings_last = c;
+  }
 }
 
 void CodeStrings::assign(CodeStrings& other) {
   other.check_valid();
   assert(is_null(), "Cannot assign onto non-empty CodeStrings");
   _strings = other._strings;
+  _strings_last = other._strings_last;
 #ifdef ASSERT
   _defunct = false;
 #endif
@@ -1142,8 +1149,11 @@
   assert(is_null(), "Cannot copy onto non-empty CodeStrings");
   CodeString* n = other._strings;
   CodeString** ps = &_strings;
+  CodeString* prev = NULL;
   while (n != NULL) {
     *ps = new CodeString(n->string(),n->offset());
+    (*ps)->_prev = prev;
+    prev = *ps;
     ps = &((*ps)->_next);
     n = n->next();
   }
@@ -1180,6 +1190,10 @@
     // unlink the node from the list saving a pointer to the next
     CodeString* p = n->next();
     n->set_next(NULL);
+    if (p != NULL) {
+      assert(p->_prev == n, "missing prev link");
+      p->_prev = NULL;
+    }
     delete n;
     n = p;
   }
@@ -1190,6 +1204,9 @@
   check_valid();
   CodeString* s = new CodeString(string);
   s->set_next(_strings);
+  if (_strings == NULL) {
+    _strings_last = s;
+  }
   _strings = s;
   assert(s->string() != NULL, "should have a string");
   return s->string();
--- a/src/hotspot/share/asm/codeBuffer.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/asm/codeBuffer.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -249,6 +249,7 @@
 private:
 #ifndef PRODUCT
   CodeString* _strings;
+  CodeString* _strings_last;
 #ifdef ASSERT
   // Becomes true after copy-out, forbids further use.
   bool _defunct; // Zero bit pattern is "valid", see memset call in decode_env::decode_env
@@ -262,6 +263,7 @@
   void set_null_and_invalidate() {
 #ifndef PRODUCT
     _strings = NULL;
+    _strings_last = NULL;
 #ifdef ASSERT
     _defunct = true;
 #endif
@@ -272,6 +274,7 @@
   CodeStrings() {
 #ifndef PRODUCT
     _strings = NULL;
+    _strings_last = NULL;
 #ifdef ASSERT
     _defunct = false;
 #endif
--- a/src/hotspot/share/c1/c1_Runtime1.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/c1/c1_Runtime1.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -705,19 +705,11 @@
     Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
   }
   Handle h_obj(thread, obj);
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, lock->lock(), true, CHECK);
-  } else {
-    if (UseFastLocking) {
-      // When using fast locking, the compiled code has already tried the fast case
-      assert(obj == lock->obj(), "must match");
-      ObjectSynchronizer::slow_enter(h_obj, lock->lock(), THREAD);
-    } else {
-      lock->set_obj(obj);
-      ObjectSynchronizer::fast_enter(h_obj, lock->lock(), false, THREAD);
-    }
+  if (!UseFastLocking) {
+    lock->set_obj(obj);
   }
+  assert(obj == lock->obj(), "must match");
+  ObjectSynchronizer::enter(h_obj, lock->lock(), THREAD);
 JRT_END
 
 
@@ -730,12 +722,7 @@
 
   oop obj = lock->obj();
   assert(oopDesc::is_oop(obj), "must be NULL or an object");
-  if (UseFastLocking) {
-    // When using fast locking, the compiled code has already tried the fast case
-    ObjectSynchronizer::slow_exit(obj, lock->lock(), THREAD);
-  } else {
-    ObjectSynchronizer::fast_exit(obj, lock->lock(), THREAD);
-  }
+  ObjectSynchronizer::exit(obj, lock->lock(), THREAD);
 JRT_END
 
 // Cf. OptoRuntime::deoptimize_caller_frame
--- a/src/hotspot/share/ci/ciMethodData.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/ci/ciMethodData.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -258,12 +258,14 @@
 void ciReceiverTypeData::translate_receiver_data_from(const ProfileData* data) {
   for (uint row = 0; row < row_limit(); row++) {
     Klass* k = data->as_ReceiverTypeData()->receiver(row);
-    if (k != NULL && k->is_loader_alive()) {
-      ciKlass* klass = CURRENT_ENV->get_klass(k);
-      set_receiver(row, klass);
-    } else {
-      // With concurrent class unloading, the MDO could have stale metadata; override it
-      clear_row(row);
+    if (k != NULL) {
+      if (k->is_loader_alive()) {
+        ciKlass* klass = CURRENT_ENV->get_klass(k);
+        set_receiver(row, klass);
+      } else {
+        // With concurrent class unloading, the MDO could have stale metadata; override it
+        clear_row(row);
+      }
     }
   }
 }
--- a/src/hotspot/share/classfile/altHashing.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/altHashing.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,7 +26,7 @@
 #include "classfile/altHashing.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/thread.hpp"
 
--- a/src/hotspot/share/classfile/classLoader.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/classLoader.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -69,12 +69,10 @@
 #include "runtime/vm_version.hpp"
 #include "services/management.hpp"
 #include "services/threadService.hpp"
+#include "utilities/classpathStream.hpp"
 #include "utilities/events.hpp"
 #include "utilities/hashtable.inline.hpp"
 #include "utilities/macros.hpp"
-#if INCLUDE_CDS
-#include "classfile/sharedPathsMiscInfo.hpp"
-#endif
 
 // Entry points in zip.dll for loading zip/jar file entries
 
@@ -146,7 +144,6 @@
 ClassPathEntry* ClassLoader::_last_app_classpath_entry = NULL;
 ClassPathEntry* ClassLoader::_module_path_entries = NULL;
 ClassPathEntry* ClassLoader::_last_module_path_entry = NULL;
-SharedPathsMiscInfo* ClassLoader::_shared_paths_misc_info = NULL;
 #endif
 
 // helper routines
@@ -249,13 +246,12 @@
   return pkgEntryTable->lookup_only(pkg_symbol);
 }
 
-ClassPathDirEntry::ClassPathDirEntry(const char* dir) : ClassPathEntry() {
-  char* copy = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
-  strcpy(copy, dir);
-  _dir = copy;
+const char* ClassPathEntry::copy_path(const char* path) {
+  char* copy = NEW_C_HEAP_ARRAY(char, strlen(path)+1, mtClass);
+  strcpy(copy, path);
+  return copy;
 }
 
-
 ClassFileStream* ClassPathDirEntry::open_stream(const char* name, TRAPS) {
   // construct full path name
   assert((_dir != NULL) && (name != NULL), "sanity");
@@ -295,9 +291,7 @@
 ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name,
                                      bool is_boot_append, bool from_class_path_attr) : ClassPathEntry() {
   _zip = zip;
-  char *copy = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass);
-  strcpy(copy, zip_name);
-  _zip_name = copy;
+  _zip_name = copy_path(zip_name);
   _from_class_path_attr = from_class_path_attr;
 }
 
@@ -382,8 +376,7 @@
   assert(_singleton == NULL, "VM supports only one jimage");
   DEBUG_ONLY(_singleton = this);
   size_t len = strlen(name) + 1;
-  _name = NEW_C_HEAP_ARRAY(const char, len, mtClass);
-  strncpy((char *)_name, name, len);
+  _name = copy_path(name);
 }
 
 ClassPathImageEntry::~ClassPathImageEntry() {
@@ -536,54 +529,19 @@
   } else {
     trace_class_path("bootstrap loader class path=", sys_class_path);
   }
-#if INCLUDE_CDS
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
-    _shared_paths_misc_info->add_boot_classpath(sys_class_path);
-  }
-#endif
   setup_boot_search_path(sys_class_path);
 }
 
 #if INCLUDE_CDS
-int ClassLoader::get_shared_paths_misc_info_size() {
-  return _shared_paths_misc_info->get_used_bytes();
-}
-
-void* ClassLoader::get_shared_paths_misc_info() {
-  return _shared_paths_misc_info->buffer();
-}
-
-bool ClassLoader::check_shared_paths_misc_info(void *buf, int size, bool is_static) {
-  SharedPathsMiscInfo* checker = new SharedPathsMiscInfo((char*)buf, size);
-  bool result = checker->check(is_static);
-  delete checker;
-  return result;
-}
-
 void ClassLoader::setup_app_search_path(const char *class_path) {
-
   assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity");
 
-  Thread* THREAD = Thread::current();
-  int len = (int)strlen(class_path);
-  int end = 0;
+  ResourceMark rm;
+  ClasspathStream cp_stream(class_path);
 
-  // Iterate over class path entries
-  for (int start = 0; start < len; start = end) {
-    while (class_path[end] && class_path[end] != os::path_separator()[0]) {
-      end++;
-    }
-    EXCEPTION_MARK;
-    ResourceMark rm(THREAD);
-    char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
-    strncpy(path, &class_path[start], end - start);
-    path[end - start] = '\0';
-
+  while (cp_stream.has_next()) {
+    const char* path = cp_stream.get_next();
     update_class_path_entry_list(path, false, false, false);
-
-    while (class_path[end] == os::path_separator()[0]) {
-      end++;
-    }
   }
 }
 
@@ -643,7 +601,6 @@
   GrowableArray<ModulePatchPath*>* patch_mod_args = Arguments::get_patch_mod_prefix();
   int num_of_entries = patch_mod_args->length();
 
-
   // Set up the boot loader's _patch_mod_entries list
   _patch_mod_entries = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleClassPathList*>(num_of_entries, true);
 
@@ -654,19 +611,11 @@
     ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym);
 
     char* class_path = (patch_mod_args->at(i))->path_string();
-    int len = (int)strlen(class_path);
-    int end = 0;
-    // Iterate over the module's class path entries
-    for (int start = 0; start < len; start = end) {
-      while (class_path[end] && class_path[end] != os::path_separator()[0]) {
-        end++;
-      }
-      EXCEPTION_MARK;
-      ResourceMark rm(THREAD);
-      char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
-      strncpy(path, &class_path[start], end - start);
-      path[end - start] = '\0';
+    ResourceMark rm(THREAD);
+    ClasspathStream cp_stream(class_path);
 
+    while (cp_stream.has_next()) {
+      const char* path = cp_stream.get_next();
       struct stat st;
       if (os::stat(path, &st) == 0) {
         // File or directory found
@@ -676,10 +625,6 @@
           module_cpl->add_to_list(new_entry);
         }
       }
-
-      while (class_path[end] == os::path_separator()[0]) {
-        end++;
-      }
     }
 
     // Record the module into the list of --patch-module entries only if
@@ -707,8 +652,9 @@
 
 // Set up the _jrt_entry if present and boot append path
 void ClassLoader::setup_boot_search_path(const char *class_path) {
-  int len = (int)strlen(class_path);
-  int end = 0;
+  EXCEPTION_MARK;
+  ResourceMark rm(THREAD);
+  ClasspathStream cp_stream(class_path);
   bool set_base_piece = true;
 
 #if INCLUDE_CDS
@@ -719,16 +665,8 @@
   }
 #endif
 
-  // Iterate over class path entries
-  for (int start = 0; start < len; start = end) {
-    while (class_path[end] && class_path[end] != os::path_separator()[0]) {
-      end++;
-    }
-    EXCEPTION_MARK;
-    ResourceMark rm(THREAD);
-    char* path = NEW_RESOURCE_ARRAY(char, end - start + 1);
-    strncpy(path, &class_path[start], end - start);
-    path[end - start] = '\0';
+  while (cp_stream.has_next()) {
+    const char* path = cp_stream.get_next();
 
     if (set_base_piece) {
       // The first time through the bootstrap_search setup, it must be determined
@@ -758,10 +696,6 @@
       // which is set by os::set_boot_path(), is considered an appended entry.
       update_class_path_entry_list(path, false, true, false);
     }
-
-    while (class_path[end] == os::path_separator()[0]) {
-      end++;
-    }
   }
 }
 
@@ -981,11 +915,6 @@
     }
     return true;
   } else {
-#if INCLUDE_CDS
-    if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
-      _shared_paths_misc_info->add_nonexist_path(path);
-    }
-#endif
     return false;
   }
 }
@@ -1605,12 +1534,6 @@
   load_zip_library();
   // lookup jimage library entry points
   load_jimage_library();
-#if INCLUDE_CDS
-  // initialize search path
-  if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
-    _shared_paths_misc_info = new SharedPathsMiscInfo();
-  }
-#endif
   setup_bootstrap_search_path();
 }
 
@@ -1618,7 +1541,6 @@
 void ClassLoader::initialize_shared_path() {
   if (DumpSharedSpaces || DynamicDumpSharedSpaces) {
     ClassLoaderExt::setup_search_paths();
-    _shared_paths_misc_info->write_jint(0); // see comments in SharedPathsMiscInfo::check()
   }
 }
 
--- a/src/hotspot/share/classfile/classLoader.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/classLoader.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -47,17 +47,19 @@
 class ClassPathEntry : public CHeapObj<mtClass> {
 private:
   ClassPathEntry* volatile _next;
+protected:
+  const char* copy_path(const char*path);
 public:
   ClassPathEntry* next() const;
   virtual ~ClassPathEntry() {}
   void set_next(ClassPathEntry* next);
-  virtual bool is_modules_image() const = 0;
-  virtual bool is_jar_file() const = 0;
+  virtual bool is_modules_image() const { return false; }
+  virtual bool is_jar_file() const { return false; }
   // Is this entry created from the "Class-path" attribute from a JAR Manifest?
-  virtual bool from_class_path_attr() const = 0;
+  virtual bool from_class_path_attr() const { return false; }
   virtual const char* name() const = 0;
-  virtual JImageFile* jimage() const = 0;
-  virtual void close_jimage() = 0;
+  virtual JImageFile* jimage() const { return NULL; }
+  virtual void close_jimage() {}
   // Constructor
   ClassPathEntry() : _next(NULL) {}
   // Attempt to locate file_name through this class path entry.
@@ -73,18 +75,14 @@
  private:
   const char* _dir;           // Name of directory
  public:
-  bool is_modules_image() const { return false; }
-  bool is_jar_file() const { return false;  }
-  bool from_class_path_attr() const { return false; }
   const char* name() const { return _dir; }
-  JImageFile* jimage() const { return NULL; }
-  void close_jimage() {}
-  ClassPathDirEntry(const char* dir);
+  ClassPathDirEntry(const char* dir) {
+    _dir = copy_path(dir);
+  }
   virtual ~ClassPathDirEntry() {}
   ClassFileStream* open_stream(const char* name, TRAPS);
 };
 
-
 // Type definitions for zip file and zip file entry
 typedef void* jzfile;
 typedef struct {
@@ -104,12 +102,9 @@
   const char*   _zip_name;   // Name of zip archive
   bool _from_class_path_attr; // From the "Class-path" attribute of a jar file
  public:
-  bool is_modules_image() const { return false; }
   bool is_jar_file() const { return true;  }
   bool from_class_path_attr() const { return _from_class_path_attr; }
   const char* name() const { return _zip_name; }
-  JImageFile* jimage() const { return NULL; }
-  void close_jimage() {}
   ClassPathZipEntry(jzfile* zip, const char* zip_name, bool is_boot_append, bool from_class_path_attr);
   virtual ~ClassPathZipEntry();
   u1* open_entry(const char* name, jint* filesize, bool nul_terminate, TRAPS);
@@ -126,8 +121,6 @@
   DEBUG_ONLY(static ClassPathImageEntry* _singleton;)
 public:
   bool is_modules_image() const;
-  bool is_jar_file() const { return false; }
-  bool from_class_path_attr() const { return false; }
   bool is_open() const { return _jimage != NULL; }
   const char* name() const { return _name == NULL ? "" : _name; }
   JImageFile* jimage() const { return _jimage; }
@@ -156,8 +149,6 @@
   void add_to_list(ClassPathEntry* new_entry);
 };
 
-class SharedPathsMiscInfo;
-
 class ClassLoader: AllStatic {
  public:
   enum ClassLoaderType {
@@ -230,8 +221,6 @@
   static ClassPathEntry* _last_append_entry;
 
   // Info used by CDS
-  CDS_ONLY(static SharedPathsMiscInfo * _shared_paths_misc_info;)
-
   CDS_ONLY(static ClassPathEntry* _app_classpath_entries;)
   CDS_ONLY(static ClassPathEntry* _last_app_classpath_entry;)
   CDS_ONLY(static ClassPathEntry* _module_path_entries;)
@@ -416,10 +405,6 @@
     }
     return num_entries;
   }
-  static void  finalize_shared_paths_misc_info();
-  static int   get_shared_paths_misc_info_size();
-  static void* get_shared_paths_misc_info();
-  static bool  check_shared_paths_misc_info(void* info, int size, bool is_static);
   static void  exit_with_path_failure(const char* error, const char* message);
   static char* skip_uri_protocol(char* source);
   static void  record_result(InstanceKlass* ik, const ClassFileStream* stream, TRAPS);
--- a/src/hotspot/share/classfile/classLoaderExt.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -30,7 +30,6 @@
 #include "classfile/classLoaderData.inline.hpp"
 #include "classfile/klassFactory.hpp"
 #include "classfile/modules.hpp"
-#include "classfile/sharedPathsMiscInfo.hpp"
 #include "classfile/systemDictionaryShared.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "memory/allocation.inline.hpp"
@@ -74,7 +73,6 @@
     trace_class_path("app loader class path (skipped)=", app_class_path);
   } else {
     trace_class_path("app loader class path=", app_class_path);
-    shared_paths_misc_info()->add_app_classpath(app_class_path);
     ClassLoader::setup_app_search_path(app_class_path);
   }
 }
@@ -212,8 +210,12 @@
         char* libname = NEW_RESOURCE_ARRAY(char, libname_len + 1);
         int n = os::snprintf(libname, libname_len + 1, "%.*s%s", dir_len, dir_name, file_start);
         assert((size_t)n == libname_len, "Unexpected number of characters in string");
-        trace_class_path("library = ", libname);
-        ClassLoader::update_class_path_entry_list(libname, true, false, true /* from_class_path_attr */);
+        if (ClassLoader::update_class_path_entry_list(libname, true, false, true /* from_class_path_attr */)) {
+          trace_class_path("library = ", libname);
+        } else {
+          trace_class_path("library (non-existent) = ", libname);
+          FileMapInfo::record_non_existent_class_path_entry(libname);
+        }
       }
 
       file_start = file_end;
@@ -222,7 +224,6 @@
 }
 
 void ClassLoaderExt::setup_search_paths() {
-  shared_paths_misc_info()->record_app_offset();
   ClassLoaderExt::setup_app_search_path();
 }
 
@@ -248,12 +249,6 @@
   result->set_class_loader_type(classloader_type);
 }
 
-void ClassLoaderExt::finalize_shared_paths_misc_info() {
-  if (!_has_app_classes) {
-    shared_paths_misc_info()->pop_app();
-  }
-}
-
 // Load the class of the given name from the location given by path. The path is specified by
 // the "source:" in the class list file (see classListParser.cpp), and can be a directory or
 // a JAR file.
--- a/src/hotspot/share/classfile/classLoaderExt.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/classLoaderExt.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -47,9 +47,6 @@
   static char* get_class_path_attr(const char* jar_path, char* manifest, jint manifest_size);
   static void setup_app_search_path(); // Only when -Xshare:dump
   static void process_module_table(ModuleEntryTable* met, TRAPS);
-  static SharedPathsMiscInfo* shared_paths_misc_info() {
-    return (SharedPathsMiscInfo*)_shared_paths_misc_info;
-  }
   // index of first app JAR in shared classpath entry table
   static jshort _app_class_paths_start_index;
   // index of first modular JAR in shared modulepath entry table
@@ -84,8 +81,6 @@
     return read_manifest(entry, manifest_size, false, THREAD);
   }
 
-  static void finalize_shared_paths_misc_info();
-
   static jshort app_class_paths_start_index() { return _app_class_paths_start_index; }
 
   static jshort app_module_paths_start_index() { return _app_module_paths_start_index; }
--- a/src/hotspot/share/classfile/javaClasses.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -64,6 +64,7 @@
 #include "runtime/safepointVerifiers.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/vframe.inline.hpp"
+#include "runtime/vm_version.hpp"
 #include "utilities/align.hpp"
 #include "utilities/preserveException.hpp"
 #include "utilities/utf8.hpp"
@@ -4034,6 +4035,7 @@
   int _page_size;
   bool _big_endian;
   bool _use_unaligned_access;
+  int _data_cache_line_flush_size;
 public:
   UnsafeConstantsFixup() {
     // round up values for all static final fields
@@ -4041,6 +4043,7 @@
     _page_size = os::vm_page_size();
     _big_endian = LITTLE_ENDIAN_ONLY(false) BIG_ENDIAN_ONLY(true);
     _use_unaligned_access = UseUnalignedAccesses;
+    _data_cache_line_flush_size = (int)VM_Version::data_cache_line_flush_size();
   }
 
   void do_field(fieldDescriptor* fd) {
@@ -4057,6 +4060,8 @@
       mirror->bool_field_put(fd->offset(), _big_endian);
     } else if (fd->name() == vmSymbols::use_unaligned_access_name()) {
       mirror->bool_field_put(fd->offset(), _use_unaligned_access);
+    } else if (fd->name() == vmSymbols::data_cache_line_flush_size_name()) {
+      mirror->int_field_put(fd->offset(), _data_cache_line_flush_size);
     } else {
       assert(false, "unexpected UnsafeConstants field");
     }
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,178 +0,0 @@
-/*
- * 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.
- *
- * 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 "classfile/classLoader.hpp"
-#include "classfile/sharedPathsMiscInfo.hpp"
-#include "logging/log.hpp"
-#include "logging/logStream.hpp"
-#include "memory/allocation.inline.hpp"
-#include "memory/filemap.hpp"
-#include "memory/metaspaceShared.hpp"
-#include "memory/resourceArea.hpp"
-#include "runtime/arguments.hpp"
-#include "runtime/os.inline.hpp"
-#include "utilities/ostream.hpp"
-
-SharedPathsMiscInfo::SharedPathsMiscInfo() {
-  _app_offset = 0;
-  _buf_size = INITIAL_BUF_SIZE;
-  _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
-  _allocated = true;
-}
-
-SharedPathsMiscInfo::~SharedPathsMiscInfo() {
-  if (_allocated) {
-    FREE_C_HEAP_ARRAY(char, _buf_start);
-  }
-}
-
-void SharedPathsMiscInfo::add_path(const char* path, int type) {
-  log_info(class, path)("type=%s ", type_name(type));
-  ClassLoader::trace_class_path("add misc shared path ", path);
-  write(path, strlen(path) + 1);
-  write_jint(jint(type));
-}
-
-void SharedPathsMiscInfo::ensure_size(size_t needed_bytes) {
-  assert(_allocated, "cannot modify buffer during validation.");
-  int used = get_used_bytes();
-  int target = used + int(needed_bytes);
-  if (target > _buf_size) {
-    _buf_size = _buf_size * 2 + (int)needed_bytes;
-    _buf_start = REALLOC_C_HEAP_ARRAY(char, _buf_start, _buf_size, mtClass);
-    _cur_ptr = _buf_start + used;
-    _end_ptr = _buf_start + _buf_size;
-  }
-}
-
-void SharedPathsMiscInfo::write(const void* ptr, size_t size) {
-  ensure_size(size);
-  memcpy(_cur_ptr, ptr, size);
-  _cur_ptr += size;
-}
-
-bool SharedPathsMiscInfo::read(void* ptr, size_t size) {
-  if (_cur_ptr + size <= _end_ptr) {
-    memcpy(ptr, _cur_ptr, size);
-    _cur_ptr += size;
-    return true;
-  }
-  return false;
-}
-
-bool SharedPathsMiscInfo::fail(const char* msg, const char* name) {
-  ClassLoader::trace_class_path(msg, name);
-  MetaspaceShared::set_archive_loading_failed();
-  return false;
-}
-
-void SharedPathsMiscInfo::print_path(outputStream* out, int type, const char* path) {
-  switch (type) {
-  case BOOT_PATH:
-    out->print("Expecting BOOT path=%s", path);
-    break;
-  case NON_EXIST:
-    out->print("Expecting that %s does not exist", path);
-    break;
-  case APP_PATH:
-    ClassLoader::trace_class_path("Expecting -Djava.class.path=", path);
-    break;
-  default:
-    ShouldNotReachHere();
-  }
-}
-
-bool SharedPathsMiscInfo::check(bool is_static) {
-  // The whole buffer must be 0 terminated so that we can use strlen and strcmp
-  // without fear.
-  _end_ptr -= sizeof(jint);
-  if (_cur_ptr >= _end_ptr) {
-    return fail("Truncated archive file header");
-  }
-  if (*_end_ptr != 0) {
-    return fail("Corrupted archive file header");
-  }
-
-  jshort cur_index = 0;
-  FileMapHeader* header = is_static ? FileMapInfo::current_info()->header() :
-                                      FileMapInfo::dynamic_info()->header();
-  jshort max_cp_index = header->max_used_path_index();
-  jshort module_paths_start_index = header->app_module_paths_start_index();
-  while (_cur_ptr < _end_ptr) {
-    jint type;
-    const char* path = _cur_ptr;
-    _cur_ptr += strlen(path) + 1;
-
-    if (!read_jint(&type)) {
-      return fail("Corrupted archive file header");
-    }
-    LogTarget(Info, class, path) lt;
-    if (lt.is_enabled()) {
-      lt.print("type=%s ", type_name(type));
-      LogStream ls(lt);
-      print_path(&ls, type, path);
-      ls.cr();
-    }
-    // skip checking the class path(s) which was not referenced during CDS dump
-    if ((cur_index <= max_cp_index) || (cur_index >= module_paths_start_index)) {
-      if (!check(type, path, is_static)) {
-        if (!PrintSharedArchiveAndExit) {
-          return false;
-        }
-      } else {
-        ClassLoader::trace_class_path("ok");
-      }
-    } else {
-      ClassLoader::trace_class_path("skipped check");
-    }
-    cur_index++;
-  }
-
-  return true;
-}
-
-bool SharedPathsMiscInfo::check(jint type, const char* path, bool is_static) {
-  assert(UseSharedSpaces, "runtime only");
-  switch (type) {
-  case BOOT_PATH:
-    break;
-  case NON_EXIST:
-    {
-      struct stat st;
-      if (os::stat(path, &st) == 0) {
-        // The file actually exists
-        // But we want it to not exist -> fail
-        return fail("File must not exist");
-      }
-    }
-    break;
-  case APP_PATH:
-    break;
-  default:
-    return fail("Corrupted archive file header");
-  }
-
-  return true;
-}
--- a/src/hotspot/share/classfile/sharedPathsMiscInfo.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-/*
- * 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.
- *
- * 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_CLASSFILE_SHAREDPATHSMISCINFO_HPP
-#define SHARE_CLASSFILE_SHAREDPATHSMISCINFO_HPP
-
-#include "classfile/classLoader.hpp"
-#include "runtime/os.hpp"
-
-class outputStream;
-// During dumping time, when processing class paths, we build up the dump-time
-// classpath. The JAR files that exist are stored in the list ClassLoader::_first_append_entry.
-// However, we need to store other "misc" information for run-time checking, such as
-//
-// + The values of Arguments::get_sysclasspath() used during dumping.
-//
-// + The class path elements specified during dumping but did not exist --
-//   these elements must also be specified at run time, and they also must not
-//   exist at run time.
-//
-// These misc items are stored in a linear buffer in SharedPathsMiscInfo.
-// The storage format is stream oriented to minimize its size.
-//
-// When writing the information to the archive file, SharedPathsMiscInfo is stored in
-// the archive file header. At run-time, this information is used only during initialization
-// (accessed using read() instead of mmap()), and is deallocated afterwards to save space.
-//
-// The SharedPathsMiscInfo class is used for both creating the the information (during
-// dumping time) and validation (at run time). Different constructors are used in the
-// two situations. See below.
-
-class SharedPathsMiscInfo : public CHeapObj<mtClass> {
-private:
-  int   _app_offset;
-protected:
-  char* _buf_start;
-  char* _cur_ptr;
-  char* _end_ptr;
-  int   _buf_size;
-  bool  _allocated;   // was _buf_start allocated by me?
-  void ensure_size(size_t needed_bytes);
-  void add_path(const char* path, int type);
-
-  void write(const void* ptr, size_t size);
-  bool read(void* ptr, size_t size);
-
-protected:
-  static bool fail(const char* msg, const char* name = NULL);
-  bool check(jint type, const char* path, bool is_static);
-
-public:
-  enum {
-    INITIAL_BUF_SIZE = 128
-  };
-  // This constructor is used when creating the misc information (during dump)
-  SharedPathsMiscInfo();
-  // This constructor is used when validating the misc info (during run time)
-  SharedPathsMiscInfo(char *buff, int size) {
-    _app_offset = 0;
-    _cur_ptr = _buf_start = buff;
-    _end_ptr = _buf_start + size;
-    _buf_size = size;
-    _allocated = false;
-  }
-  ~SharedPathsMiscInfo();
-
-  int get_used_bytes() {
-    return _cur_ptr - _buf_start;
-  }
-  void* buffer() {
-    return _buf_start;
-  }
-
-  // writing --
-
-  // The path must not exist at run-time
-  void add_nonexist_path(const char* path) {
-    add_path(path, NON_EXIST);
-  }
-
-  // The path must exist, and must contain exactly <num_entries> files/dirs
-  void add_boot_classpath(const char* path) {
-    add_path(path, BOOT_PATH);
-  }
-
-  void add_app_classpath(const char* path) {
-    add_path(path, APP_PATH);
-  }
-  void record_app_offset() {
-    _app_offset = get_used_bytes();
-  }
-  void pop_app() {
-    _cur_ptr = _buf_start + _app_offset;
-    write_jint(0);
-  }
-
-  int write_jint(jint num) {
-    write(&num, sizeof(num));
-    return 0;
-  }
-  void write_time(time_t t) {
-    write(&t, sizeof(t));
-  }
-  void write_long(long l) {
-    write(&l, sizeof(l));
-  }
-
-  bool dump_to_file(int fd) {
-    int n = get_used_bytes();
-    return (os::write(fd, _buf_start, n) == (size_t)n);
-  }
-
-  // reading --
-
-private:
-  enum {
-    BOOT_PATH      = 1,
-    APP_PATH       = 2,
-    NON_EXIST      = 3
-  };
-
-  const char* type_name(int type) {
-    switch (type) {
-    case BOOT_PATH:   return "BOOT";
-    case APP_PATH:    return "APP";
-    case NON_EXIST:   return "NON_EXIST";
-    default:          ShouldNotReachHere(); return "?";
-    }
-  }
-
-  void print_path(outputStream* os, int type, const char* path);
-
-  bool read_jint(jint *ptr) {
-    return read(ptr, sizeof(jint));
-  }
-  bool read_long(long *ptr) {
-    return read(ptr, sizeof(long));
-  }
-  bool read_time(time_t *ptr) {
-    return read(ptr, sizeof(time_t));
-  }
-
-public:
-  bool check(bool is_static);
-};
-
-#endif // SHARE_CLASSFILE_SHAREDPATHSMISCINFO_HPP
--- a/src/hotspot/share/classfile/stringTable.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/stringTable.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -30,6 +30,7 @@
 #include "classfile/systemDictionary.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/oopStorage.inline.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.inline.hpp"
@@ -86,7 +87,6 @@
 volatile bool StringTable::_needs_rehashing = false;
 
 volatile size_t StringTable::_uncleaned_items_count = 0;
-OopStorage* StringTable::_weak_handles = NULL;
 
 static size_t _current_size = 0;
 static volatile size_t _items_count = 0;
@@ -206,9 +206,6 @@
 }
 
 void StringTable::create_table() {
-  _weak_handles = new OopStorage("StringTable weak",
-                                 StringTableWeakAlloc_lock,
-                                 StringTableWeakActive_lock);
   size_t start_size_log_2 = ceil_log2(StringTableSize);
   _current_size = ((size_t)1) << start_size_log_2;
   log_trace(stringtable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
@@ -388,7 +385,7 @@
 
 void StringTable::oops_do(OopClosure* f) {
   assert(f != NULL, "No closure");
-  _weak_handles->oops_do(f);
+  OopStorageSet::string_table_weak()->oops_do(f);
 }
 
 // Concurrent work
--- a/src/hotspot/share/classfile/stringTable.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/stringTable.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,7 +25,6 @@
 #ifndef SHARE_CLASSFILE_STRINGTABLE_HPP
 #define SHARE_CLASSFILE_STRINGTABLE_HPP
 
-#include "gc/shared/oopStorage.hpp"
 #include "memory/allocation.hpp"
 #include "memory/padded.hpp"
 #include "oops/oop.hpp"
@@ -33,6 +32,7 @@
 #include "utilities/tableStatistics.hpp"
 
 class CompactHashtableWriter;
+class JavaThread;
 class SerializeClosure;
 
 class StringTable;
@@ -51,8 +51,6 @@
   // Set if one bucket is out of balance due to hash algorithm deficiency
   static volatile bool _needs_rehashing;
 
-  static OopStorage* _weak_handles;
-
   static void grow(JavaThread* jt);
   static void clean_dead_entries(JavaThread* jt);
 
@@ -78,8 +76,6 @@
   static size_t table_size();
   static TableStatistics get_table_statistics();
 
-  static OopStorage* weak_storage() { return _weak_handles; }
-
   static void create_table();
 
   static void do_concurrent_work(JavaThread* jt);
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -47,6 +47,7 @@
 #include "compiler/compileBroker.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/oopStorage.inline.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "interpreter/bytecodeStream.hpp"
 #include "interpreter/interpreter.hpp"
 #include "jfr/jfrEvents.hpp"
@@ -114,10 +115,6 @@
 
 const int defaultProtectionDomainCacheSize = 1009;
 
-OopStorage* SystemDictionary::_vm_global_oop_storage = NULL;
-OopStorage* SystemDictionary::_vm_weak_oop_storage = NULL;
-
-
 // ----------------------------------------------------------------------------
 // Java-level SystemLoader and PlatformLoader
 
@@ -1855,7 +1852,7 @@
   invoke_method_table()->oops_do(f);
 
   if (include_handles) {
-    vm_global_oop_storage()->oops_do(f);
+    OopStorageSet::vm_global()->oops_do(f);
   }
 }
 
@@ -2896,25 +2893,3 @@
     return 0;
   }
 }
-
-void SystemDictionary::initialize_oop_storage() {
-  _vm_global_oop_storage =
-    new OopStorage("VM Global Oop Handles",
-                   VMGlobalAlloc_lock,
-                   VMGlobalActive_lock);
-
-  _vm_weak_oop_storage =
-    new OopStorage("VM Weak Oop Handles",
-                   VMWeakAlloc_lock,
-                   VMWeakActive_lock);
-}
-
-OopStorage* SystemDictionary::vm_global_oop_storage() {
-  assert(_vm_global_oop_storage != NULL, "Uninitialized");
-  return _vm_global_oop_storage;
-}
-
-OopStorage* SystemDictionary::vm_weak_oop_storage() {
-  assert(_vm_weak_oop_storage != NULL, "Uninitialized");
-  return _vm_weak_oop_storage;
-}
--- a/src/hotspot/share/classfile/systemDictionary.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/systemDictionary.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -84,7 +84,6 @@
 class ProtectionDomainCacheTable;
 class ProtectionDomainCacheEntry;
 class GCTimer;
-class OopStorage;
 
 #define WK_KLASS_ENUM_NAME(kname)    kname##_knum
 
@@ -349,7 +348,7 @@
 
   // Applies "f->do_oop" to all root oops in the system dictionary.
   // If include_handles is true (the default), then the handles in the
-  // storage object returned by vm_global_oop_storage() are included.
+  // vm_global OopStorage object are included.
   static void oops_do(OopClosure* f, bool include_handles = true);
 
   // System loader lock
@@ -565,10 +564,6 @@
   // ProtectionDomain cache
   static ProtectionDomainCacheTable*   _pd_cache_table;
 
-  // VM OopStorage objects.
-  static OopStorage*             _vm_global_oop_storage;
-  static OopStorage*             _vm_weak_oop_storage;
-
 protected:
   static void validate_protection_domain(InstanceKlass* klass,
                                          Handle class_loader,
@@ -623,10 +618,6 @@
     return !m->is_public() && m->method_holder() == SystemDictionary::Object_klass();
   }
 
-  static void initialize_oop_storage();
-  static OopStorage* vm_global_oop_storage();
-  static OopStorage* vm_weak_oop_storage();
-
 protected:
   // Setup link to hierarchy
   static void add_to_hierarchy(InstanceKlass* k, TRAPS);
--- a/src/hotspot/share/classfile/vmSymbols.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/classfile/vmSymbols.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -452,6 +452,7 @@
   template(page_size_name,                            "PAGE_SIZE")                                \
   template(big_endian_name,                           "BIG_ENDIAN")                               \
   template(use_unaligned_access_name,                 "UNALIGNED_ACCESS")                         \
+  template(data_cache_line_flush_size_name,           "DATA_CACHE_LINE_FLUSH_SIZE")               \
                                                                                                   \
   /* name symbols needed by intrinsics */                                                         \
   VM_INTRINSICS_DO(VM_INTRINSIC_IGNORE, VM_SYMBOL_IGNORE, template, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE) \
@@ -480,6 +481,7 @@
   template(long_int_signature,                        "(J)I")                                     \
   template(long_long_signature,                       "(J)J")                                     \
   template(long_double_signature,                     "(J)D")                                     \
+  template(long_void_signature,                       "(J)V")                                     \
   template(byte_signature,                            "B")                                        \
   template(char_signature,                            "C")                                        \
   template(double_signature,                          "D")                                        \
@@ -1093,6 +1095,12 @@
   do_class(jdk_internal_misc_Unsafe,               "jdk/internal/misc/Unsafe")                                          \
   do_class(sun_misc_Unsafe,                        "sun/misc/Unsafe")                                                   \
                                                                                                                         \
+  do_intrinsic(_writeback0,               jdk_internal_misc_Unsafe,     writeback0_name, long_void_signature , F_RN)             \
+   do_name(     writeback0_name,                                        "writeback0")                                            \
+  do_intrinsic(_writebackPreSync0,        jdk_internal_misc_Unsafe,     writebackPreSync0_name, void_method_signature , F_RN)    \
+   do_name(     writebackPreSync0_name,                                 "writebackPreSync0")                                     \
+  do_intrinsic(_writebackPostSync0,       jdk_internal_misc_Unsafe,    writebackPostSync0_name, void_method_signature , F_RN)    \
+   do_name(     writebackPostSync0_name,                                "writebackPostSync0")                                    \
   do_intrinsic(_allocateInstance,         jdk_internal_misc_Unsafe,     allocateInstance_name, allocateInstance_signature, F_RN) \
    do_name(     allocateInstance_name,                                  "allocateInstance")                                      \
    do_signature(allocateInstance_signature,                             "(Ljava/lang/Class;)Ljava/lang/Object;")                 \
--- a/src/hotspot/share/code/vmreg.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/code/vmreg.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,6 +26,7 @@
 #define SHARE_CODE_VMREG_HPP
 
 #include "asm/register.hpp"
+#include "runtime/globals.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
 #include "utilities/ostream.hpp"
--- a/src/hotspot/share/compiler/compileBroker.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/compiler/compileBroker.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -2674,8 +2674,8 @@
   // for the entire duration of aggregation and printing. That makes sure
   // we see a consistent picture and do not run into issues caused by
   // the CodeHeap being altered concurrently.
-  Monitor* global_lock   = allFun ? CodeCache_lock : NULL;
-  Monitor* function_lock = allFun ? NULL : CodeCache_lock;
+  Mutex* global_lock   = allFun ? CodeCache_lock : NULL;
+  Mutex* function_lock = allFun ? NULL : CodeCache_lock;
   ts_global.update(); // record starting point
   MutexLocker mu2(global_lock, Mutex::_no_safepoint_check_flag);
   if (global_lock != NULL) {
--- a/src/hotspot/share/gc/cms/allocationStats.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/cms/allocationStats.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,6 +27,7 @@
 
 #include "gc/shared/gcUtil.hpp"
 #include "logging/log.hpp"
+#include "runtime/globals.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
 
--- a/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/cms/concurrentMarkSweepGeneration.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -8008,14 +8008,14 @@
 // Single threaded
 void CMSCollector::preserve_mark_if_necessary(oop p) {
   markWord m = p->mark_raw();
-  if (m.must_be_preserved(p)) {
+  if (p->mark_must_be_preserved(m)) {
     preserve_mark_work(p, m);
   }
 }
 
 void CMSCollector::par_preserve_mark_if_necessary(oop p) {
   markWord m = p->mark_raw();
-  if (m.must_be_preserved(p)) {
+  if (p->mark_must_be_preserved(m)) {
     MutexLocker x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
     // Even though we read the mark word without holding
     // the lock, we are assured that it will not change
--- a/src/hotspot/share/gc/cms/freeChunk.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/cms/freeChunk.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,7 +26,7 @@
 #define SHARE_GC_CMS_FREECHUNK_HPP
 
 #include "memory/memRegion.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/orderAccess.hpp"
 #include "utilities/debug.hpp"
--- a/src/hotspot/share/gc/cms/promotionInfo.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/cms/promotionInfo.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,8 +27,8 @@
 #include "gc/cms/promotionInfo.hpp"
 #include "gc/shared/genOopClosures.hpp"
 #include "oops/compressedOops.inline.hpp"
-#include "oops/markOop.inline.hpp"
-#include "oops/oop.hpp"
+#include "oops/markWord.inline.hpp"
+#include "oops/oop.inline.hpp"
 
 /////////////////////////////////////////////////////////////////////////
 //// PromotionInfo
--- a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,6 +26,7 @@
 #include "gc/epsilon/epsilonMemoryPool.hpp"
 #include "gc/epsilon/epsilonThreadLocalData.hpp"
 #include "gc/shared/gcArguments.hpp"
+#include "gc/shared/locationPrinter.inline.hpp"
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
@@ -305,6 +306,10 @@
   MetaspaceUtils::print_on(st);
 }
 
+bool EpsilonHeap::print_location(outputStream* st, void* addr) const {
+  return BlockLocationPrinter<EpsilonHeap>::print_location(st, addr);
+}
+
 void EpsilonHeap::print_tracing_info() const {
   print_heap_info(used());
   print_metaspace_info();
--- a/src/hotspot/share/gc/epsilon/epsilonHeap.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/epsilon/epsilonHeap.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -114,8 +114,8 @@
   virtual void unpin_object(JavaThread* thread, oop obj) { }
 
   // No support for block parsing.
-  virtual HeapWord* block_start(const void* addr) const { return NULL;  }
-  virtual bool block_is_obj(const HeapWord* addr) const { return false; }
+  HeapWord* block_start(const void* addr) const { return NULL;  }
+  bool block_is_obj(const HeapWord* addr) const { return false; }
 
   // No GC threads
   virtual void print_gc_threads_on(outputStream* st) const {}
@@ -138,6 +138,7 @@
 
   virtual void print_on(outputStream* st) const;
   virtual void print_tracing_info() const;
+  virtual bool print_location(outputStream* st, void* addr) const;
 
 private:
   void print_heap_info(size_t used) const;
--- a/src/hotspot/share/gc/g1/g1Analytics.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1Analytics.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/g1/g1Analytics.hpp"
 #include "gc/g1/g1Predictions.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/os.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/numberSeq.hpp"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1BufferNodeList.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,39 @@
+/*
+ * 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 "gc/g1/g1BufferNodeList.hpp"
+#include "utilities/debug.hpp"
+
+G1BufferNodeList::G1BufferNodeList() :
+  _head(NULL), _tail(NULL), _entry_count(0) {}
+
+G1BufferNodeList::G1BufferNodeList(BufferNode* head,
+                                   BufferNode* tail,
+                                   size_t entry_count) :
+  _head(head), _tail(tail), _entry_count(entry_count)
+{
+  assert((_head == NULL) == (_tail == NULL), "invariant");
+  assert((_head == NULL) == (_entry_count == 0), "invariant");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1BufferNodeList.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1BUFFERNODELIST_HPP
+#define SHARE_GC_G1_G1BUFFERNODELIST_HPP
+
+#include "utilities/globalDefinitions.hpp"
+
+class BufferNode;
+
+struct G1BufferNodeList {
+  BufferNode* _head;            // First node in list or NULL if empty.
+  BufferNode* _tail;            // Last node in list or NULL if empty.
+  size_t _entry_count;          // Sum of entries in nodes in list.
+
+  G1BufferNodeList();
+  G1BufferNodeList(BufferNode* head, BufferNode* tail, size_t entry_count);
+};
+
+#endif // SHARE_GC_G1_G1BUFFERNODELIST_HPP
+
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -74,6 +74,7 @@
 #include "gc/shared/gcTraceTime.inline.hpp"
 #include "gc/shared/generationSpec.hpp"
 #include "gc/shared/isGCActiveMark.hpp"
+#include "gc/shared/locationPrinter.inline.hpp"
 #include "gc/shared/oopStorageParState.hpp"
 #include "gc/shared/preservedMarks.inline.hpp"
 #include "gc/shared/suspendibleThreadSet.hpp"
@@ -2490,6 +2491,10 @@
 }
 #endif // PRODUCT
 
+bool G1CollectedHeap::print_location(outputStream* st, void* addr) const {
+  return BlockLocationPrinter<G1CollectedHeap>::print_location(st, addr);
+}
+
 G1HeapSummary G1CollectedHeap::create_g1_heap_summary() {
 
   size_t eden_used_bytes = _eden.used_bytes();
@@ -3988,8 +3993,8 @@
       g1h->clear_region_attr(r);
 
       if (r->is_young()) {
-        assert(r->young_index_in_cset() != -1 && (uint)r->young_index_in_cset() < g1h->collection_set()->young_region_length(),
-               "Young index %d is wrong for region %u of type %s with %u young regions",
+        assert(r->young_index_in_cset() != 0 && (uint)r->young_index_in_cset() <= g1h->collection_set()->young_region_length(),
+               "Young index %u is wrong for region %u of type %s with %u young regions",
                r->young_index_in_cset(),
                r->hrm_index(),
                r->get_type_str(),
@@ -4008,7 +4013,7 @@
                          true  /* locked */);
       } else {
         r->uninstall_surv_rate_group();
-        r->set_young_index_in_cset(-1);
+        r->clear_young_index_in_cset();
         r->set_evacuation_failed(false);
         // When moving a young gen region to old gen, we "allocate" that whole region
         // there. This is in addition to any already evacuated objects. Notify the
@@ -4381,7 +4386,7 @@
   virtual bool do_heap_region(HeapRegion* r) {
     assert(r->in_collection_set(), "Region %u must have been in collection set", r->hrm_index());
     G1CollectedHeap::heap()->clear_region_attr(r);
-    r->set_young_index_in_cset(-1);
+    r->clear_young_index_in_cset();
     return false;
   }
 };
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1211,11 +1211,11 @@
   // address "addr".  We say "blocks" instead of "object" since some heaps
   // may not pack objects densely; a chunk may either be an object or a
   // non-object.
-  virtual HeapWord* block_start(const void* addr) const;
+  HeapWord* block_start(const void* addr) const;
 
   // Requires "addr" to be the start of a block, and returns "TRUE" iff
   // the block is an object.
-  virtual bool block_is_obj(const HeapWord* addr) const;
+  bool block_is_obj(const HeapWord* addr) const;
 
   // Section on thread-local allocation buffers (TLABs)
   // See CollectedHeap for semantics.
@@ -1428,6 +1428,9 @@
   void print_cset_rsets() PRODUCT_RETURN;
   void print_all_rsets() PRODUCT_RETURN;
 
+  // Used to print information about locations in the hs_err file.
+  virtual bool print_location(outputStream* st, void* addr) const;
+
   size_t pending_card_num();
 };
 
--- a/src/hotspot/share/gc/g1/g1CollectionSet.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1CollectionSet.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -279,8 +279,10 @@
   assert(_inc_build_state == Active, "Precondition");
 
   size_t collection_set_length = _collection_set_cur_length;
-  assert(collection_set_length <= INT_MAX, "Collection set is too large with %d entries", (int)collection_set_length);
-  hr->set_young_index_in_cset((int)collection_set_length);
+  // We use UINT_MAX as "invalid" marker in verification.
+  assert(collection_set_length < (UINT_MAX - 1),
+         "Collection set is too large with " SIZE_FORMAT " entries", collection_set_length);
+  hr->set_young_index_in_cset((uint)collection_set_length + 1);
 
   _collection_set_regions[collection_set_length] = hr->hrm_index();
   // Concurrent readers must observe the store of the value in the array before an
@@ -550,12 +552,12 @@
 class G1VerifyYoungCSetIndicesClosure : public HeapRegionClosure {
 private:
   size_t _young_length;
-  int* _heap_region_indices;
+  uint* _heap_region_indices;
 public:
   G1VerifyYoungCSetIndicesClosure(size_t young_length) : HeapRegionClosure(), _young_length(young_length) {
-    _heap_region_indices = NEW_C_HEAP_ARRAY(int, young_length, mtGC);
-    for (size_t i = 0; i < young_length; i++) {
-      _heap_region_indices[i] = -1;
+    _heap_region_indices = NEW_C_HEAP_ARRAY(uint, young_length + 1, mtGC);
+    for (size_t i = 0; i < young_length + 1; i++) {
+      _heap_region_indices[i] = UINT_MAX;
     }
   }
   ~G1VerifyYoungCSetIndicesClosure() {
@@ -563,12 +565,12 @@
   }
 
   virtual bool do_heap_region(HeapRegion* r) {
-    const int idx = r->young_index_in_cset();
+    const uint idx = r->young_index_in_cset();
 
-    assert(idx > -1, "Young index must be set for all regions in the incremental collection set but is not for region %u.", r->hrm_index());
-    assert((size_t)idx < _young_length, "Young cset index too large for region %u", r->hrm_index());
+    assert(idx > 0, "Young index must be set for all regions in the incremental collection set but is not for region %u.", r->hrm_index());
+    assert(idx <= _young_length, "Young cset index %u too large for region %u", idx, r->hrm_index());
 
-    assert(_heap_region_indices[idx] == -1,
+    assert(_heap_region_indices[idx] == UINT_MAX,
            "Index %d used by multiple regions, first use by region %u, second by region %u",
            idx, _heap_region_indices[idx], r->hrm_index());
 
--- a/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1DirtyCardQueue.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/g1/g1BufferNodeList.hpp"
 #include "gc/g1/g1CardTableEntryClosure.hpp"
 #include "gc/g1/g1CollectedHeap.inline.hpp"
 #include "gc/g1/g1DirtyCardQueue.hpp"
@@ -215,7 +216,7 @@
 // must share the monitor.
 void G1DirtyCardQueueSet::merge_bufferlists(G1RedirtyCardsQueueSet* src) {
   assert(allocator() == src->allocator(), "precondition");
-  const G1RedirtyCardsBufferList from = src->take_all_completed_buffers();
+  const G1BufferNodeList from = src->take_all_completed_buffers();
   if (from._head == NULL) return;
 
   MutexLocker x(_cbl_mon, Mutex::_no_safepoint_check_flag);
--- a/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1FullGCCompactionPoint.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -116,11 +116,11 @@
     } else {
       // Make sure object has the correct mark-word set or that it will be
       // fixed when restoring the preserved marks.
-      assert(object->mark_raw() == markWord::prototype_for_object(object) || // Correct mark
-             object->mark_raw().must_be_preserved(object) || // Will be restored by PreservedMarksSet
+      assert(object->mark_raw() == markWord::prototype_for_klass(object->klass()) || // Correct mark
+             object->mark_must_be_preserved() || // Will be restored by PreservedMarksSet
              (UseBiasedLocking && object->has_bias_pattern_raw()), // Will be restored by BiasedLocking
              "should have correct prototype obj: " PTR_FORMAT " mark: " PTR_FORMAT " prototype: " PTR_FORMAT,
-             p2i(object), object->mark_raw().value(), markWord::prototype_for_object(object).value());
+             p2i(object), object->mark_raw().value(), markWord::prototype_for_klass(object->klass()).value());
     }
     assert(object->forwardee() == NULL, "should be forwarded to NULL");
   }
--- a/src/hotspot/share/gc/g1/g1FullGCMarker.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1FullGCMarker.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -29,7 +29,7 @@
 #include "gc/shared/preservedMarks.hpp"
 #include "gc/shared/taskqueue.hpp"
 #include "memory/iterator.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.hpp"
 #include "runtime/timer.hpp"
 #include "utilities/chunkedList.hpp"
--- a/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -51,7 +51,7 @@
 
   // Marked by us, preserve if needed.
   markWord mark = obj->mark_raw();
-  if (mark.must_be_preserved(obj) &&
+  if (obj->mark_must_be_preserved(mark) &&
       !G1ArchiveAllocator::is_open_archive_object(obj)) {
     preserved_stack()->push(obj, mark);
   }
--- a/src/hotspot/share/gc/g1/g1FullGCOopClosures.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1FullGCOopClosures.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -77,11 +77,11 @@
   oop forwardee = obj->forwardee();
   if (forwardee == NULL) {
     // Not forwarded, return current reference.
-    assert(obj->mark_raw() == markWord::prototype_for_object(obj) || // Correct mark
-           obj->mark_raw().must_be_preserved(obj) || // Will be restored by PreservedMarksSet
+    assert(obj->mark_raw() == markWord::prototype_for_klass(obj->klass()) || // Correct mark
+           obj->mark_must_be_preserved() || // Will be restored by PreservedMarksSet
            (UseBiasedLocking && obj->has_bias_pattern_raw()), // Will be restored by BiasedLocking
            "Must have correct prototype or be preserved, obj: " PTR_FORMAT ", mark: " PTR_FORMAT ", prototype: " PTR_FORMAT,
-           p2i(obj), obj->mark_raw().value(), markWord::prototype_for_object(obj).value());
+           p2i(obj), obj->mark_raw().value(), markWord::prototype_for_klass(obj->klass()).value());
     return;
   }
 
--- a/src/hotspot/share/gc/g1/g1OopClosures.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1OopClosures.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,7 +27,7 @@
 
 #include "gc/g1/g1HeapRegionAttr.hpp"
 #include "memory/iterator.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 
 class HeapRegion;
 class G1CollectedHeap;
--- a/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1PageBasedVirtualSpace.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,7 +25,7 @@
 #include "precompiled.hpp"
 #include "gc/g1/g1PageBasedVirtualSpace.hpp"
 #include "gc/shared/workgroup.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/os.inline.hpp"
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -59,19 +59,13 @@
     _old_gen_is_full(false),
     _num_optional_regions(optional_cset_length)
 {
-  // we allocate G1YoungSurvRateNumRegions plus one entries, since
-  // we "sacrifice" entry 0 to keep track of surviving bytes for
-  // non-young regions (where the age is -1)
+  // We allocate number of young gen regions in the collection set plus one
+  // entries, since entry 0 keeps track of surviving bytes for non-young regions.
   // We also add a few elements at the beginning and at the end in
   // an attempt to eliminate cache contention
-  size_t real_length = 1 + young_cset_length;
-  size_t array_length = PADDING_ELEM_NUM +
-                      real_length +
-                      PADDING_ELEM_NUM;
+  size_t real_length = young_cset_length + 1;
+  size_t array_length = PADDING_ELEM_NUM + real_length + PADDING_ELEM_NUM;
   _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
-  if (_surviving_young_words_base == NULL)
-    vm_exit_out_of_memory(array_length * sizeof(size_t), OOM_MALLOC_ERROR,
-                          "Not enough space for young surv histo.");
   _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM;
   memset(_surviving_young_words, 0, real_length * sizeof(size_t));
 
@@ -94,9 +88,9 @@
   _plab_allocator->flush_and_retire_stats();
   _g1h->policy()->record_age_table(&_age_table);
 
-  uint length = _g1h->collection_set()->young_region_length();
-  for (uint region_index = 0; region_index < length; region_index++) {
-    surviving_young_words[region_index] += _surviving_young_words[region_index];
+  uint length = _g1h->collection_set()->young_region_length() + 1;
+  for (uint i = 0; i < length; i++) {
+    surviving_young_words[i] += _surviving_young_words[i];
   }
 }
 
@@ -226,11 +220,6 @@
                                                  oop const old,
                                                  markWord const old_mark) {
   const size_t word_sz = old->size();
-  HeapRegion* const from_region = _g1h->heap_region_containing(old);
-  // +1 to make the -1 indexes valid...
-  const int young_index = from_region->young_index_in_cset()+1;
-  assert( (from_region->is_young() && young_index >  0) ||
-         (!from_region->is_young() && young_index == 0), "invariant" );
 
   uint age = 0;
   G1HeapRegionAttr dest_attr = next_region_attr(region_attr, old_mark, age);
@@ -281,6 +270,12 @@
   if (forward_ptr == NULL) {
     Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz);
 
+    HeapRegion* const from_region = _g1h->heap_region_containing(old);
+    const uint young_index = from_region->young_index_in_cset();
+
+    assert((from_region->is_young() && young_index >  0) ||
+           (!from_region->is_young() && young_index == 0), "invariant" );
+
     if (dest_attr.is_young()) {
       if (age < markWord::max_age) {
         age++;
@@ -303,7 +298,7 @@
     if (G1StringDedup::is_enabled()) {
       const bool is_from_young = region_attr.is_young();
       const bool is_to_young = dest_attr.is_young();
-      assert(is_from_young == _g1h->heap_region_containing(old)->is_young(),
+      assert(is_from_young == from_region->is_young(),
              "sanity");
       assert(is_to_young == _g1h->heap_region_containing(obj)->is_young(),
              "sanity");
@@ -415,7 +410,7 @@
     _g1h(g1h),
     _rdcqs(rdcqs),
     _states(NEW_C_HEAP_ARRAY(G1ParScanThreadState*, n_workers, mtGC)),
-    _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length, mtGC)),
+    _surviving_young_words_total(NEW_C_HEAP_ARRAY(size_t, young_cset_length + 1, mtGC)),
     _young_cset_length(young_cset_length),
     _optional_cset_length(optional_cset_length),
     _n_workers(n_workers),
@@ -423,7 +418,7 @@
   for (uint i = 0; i < n_workers; ++i) {
     _states[i] = NULL;
   }
-  memset(_surviving_young_words_total, 0, young_cset_length * sizeof(size_t));
+  memset(_surviving_young_words_total, 0, (young_cset_length + 1) * sizeof(size_t));
 }
 
 G1ParScanThreadStateSet::~G1ParScanThreadStateSet() {
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -145,12 +145,6 @@
   size_t lab_waste_words() const;
   size_t lab_undo_waste_words() const;
 
-  size_t* surviving_young_words() {
-    // We add one to hide entry 0 which accumulates surviving words for
-    // age -1 regions (i.e. non-young ones)
-    return _surviving_young_words + 1;
-  }
-
   void flush(size_t* surviving_young_words);
 
 private:
--- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -28,20 +28,6 @@
 #include "utilities/debug.hpp"
 #include "utilities/macros.hpp"
 
-// G1RedirtyCardsBufferList
-
-G1RedirtyCardsBufferList::G1RedirtyCardsBufferList() :
-  _head(NULL), _tail(NULL), _entry_count(0) {}
-
-G1RedirtyCardsBufferList::G1RedirtyCardsBufferList(BufferNode* head,
-                                                   BufferNode* tail,
-                                                   size_t entry_count) :
-  _head(head), _tail(tail), _entry_count(entry_count)
-{
-  assert((_head == NULL) == (_tail == NULL), "invariant");
-  assert((_head == NULL) == (_entry_count == 0), "invariant");
-}
-
 // G1RedirtyCardsQueueBase::LocalQSet
 
 G1RedirtyCardsQueueBase::LocalQSet::LocalQSet(G1RedirtyCardsQueueSet* shared_qset) :
@@ -67,9 +53,9 @@
   }
 }
 
-G1RedirtyCardsBufferList G1RedirtyCardsQueueBase::LocalQSet::take_all_completed_buffers() {
-  G1RedirtyCardsBufferList result = _buffers;
-  _buffers = G1RedirtyCardsBufferList();
+G1BufferNodeList G1RedirtyCardsQueueBase::LocalQSet::take_all_completed_buffers() {
+  G1BufferNodeList result = _buffers;
+  _buffers = G1BufferNodeList();
   return result;
 }
 
@@ -126,9 +112,9 @@
   return _list.top();
 }
 
-G1RedirtyCardsBufferList G1RedirtyCardsQueueSet::take_all_completed_buffers() {
+G1BufferNodeList G1RedirtyCardsQueueSet::take_all_completed_buffers() {
   DEBUG_ONLY(_collecting = false;)
-  G1RedirtyCardsBufferList result(_list.pop_all(), _tail, _entry_count);
+  G1BufferNodeList result(_list.pop_all(), _tail, _entry_count);
   _tail = NULL;
   _entry_count = 0;
   DEBUG_ONLY(_collecting = true;)
@@ -154,7 +140,7 @@
 
 void G1RedirtyCardsQueueSet::merge_bufferlist(LocalQSet* src) {
   assert(_collecting, "precondition");
-  const G1RedirtyCardsBufferList from = src->take_all_completed_buffers();
+  const G1BufferNodeList from = src->take_all_completed_buffers();
   if (from._head != NULL) {
     assert(from._tail != NULL, "invariant");
     Atomic::add(from._entry_count, &_entry_count);
--- a/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/g1RedirtyCardsQueue.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,6 +25,7 @@
 #ifndef SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP
 #define SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP
 
+#include "gc/g1/g1BufferNodeList.hpp"
 #include "gc/shared/ptrQueue.hpp"
 #include "memory/allocation.hpp"
 #include "memory/padded.hpp"
@@ -33,15 +34,6 @@
 class G1RedirtyCardsQueue;
 class G1RedirtyCardsQueueSet;
 
-struct G1RedirtyCardsBufferList {
-  BufferNode* _head;
-  BufferNode* _tail;
-  size_t _entry_count;
-
-  G1RedirtyCardsBufferList();
-  G1RedirtyCardsBufferList(BufferNode* head, BufferNode* tail, size_t entry_count);
-};
-
 // Provide G1RedirtyCardsQueue with a thread-local qset.  It provides an
 // uncontended staging area for completed buffers, to be flushed to the
 // shared qset en masse.  Using the "base from member" idiom so the local
@@ -52,7 +44,7 @@
 
   class LocalQSet : public PtrQueueSet {
     G1RedirtyCardsQueueSet* _shared_qset;
-    G1RedirtyCardsBufferList _buffers;
+    G1BufferNodeList _buffers;
 
   public:
     LocalQSet(G1RedirtyCardsQueueSet* shared_qset);
@@ -64,7 +56,7 @@
     // Transfer all completed buffers to the shared qset.
     void flush();
 
-    G1RedirtyCardsBufferList take_all_completed_buffers();
+    G1BufferNodeList take_all_completed_buffers();
   };
 
   G1RedirtyCardsQueueBase(G1RedirtyCardsQueueSet* shared_qset) :
@@ -123,7 +115,7 @@
   // Processing phase operations.
   // precondition: Must not be concurrent with buffer collection.
   BufferNode* all_completed_buffers() const;
-  G1RedirtyCardsBufferList take_all_completed_buffers();
+  G1BufferNodeList take_all_completed_buffers();
 };
 
 #endif // SHARE_GC_G1_G1REDIRTYCARDSQUEUE_HPP
--- a/src/hotspot/share/gc/g1/heapRegion.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/heapRegion.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -119,7 +119,7 @@
   assert(!in_collection_set(),
          "Should not clear heap region %u in the collection set", hrm_index());
 
-  set_young_index_in_cset(-1);
+  clear_young_index_in_cset();
   clear_index_in_opt_cset();
   uninstall_surv_rate_group();
   set_free();
--- a/src/hotspot/share/gc/g1/heapRegion.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/g1/heapRegion.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -255,7 +255,9 @@
   // The index in the optional regions array, if this region
   // is considered optional during a mixed collections.
   uint _index_in_opt_cset;
-  int  _young_index_in_cset;
+
+  // Data for young region survivor prediction.
+  uint  _young_index_in_cset;
   SurvRateGroup* _surv_rate_group;
   int  _age_index;
 
@@ -563,21 +565,24 @@
   void set_index_in_opt_cset(uint index) { _index_in_opt_cset = index; }
   void clear_index_in_opt_cset() { _index_in_opt_cset = InvalidCSetIndex; }
 
-  int  young_index_in_cset() const { return _young_index_in_cset; }
-  void set_young_index_in_cset(int index) {
-    assert( (index == -1) || is_young(), "pre-condition" );
+  uint  young_index_in_cset() const { return _young_index_in_cset; }
+  void clear_young_index_in_cset() { _young_index_in_cset = 0; }
+  void set_young_index_in_cset(uint index) {
+    assert(index != UINT_MAX, "just checking");
+    assert(index != 0, "just checking");
+    assert(is_young(), "pre-condition");
     _young_index_in_cset = index;
   }
 
   int age_in_surv_rate_group() {
-    assert( _surv_rate_group != NULL, "pre-condition" );
-    assert( _age_index > -1, "pre-condition" );
+    assert(_surv_rate_group != NULL, "pre-condition");
+    assert(_age_index > -1, "pre-condition");
     return _surv_rate_group->age_in_group(_age_index);
   }
 
   void record_surv_words_in_group(size_t words_survived) {
-    assert( _surv_rate_group != NULL, "pre-condition" );
-    assert( _age_index > -1, "pre-condition" );
+    assert(_surv_rate_group != NULL, "pre-condition");
+    assert(_age_index > -1, "pre-condition");
     int age_in_group = age_in_surv_rate_group();
     _surv_rate_group->record_surviving_words(age_in_group, words_survived);
   }
@@ -594,9 +599,9 @@
   }
 
   void install_surv_rate_group(SurvRateGroup* surv_rate_group) {
-    assert( surv_rate_group != NULL, "pre-condition" );
-    assert( _surv_rate_group == NULL, "pre-condition" );
-    assert( is_young(), "pre-condition" );
+    assert(surv_rate_group != NULL, "pre-condition");
+    assert(_surv_rate_group == NULL, "pre-condition");
+    assert(is_young(), "pre-condition");
 
     _surv_rate_group = surv_rate_group;
     _age_index = surv_rate_group->next_age_index();
@@ -604,13 +609,13 @@
 
   void uninstall_surv_rate_group() {
     if (_surv_rate_group != NULL) {
-      assert( _age_index > -1, "pre-condition" );
-      assert( is_young(), "pre-condition" );
+      assert(_age_index > -1, "pre-condition");
+      assert(is_young(), "pre-condition");
 
       _surv_rate_group = NULL;
       _age_index = -1;
     } else {
-      assert( _age_index == -1, "pre-condition" );
+      assert(_age_index == -1, "pre-condition");
     }
   }
 
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -41,6 +41,7 @@
 #include "gc/shared/gcLocker.hpp"
 #include "gc/shared/gcWhen.hpp"
 #include "gc/shared/genArguments.hpp"
+#include "gc/shared/locationPrinter.inline.hpp"
 #include "gc/shared/scavengableNMethods.hpp"
 #include "logging/log.hpp"
 #include "memory/metaspaceCounters.hpp"
@@ -584,6 +585,10 @@
   return PSHeapSummary(heap_summary, used(), old_summary, old_space, young_summary, eden_space, from_space, to_space);
 }
 
+bool ParallelScavengeHeap::print_location(outputStream* st, void* addr) const {
+  return BlockLocationPrinter<ParallelScavengeHeap>::print_location(st, addr);
+}
+
 void ParallelScavengeHeap::print_on(outputStream* st) const {
   young_gen()->print_on(st);
   old_gen()->print_on(st);
--- a/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/parallel/parallelScavengeHeap.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -228,6 +228,9 @@
   PreGenGCValues get_pre_gc_values() const;
   void print_heap_change(const PreGenGCValues& pre_gc_values) const;
 
+  // Used to print information about locations in the hs_err file.
+  virtual bool print_location(outputStream* st, void* addr) const;
+
   void verify(VerifyOption option /* ignored */);
 
   // Resize the young generation.  The reserved space for the
--- a/src/hotspot/share/gc/serial/markSweep.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/serial/markSweep.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -29,7 +29,7 @@
 #include "gc/shared/genOopClosures.hpp"
 #include "gc/shared/taskqueue.hpp"
 #include "memory/iterator.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.hpp"
 #include "runtime/timer.hpp"
 #include "utilities/growableArray.hpp"
--- a/src/hotspot/share/gc/serial/markSweep.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/serial/markSweep.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -28,7 +28,7 @@
 #include "classfile/classLoaderData.inline.hpp"
 #include "gc/serial/markSweep.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.inline.hpp"
+#include "oops/markWord.inline.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -40,7 +40,7 @@
   markWord mark = obj->mark_raw();
   obj->set_mark_raw(markWord::prototype().set_marked());
 
-  if (mark.must_be_preserved(obj)) {
+  if (obj->mark_must_be_preserved(mark)) {
     preserve_mark(obj, mark);
   }
 }
--- a/src/hotspot/share/gc/shared/ageTable.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/ageTable.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,7 +25,7 @@
 #ifndef SHARE_GC_SHARED_AGETABLE_HPP
 #define SHARE_GC_SHARED_AGETABLE_HPP
 
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.hpp"
 #include "runtime/perfData.hpp"
 
--- a/src/hotspot/share/gc/shared/collectedHeap.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/collectedHeap.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -254,9 +254,9 @@
   }
   GCCause::Cause gc_cause() { return _gc_cause; }
 
-  virtual oop obj_allocate(Klass* klass, int size, TRAPS);
+  oop obj_allocate(Klass* klass, int size, TRAPS);
   virtual oop array_allocate(Klass* klass, int size, int length, bool do_zero, TRAPS);
-  virtual oop class_allocate(Klass* klass, int size, TRAPS);
+  oop class_allocate(Klass* klass, int size, TRAPS);
 
   // Utilities for turning raw memory into filler objects.
   //
@@ -402,28 +402,6 @@
   // over live objects.
   virtual void safe_object_iterate(ObjectClosure* cl) = 0;
 
-  // NOTE! There is no requirement that a collector implement these
-  // functions.
-  //
-  // A CollectedHeap is divided into a dense sequence of "blocks"; that is,
-  // each address in the (reserved) heap is a member of exactly
-  // one block.  The defining characteristic of a block is that it is
-  // possible to find its size, and thus to progress forward to the next
-  // block.  (Blocks may be of different sizes.)  Thus, blocks may
-  // represent Java objects, or they might be free blocks in a
-  // free-list-based heap (or subheap), as long as the two kinds are
-  // distinguishable and the size of each is determinable.
-
-  // Returns the address of the start of the "block" that contains the
-  // address "addr".  We say "blocks" instead of "object" since some heaps
-  // may not pack objects densely; a chunk may either be an object or a
-  // non-object.
-  virtual HeapWord* block_start(const void* addr) const = 0;
-
-  // Requires "addr" to be the start of a block, and returns "TRUE" iff
-  // the block is an object.
-  virtual bool block_is_obj(const HeapWord* addr) const = 0;
-
   // Returns the longest time (in ms) that has elapsed since the last
   // time that any part of the heap was examined by a garbage collection.
   virtual jlong millis_since_last_gc() = 0;
@@ -461,6 +439,9 @@
 
   virtual void print_on_error(outputStream* st) const;
 
+  // Used to print information about locations in the hs_err file.
+  virtual bool print_location(outputStream* st, void* addr) const = 0;
+
   // Print all GC threads (other than the VM thread)
   // used by this heap.
   virtual void print_gc_threads_on(outputStream* st) const = 0;
--- a/src/hotspot/share/gc/shared/gcOverheadChecker.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/gcOverheadChecker.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -28,6 +28,7 @@
 
 #include "memory/allocation.hpp"
 #include "gc/shared/gcCause.hpp"
+#include "runtime/globals.hpp"
 
 class SoftRefPolicy;
 
--- a/src/hotspot/share/gc/shared/gcThreadLocalData.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/gcThreadLocalData.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -40,6 +40,6 @@
 // should consider placing frequently accessed fields first in
 // T, so that field offsets relative to Thread are small, which
 // often allows for a more compact instruction encoding.
-typedef uint64_t GCThreadLocalData[18]; // 144 bytes
+typedef uint64_t GCThreadLocalData[19]; // 152 bytes
 
 #endif // SHARE_GC_SHARED_GCTHREADLOCALDATA_HPP
--- a/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -47,6 +47,7 @@
 #include "gc/shared/genCollectedHeap.hpp"
 #include "gc/shared/genOopClosures.inline.hpp"
 #include "gc/shared/generationSpec.hpp"
+#include "gc/shared/locationPrinter.inline.hpp"
 #include "gc/shared/oopStorageParState.inline.hpp"
 #include "gc/shared/scavengableNMethods.hpp"
 #include "gc/shared/space.hpp"
@@ -1260,6 +1261,10 @@
 void GenCollectedHeap::print_gc_threads_on(outputStream* st) const {
 }
 
+bool GenCollectedHeap::print_location(outputStream* st, void* addr) const {
+  return BlockLocationPrinter<GenCollectedHeap>::print_location(st, addr);
+}
+
 void GenCollectedHeap::print_tracing_info() const {
   if (log_is_enabled(Debug, gc, heap, exit)) {
     LogStreamHandle(Debug, gc, heap, exit) lsh;
--- a/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/genCollectedHeap.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -260,13 +260,13 @@
   // address "addr".  We say "blocks" instead of "object" since some heaps
   // may not pack objects densely; a chunk may either be an object or a
   // non-object.
-  virtual HeapWord* block_start(const void* addr) const;
+  HeapWord* block_start(const void* addr) const;
 
   // Requires "addr" to be the start of a block, and returns "TRUE" iff
   // the block is an object. Assumes (and verifies in non-product
   // builds) that addr is in the allocated part of the heap and is
   // the start of a chunk.
-  virtual bool block_is_obj(const HeapWord* addr) const;
+  bool block_is_obj(const HeapWord* addr) const;
 
   // Section on TLAB's.
   virtual bool supports_tlab_allocation() const;
@@ -332,6 +332,9 @@
   virtual void gc_threads_do(ThreadClosure* tc) const;
   virtual void print_tracing_info() const;
 
+  // Used to print information about locations in the hs_err file.
+  virtual bool print_location(outputStream* st, void* addr) const;
+
   void print_heap_change(size_t young_prev_used, size_t old_prev_used) const;
 
   // The functions below are helper functions that a subclass of
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/locationPrinter.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,50 @@
+/*
+ * 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 "gc/shared/collectedHeap.hpp"
+#include "gc/shared/locationPrinter.hpp"
+#include "memory/universe.hpp"
+#include "runtime/os.hpp"
+#include "oops/klass.hpp"
+
+bool LocationPrinter::is_valid_obj(void* obj) {
+  if (!is_object_aligned(obj)) {
+    return false;
+  }
+  if (obj < (void*)os::min_page_size()) {
+    return false;
+  }
+
+  // We need at least the mark and the klass word in the committed region.
+  if (!os::is_readable_range(obj, (HeapWord*)obj + oopDesc::header_size())) {
+    return false;
+  }
+  if (!Universe::heap()->is_in(obj)) {
+    return false;
+  }
+
+  Klass* k = (Klass*)oopDesc::load_klass_raw((oopDesc*)obj);
+  return Klass::is_valid(k);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/locationPrinter.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_SHARED_LOCATIONPRINTER_HPP
+#define SHARE_GC_SHARED_LOCATIONPRINTER_HPP
+
+#include "memory/allocation.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class outputStream;
+
+class LocationPrinter : AllStatic {
+ public:
+  static bool is_valid_obj(void* addr);
+};
+
+template <typename CollectedHeapT>
+class BlockLocationPrinter : public LocationPrinter {
+  static oop base_oop_or_null(void* addr);
+
+public:
+  static bool print_location(outputStream* st, void* addr);
+};
+
+
+#endif // SHARE_GC_SHARED_LOCATIONPRINTER_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/locationPrinter.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,87 @@
+/*
+ * 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_GC_SHARED_LOCATIONPRINTER_INLINE_HPP
+#define SHARE_GC_SHARED_LOCATIONPRINTER_INLINE_HPP
+
+#include "gc/shared/locationPrinter.hpp"
+#include "oops/compressedOops.inline.hpp"
+#include "oops/oopsHierarchy.hpp"
+
+template <typename CollectedHeapT>
+oop BlockLocationPrinter<CollectedHeapT>::base_oop_or_null(void* addr) {
+  if (is_valid_obj(addr)) {
+    // We were just given an oop directly.
+    return oop(addr);
+  }
+
+  // Try to find addr using block_start.
+  HeapWord* p = CollectedHeapT::heap()->block_start(addr);
+  if (p != NULL && CollectedHeapT::heap()->block_is_obj(p)) {
+    if (!is_valid_obj(p)) {
+      return NULL;
+    }
+    return oop(p);
+  }
+
+  return NULL;
+}
+
+template <typename CollectedHeapT>
+bool BlockLocationPrinter<CollectedHeapT>::print_location(outputStream* st, void* addr) {
+  // Check if addr points into Java heap.
+  if (CollectedHeapT::heap()->is_in(addr)) {
+    oop o = base_oop_or_null(addr);
+    if (o != NULL) {
+      if ((void*)o == addr) {
+        st->print(INTPTR_FORMAT " is an oop: ", p2i(addr));
+      } else {
+        st->print(INTPTR_FORMAT " is pointing into object: " , p2i(addr));
+      }
+      o->print_on(st);
+      return true;
+    }
+  } else if (CollectedHeapT::heap()->is_in_reserved(addr)) {
+    st->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", p2i(addr));
+    return true;
+  }
+
+  // Compressed oop needs to be decoded first.
+#ifdef _LP64
+  if (UseCompressedOops && ((uintptr_t)addr &~ (uintptr_t)max_juint) == 0) {
+    narrowOop narrow_oop = (narrowOop)(uintptr_t)addr;
+    oop o = CompressedOops::decode_raw(narrow_oop);
+
+    if (is_valid_obj((address)o)) {
+      st->print(UINT32_FORMAT " is a compressed pointer to object: ", narrow_oop);
+      o->print_on(st);
+      return true;
+    }
+  }
+#endif
+
+  return false;
+}
+
+#endif // SHARE_GC_SHARED_LOCATIONPRINTER_INLINE_HPP
--- a/src/hotspot/share/gc/shared/memAllocator.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/memAllocator.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -226,10 +226,10 @@
   size_t size_in_bytes = _allocator._word_size * HeapWordSize;
 
   if (_allocated_outside_tlab) {
-    AllocTracer::send_allocation_outside_tlab(_allocator._klass, mem, size_in_bytes, _thread);
+    AllocTracer::send_allocation_outside_tlab(obj()->klass(), mem, size_in_bytes, _thread);
   } else if (_allocated_tlab_size != 0) {
     // TLAB was refilled
-    AllocTracer::send_allocation_in_new_tlab(_allocator._klass, mem, _allocated_tlab_size * HeapWordSize,
+    AllocTracer::send_allocation_in_new_tlab(obj()->klass(), mem, _allocated_tlab_size * HeapWordSize,
                                              size_in_bytes, _thread);
   }
 }
@@ -237,7 +237,7 @@
 void MemAllocator::Allocation::notify_allocation_dtrace_sampler() {
   if (DTraceAllocProbes) {
     // support for Dtrace object alloc event (no-op most of the time)
-    Klass* klass = _allocator._klass;
+    Klass* klass = obj()->klass();
     size_t word_size = _allocator._word_size;
     if (klass != NULL && klass->name() != NULL) {
       SharedRuntime::dtrace_object_alloc(obj(), (int)word_size);
--- a/src/hotspot/share/gc/shared/memAllocator.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/memAllocator.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -59,13 +59,11 @@
   // This finish constructing an oop by installing the mark word and the Klass* pointer
   // last. At the point when the Klass pointer is initialized, this is a constructed object
   // that must be parseable as an oop by concurrent collectors.
-  oop finish(HeapWord* mem) const;
+  virtual oop finish(HeapWord* mem) const;
 
-  // Raw memory allocation. This may or may not use TLAB allocations to satisfy the
-  // allocation. A GC implementation may override this function to satisfy the allocation
-  // in any way. But the default is to try a TLAB allocation, and otherwise perform
-  // mem_allocate.
-  virtual HeapWord* mem_allocate(Allocation& allocation) const;
+  // Raw memory allocation. This will try to do a TLAB allocation, and otherwise fall
+  // back to calling CollectedHeap::mem_allocate().
+  HeapWord* mem_allocate(Allocation& allocation) const;
 
   virtual MemRegion obj_memory_range(oop obj) const {
     return MemRegion((HeapWord*)obj, _word_size);
--- a/src/hotspot/share/gc/shared/oopStorageParState.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/oopStorageParState.hpp	Wed Aug 28 11:58:56 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
@@ -153,6 +153,8 @@
                 bool concurrent);
   ~BasicParState();
 
+  const OopStorage* storage() const { return _storage; }
+
   template<bool is_const, typename F> void iterate(F f);
 
   static uint default_estimated_thread_count(bool concurrent);
@@ -172,6 +174,7 @@
     _basic_state(storage, estimated_thread_count, concurrent)
   {}
 
+  const OopStorage* storage() const { return _basic_state.storage(); }
   template<typename F> void iterate(F f);
   template<typename Closure> void oops_do(Closure* cl);
 };
@@ -186,6 +189,7 @@
     _basic_state(storage, estimated_thread_count, false)
   {}
 
+  const OopStorage* storage() const { return _basic_state.storage(); }
   template<typename F> void iterate(F f);
   template<typename Closure> void oops_do(Closure* cl);
   template<typename Closure> void weak_oops_do(Closure* cl);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/oopStorageSet.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,94 @@
+/*
+ * 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 "gc/shared/oopStorage.hpp"
+#include "gc/shared/oopStorageSet.hpp"
+#include "runtime/mutex.hpp"
+#include "runtime/os.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+
+// +1 for NULL singular entry.
+OopStorage* OopStorageSet::storages[all_count + 1] = {};
+
+static Mutex* make_oopstorage_mutex(const char* storage_name,
+                                    const char* kind,
+                                    int rank) {
+  char name[256];
+  os::snprintf(name, sizeof(name), "%s %s lock", storage_name, kind);
+  return new PaddedMutex(rank, name, true, Mutex::_safepoint_check_never);
+}
+
+static OopStorage* make_oopstorage(const char* name) {
+  Mutex* alloc = make_oopstorage_mutex(name, "alloc", Mutex::oopstorage);
+  Mutex* active = make_oopstorage_mutex(name, "active", Mutex::oopstorage - 1);
+  return new OopStorage(name, alloc, active);
+}
+
+void OopStorageSet::initialize() {
+  storages[jni_global_index]        = make_oopstorage("JNI global");
+  storages[vm_global_index]         = make_oopstorage("VM global");
+  storages[jni_weak_index]          = make_oopstorage("JNI weak");
+  storages[vm_weak_index]           = make_oopstorage("VM weak");
+  storages[string_table_weak_index] = make_oopstorage("StringTable weak");
+  storages[resolved_method_table_weak_index] =
+    make_oopstorage("ResolvedMethodTable weak");
+
+  // Ensure we have all of them.
+  STATIC_ASSERT(all_count == 6);
+  assert(storages[singular_index] == NULL, "postcondition");
+#ifdef ASSERT
+  for (uint i = all_start; i < all_end; ++i) {
+    assert(storages[i] != NULL, "postcondition");
+  }
+#endif // ASSERT
+}
+
+void oopstorage_init() {
+  OopStorageSet::initialize();
+}
+
+#ifdef ASSERT
+
+void OopStorageSet::verify_initialized(uint index) {
+  assert(storages[index] != NULL, "oopstorage_init not yet called");
+}
+
+void OopStorageSet::Iterator::verify_nonsingular() const {
+  assert(_category != singular, "precondition");
+}
+
+void OopStorageSet::Iterator::verify_category_match(const Iterator& other) const {
+  verify_nonsingular();
+  assert(_category == other._category, "precondition");
+}
+
+void OopStorageSet::Iterator::verify_dereferenceable() const {
+  verify_nonsingular();
+  assert(!is_end(), "precondition");
+}
+
+#endif // ASSERT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/shared/oopStorageSet.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,184 @@
+/*
+ * 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_GC_SHARED_OOPSTORAGESET_HPP
+#define SHARE_GC_SHARED_OOPSTORAGESET_HPP
+
+#include "memory/allocation.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+
+class OopStorage;
+
+class OopStorageSet : public AllStatic {
+private:
+  friend void oopstorage_init();
+
+  enum {
+    singular_index,             // For singular iterator.
+
+    all_start,
+
+    // Strong
+    strong_start = all_start,
+    jni_global_index = strong_start,
+    vm_global_index,
+    strong_end,
+
+    // Weak
+    weak_start = strong_end,
+    jni_weak_index = weak_start,
+    vm_weak_index,
+    string_table_weak_index,
+    resolved_method_table_weak_index,
+    weak_end,
+
+    all_end = weak_end
+  };
+
+  static OopStorage* storages[all_end];
+
+  static void verify_initialized(uint index) NOT_DEBUG_RETURN;
+
+  static OopStorage* storage(uint index) {
+    verify_initialized(index);
+    return storages[index];
+  }
+
+  static void initialize();
+
+public:
+  class Iterator;
+
+  static const uint strong_count = (strong_end - strong_start);
+  static const uint weak_count = (weak_end - weak_start);
+  static const uint all_count = (all_end - all_start);
+
+  static Iterator strong_iterator();
+  static Iterator weak_iterator();
+  static Iterator all_iterator();
+
+  // Strong
+  static OopStorage* jni_global() { return storage(jni_global_index); }
+  static OopStorage* vm_global()  { return storage(vm_global_index); }
+
+  // Weak
+  static OopStorage* jni_weak()   { return storage(jni_weak_index); }
+  static OopStorage* vm_weak()    { return storage(vm_weak_index); }
+
+  static OopStorage* string_table_weak() {
+    return storage(string_table_weak_index);
+  }
+
+  static OopStorage* resolved_method_table_weak() {
+    return storage(resolved_method_table_weak_index);
+  }
+};
+
+class OopStorageSet::Iterator {
+  friend class OopStorageSet;
+
+  enum Category { singular, strong, weak, all };
+
+  uint _index;
+  uint _limit;
+  DEBUG_ONLY(Category _category;)
+
+  Iterator(uint index, uint limit, Category category) :
+    _index(index), _limit(limit) DEBUG_ONLY(COMMA _category(category)) {}
+
+  void verify_nonsingular() const NOT_DEBUG_RETURN;
+  void verify_category_match(const Iterator& other) const NOT_DEBUG_RETURN;
+  void verify_dereferenceable() const NOT_DEBUG_RETURN;
+
+public:
+  // Construct a singular iterator for later assignment.  The only valid
+  // operations are destruction and assignment.
+  Iterator() :
+    _index(singular_index),
+    _limit(singular_index)
+    DEBUG_ONLY(COMMA _category(singular)) {}
+
+  bool is_end() const {
+    verify_nonsingular();
+    return _index == _limit;
+  }
+
+  bool operator==(const Iterator& other) const {
+    verify_category_match(other);
+    return _index == other._index;
+  }
+
+  bool operator!=(const Iterator& other) const {
+    return !operator==(other);
+  }
+
+  OopStorage* operator*() const {
+    verify_dereferenceable();
+    return storage(_index);
+  }
+
+  OopStorage* operator->() const {
+    return operator*();
+  }
+
+  Iterator& operator++() {
+    verify_dereferenceable();
+    ++_index;
+    return *this;
+  }
+
+  Iterator operator++(int) {
+    Iterator result = *this;
+    operator++();
+    return result;
+  }
+
+  Iterator begin() const {
+    verify_nonsingular();
+    return *this;
+  }
+
+  Iterator end() const {
+    verify_nonsingular();
+    Iterator result = *this;
+    result._index = _limit;
+    return result;
+  }
+};
+
+inline OopStorageSet::Iterator OopStorageSet::strong_iterator() {
+  return Iterator(strong_start, strong_end, Iterator::strong);
+}
+
+inline OopStorageSet::Iterator OopStorageSet::weak_iterator() {
+  return Iterator(weak_start, weak_end, Iterator::weak);
+}
+
+inline OopStorageSet::Iterator OopStorageSet::all_iterator() {
+  return Iterator(all_start, all_end, Iterator::all);
+}
+
+#endif // SHARE_GC_SHARED_OOPSTORAGESET_HPP
--- a/src/hotspot/share/gc/shared/preservedMarks.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/preservedMarks.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -31,7 +31,7 @@
 #include "utilities/stack.inline.hpp"
 
 inline bool PreservedMarks::should_preserve_mark(oop obj, markWord m) const {
-  return m.must_be_preserved_for_promotion_failure(obj);
+  return obj->mark_must_be_preserved_for_promotion_failure(m);
 }
 
 inline void PreservedMarks::push(oop obj, markWord m) {
--- a/src/hotspot/share/gc/shared/space.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/space.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -31,7 +31,7 @@
 #include "memory/allocation.hpp"
 #include "memory/iterator.hpp"
 #include "memory/memRegion.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "utilities/align.hpp"
 #include "utilities/macros.hpp"
--- a/src/hotspot/share/gc/shared/weakProcessor.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/weakProcessor.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,6 +26,7 @@
 #include "classfile/stringTable.hpp"
 #include "gc/shared/oopStorage.inline.hpp"
 #include "gc/shared/oopStorageParState.inline.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "gc/shared/weakProcessor.inline.hpp"
 #include "gc/shared/weakProcessorPhases.hpp"
 #include "gc/shared/weakProcessorPhaseTimes.hpp"
@@ -38,11 +39,11 @@
 template <typename Container>
 class OopsDoAndReportCounts {
 public:
-  void operator()(BoolObjectClosure* is_alive, OopClosure* keep_alive, WeakProcessorPhase phase) {
+  void operator()(BoolObjectClosure* is_alive, OopClosure* keep_alive, OopStorage* storage) {
     Container::reset_dead_counter();
 
     CountingSkippedIsAliveClosure<BoolObjectClosure, OopClosure> cl(is_alive, keep_alive);
-    WeakProcessorPhases::oop_storage(phase)->oops_do(&cl);
+    storage->oops_do(&cl);
 
     Container::inc_dead_counter(cl.num_dead() + cl.num_skipped());
     Container::finish_dead_counter();
@@ -50,17 +51,19 @@
 };
 
 void WeakProcessor::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive) {
-  FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
-    if (WeakProcessorPhases::is_serial(phase)) {
-      WeakProcessorPhases::processor(phase)(is_alive, keep_alive);
+  WeakProcessorPhases::Iterator pit = WeakProcessorPhases::serial_iterator();
+  for ( ; !pit.is_end(); ++pit) {
+    WeakProcessorPhases::processor(*pit)(is_alive, keep_alive);
+  }
+
+  OopStorageSet::Iterator it = OopStorageSet::weak_iterator();
+  for ( ; !it.is_end(); ++it) {
+    if (OopStorageSet::string_table_weak() == *it) {
+      OopsDoAndReportCounts<StringTable>()(is_alive, keep_alive, *it);
+    } else if (OopStorageSet::resolved_method_table_weak() == *it) {
+      OopsDoAndReportCounts<ResolvedMethodTable>()(is_alive, keep_alive, *it);
     } else {
-      if (WeakProcessorPhases::is_stringtable(phase)) {
-        OopsDoAndReportCounts<StringTable>()(is_alive, keep_alive, phase);
-      } else if (WeakProcessorPhases::is_resolved_method_table(phase)){
-        OopsDoAndReportCounts<ResolvedMethodTable>()(is_alive, keep_alive, phase);
-      } else {
-        WeakProcessorPhases::oop_storage(phase)->weak_oops_do(is_alive, keep_alive);
-      }
+      it->weak_oops_do(is_alive, keep_alive);
     }
   }
 }
@@ -86,8 +89,9 @@
   // and development oriented, so not allocating any threads
   // specifically for them is okay.
   size_t ref_count = 0;
-  FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) {
-    ref_count += WeakProcessorPhases::oop_storage(phase)->allocation_count();
+  OopStorageSet::Iterator it = OopStorageSet::weak_iterator();
+  for ( ; !it.is_end(); ++it) {
+    ref_count += it->allocation_count();
   }
 
   // +1 to (approx) round up the ref per thread division.
@@ -106,14 +110,16 @@
     _phase_times->set_active_workers(_nworkers);
   }
 
-  uint storage_count = WeakProcessorPhases::oop_storage_phase_count;
+  uint storage_count = WeakProcessorPhases::oopstorage_phase_count;
   _storage_states = NEW_C_HEAP_ARRAY(StorageState, storage_count, mtGC);
 
-  StorageState* states = _storage_states;
-  FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) {
-    OopStorage* storage = WeakProcessorPhases::oop_storage(phase);
-    new (states++) StorageState(storage, _nworkers);
+  StorageState* cur_state = _storage_states;
+  OopStorageSet::Iterator it = OopStorageSet::weak_iterator();
+  for ( ; !it.is_end(); ++it, ++cur_state) {
+    assert(pointer_delta(cur_state, _storage_states, sizeof(StorageState)) < storage_count, "invariant");
+    new (cur_state) StorageState(*it, _nworkers);
   }
+  assert(pointer_delta(cur_state, _storage_states, sizeof(StorageState)) == storage_count, "invariant");
   StringTable::reset_dead_counter();
   ResolvedMethodTable::reset_dead_counter();
 }
@@ -139,7 +145,7 @@
 WeakProcessor::Task::~Task() {
   if (_storage_states != NULL) {
     StorageState* states = _storage_states;
-    FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) {
+    for (uint i = 0; i < WeakProcessorPhases::oopstorage_phase_count; ++i) {
       states->StorageState::~StorageState();
       ++states;
     }
--- a/src/hotspot/share/gc/shared/weakProcessor.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/weakProcessor.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -28,6 +28,7 @@
 #include "classfile/stringTable.hpp"
 #include "gc/shared/oopStorage.inline.hpp"
 #include "gc/shared/oopStorageParState.inline.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "gc/shared/weakProcessor.hpp"
 #include "gc/shared/weakProcessorPhases.hpp"
 #include "gc/shared/weakProcessorPhaseTimes.hpp"
@@ -94,31 +95,36 @@
          "worker_id (%u) exceeds task's configured workers (%u)",
          worker_id, _nworkers);
 
-  FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
-    if (WeakProcessorPhases::is_serial(phase)) {
-      CountingIsAliveClosure<IsAlive> cl(is_alive);
-      uint serial_index = WeakProcessorPhases::serial_index(phase);
-      if (_serial_phases_done.try_claim_task(serial_index)) {
-        WeakProcessorPhaseTimeTracker pt(_phase_times, phase);
-        WeakProcessorPhases::processor(phase)(&cl, keep_alive);
-        if (_phase_times != NULL) {
-          _phase_times->record_phase_items(phase, cl.num_dead(), cl.num_total());
-        }
+  typedef WeakProcessorPhases::Iterator Iterator;
+
+  for (Iterator it = WeakProcessorPhases::serial_iterator(); !it.is_end(); ++it) {
+    WeakProcessorPhase phase = *it;
+    CountingIsAliveClosure<IsAlive> cl(is_alive);
+    uint serial_index = WeakProcessorPhases::serial_index(phase);
+    if (_serial_phases_done.try_claim_task(serial_index)) {
+      WeakProcessorPhaseTimeTracker pt(_phase_times, phase);
+      WeakProcessorPhases::processor(phase)(&cl, keep_alive);
+      if (_phase_times != NULL) {
+        _phase_times->record_phase_items(phase, cl.num_dead(), cl.num_total());
       }
-    } else {
-      CountingSkippedIsAliveClosure<IsAlive, KeepAlive> cl(is_alive, keep_alive);
-      WeakProcessorPhaseTimeTracker pt(_phase_times, phase, worker_id);
-      uint storage_index = WeakProcessorPhases::oop_storage_index(phase);
-      _storage_states[storage_index].oops_do(&cl);
-      if (_phase_times != NULL) {
-        _phase_times->record_worker_items(worker_id, phase, cl.num_dead(), cl.num_total());
-      }
-      if (WeakProcessorPhases::is_stringtable(phase)) {
-        StringTable::inc_dead_counter(cl.num_dead() + cl.num_skipped());
-      }
-      if (WeakProcessorPhases::is_resolved_method_table(phase)) {
-        ResolvedMethodTable::inc_dead_counter(cl.num_dead() + cl.num_skipped());
-      }
+    }
+  }
+
+  for (Iterator it = WeakProcessorPhases::oopstorage_iterator(); !it.is_end(); ++it) {
+    WeakProcessorPhase phase = *it;
+    CountingSkippedIsAliveClosure<IsAlive, KeepAlive> cl(is_alive, keep_alive);
+    WeakProcessorPhaseTimeTracker pt(_phase_times, phase, worker_id);
+    uint oopstorage_index = WeakProcessorPhases::oopstorage_index(phase);
+    StorageState& cur_state = _storage_states[oopstorage_index];
+    cur_state.oops_do(&cl);
+    if (_phase_times != NULL) {
+      _phase_times->record_worker_items(worker_id, phase, cl.num_dead(), cl.num_total());
+    }
+    const OopStorage* cur_storage = cur_state.storage();
+    if (cur_storage == OopStorageSet::string_table_weak()) {
+      StringTable::inc_dead_counter(cl.num_dead() + cl.num_skipped());
+    } else if (cur_storage == OopStorageSet::resolved_method_table_weak()) {
+      ResolvedMethodTable::inc_dead_counter(cl.num_dead() + cl.num_skipped());
     }
   }
 
--- a/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/shared/oopStorage.hpp"
 #include "gc/shared/weakProcessorPhases.hpp"
 #include "gc/shared/weakProcessorPhaseTimes.hpp"
 #include "gc/shared/workerDataArray.inline.hpp"
@@ -32,17 +33,22 @@
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/ticks.hpp"
 
-static uint phase_index(WeakProcessorPhase phase) {
-  return WeakProcessorPhases::index(phase);
+static uint serial_phase_index(WeakProcessorPhase phase) {
+  return WeakProcessorPhases::serial_index(phase);
 }
 
 static bool is_serial_phase(WeakProcessorPhase phase) {
   return WeakProcessorPhases::is_serial(phase);
 }
 
-static void assert_oop_storage_phase(WeakProcessorPhase phase) {
-  assert(WeakProcessorPhases::is_oop_storage(phase),
-         "Not an oop_storage phase %u", phase_index(phase));
+static void assert_serial_phase(WeakProcessorPhase phase) {
+  assert(is_serial_phase(phase),
+         "Not a serial phase %u", static_cast<uint>(phase));
+}
+
+static void assert_oopstorage_phase(WeakProcessorPhase phase) {
+  assert(WeakProcessorPhases::is_oopstorage(phase),
+         "Not an oopstorage phase %u", static_cast<uint>(phase));
 }
 
 const double uninitialized_time = -1.0;
@@ -64,6 +70,12 @@
   }
 }
 
+void WeakProcessorPhaseTimes::reset_phase_data() {
+  reset_times(_phase_times_sec, ARRAY_SIZE(_phase_times_sec));
+  reset_items(_phase_dead_items, ARRAY_SIZE(_phase_dead_items));
+  reset_items(_phase_total_items, ARRAY_SIZE(_phase_total_items));
+}
+
 WeakProcessorPhaseTimes::WeakProcessorPhaseTimes(uint max_threads) :
   _max_threads(max_threads),
   _active_workers(0),
@@ -74,20 +86,19 @@
 {
   assert(_max_threads > 0, "max_threads must not be zero");
 
-  reset_times(_phase_times_sec, ARRAY_SIZE(_phase_times_sec));
-  reset_items(_phase_dead_items, ARRAY_SIZE(_phase_dead_items));
-  reset_items(_phase_total_items, ARRAY_SIZE(_phase_total_items));
+  reset_phase_data();
 
-  if (_max_threads > 1) {
-    WorkerDataArray<double>** wpt = _worker_data;
-    FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(phase) {
-      const char* description = WeakProcessorPhases::description(phase);
-      *wpt = new WorkerDataArray<double>(_max_threads, description);
-      (*wpt)->link_thread_work_items(new WorkerDataArray<size_t>(_max_threads, "Dead"), DeadItems);
-      (*wpt)->link_thread_work_items(new WorkerDataArray<size_t>(_max_threads, "Total"), TotalItems);
-      wpt++;
-    }
+  WorkerDataArray<double>** wpt = _worker_data;
+  OopStorageSet::Iterator it = OopStorageSet::weak_iterator();
+  for ( ; !it.is_end(); ++it) {
+    assert(size_t(wpt - _worker_data) < ARRAY_SIZE(_worker_data), "invariant");
+    const char* description = it->name();
+    *wpt = new WorkerDataArray<double>(_max_threads, description);
+    (*wpt)->link_thread_work_items(new WorkerDataArray<size_t>(_max_threads, "Dead"), DeadItems);
+    (*wpt)->link_thread_work_items(new WorkerDataArray<size_t>(_max_threads, "Total"), TotalItems);
+    wpt++;
   }
+  assert(size_t(wpt - _worker_data) == ARRAY_SIZE(_worker_data), "invariant");
 }
 
 WeakProcessorPhaseTimes::~WeakProcessorPhaseTimes() {
@@ -115,13 +126,9 @@
 void WeakProcessorPhaseTimes::reset() {
   _active_workers = 0;
   _total_time_sec = uninitialized_time;
-  reset_times(_phase_times_sec, ARRAY_SIZE(_phase_times_sec));
-  reset_items(_phase_dead_items, ARRAY_SIZE(_phase_dead_items));
-  reset_items(_phase_total_items, ARRAY_SIZE(_phase_total_items));
-  if (_max_threads > 1) {
-    for (size_t i = 0; i < ARRAY_SIZE(_worker_data); ++i) {
-      _worker_data[i]->reset();
-    }
+  reset_phase_data();
+  for (size_t i = 0; i < ARRAY_SIZE(_worker_data); ++i) {
+    _worker_data[i]->reset();
   }
 }
 
@@ -136,19 +143,22 @@
 }
 
 double WeakProcessorPhaseTimes::phase_time_sec(WeakProcessorPhase phase) const {
-  assert(is_initialized_time(_phase_times_sec[phase_index(phase)]),
-         "phase time not set %u", phase_index(phase));
-  return _phase_times_sec[phase_index(phase)];
+  assert_serial_phase(phase);
+  assert(is_initialized_time(_phase_times_sec[serial_phase_index(phase)]),
+         "phase time not set %u", serial_phase_index(phase));
+  return _phase_times_sec[serial_phase_index(phase)];
 }
 
 void WeakProcessorPhaseTimes::record_phase_time_sec(WeakProcessorPhase phase, double time_sec) {
-  assert(!is_initialized_time(_phase_times_sec[phase_index(phase)]),
-         "Already set time for phase %u", phase_index(phase));
-  _phase_times_sec[phase_index(phase)] = time_sec;
+  assert_serial_phase(phase);
+  assert(!is_initialized_time(_phase_times_sec[serial_phase_index(phase)]),
+         "Already set time for phase %u", serial_phase_index(phase));
+  _phase_times_sec[serial_phase_index(phase)] = time_sec;
 }
 
 void WeakProcessorPhaseTimes::record_phase_items(WeakProcessorPhase phase, size_t num_dead, size_t num_total) {
-  uint p = phase_index(phase);
+  assert_serial_phase(phase);
+  uint p = serial_phase_index(phase);
   assert(!is_initialized_items(_phase_dead_items[p]),
          "Already set dead items for phase %u", p);
   assert(!is_initialized_items(_phase_total_items[p]),
@@ -158,41 +168,29 @@
 }
 
 WorkerDataArray<double>* WeakProcessorPhaseTimes::worker_data(WeakProcessorPhase phase) const {
-  assert_oop_storage_phase(phase);
-  assert(active_workers() > 1, "No worker data when single-threaded");
-  return _worker_data[WeakProcessorPhases::oop_storage_index(phase)];
+  assert_oopstorage_phase(phase);
+  return _worker_data[WeakProcessorPhases::oopstorage_index(phase)];
 }
 
 double WeakProcessorPhaseTimes::worker_time_sec(uint worker_id, WeakProcessorPhase phase) const {
   assert(worker_id < active_workers(),
          "invalid worker id %u for %u", worker_id, active_workers());
-  if (active_workers() == 1) {
-    return phase_time_sec(phase);
-  } else {
-    return worker_data(phase)->get(worker_id);
-  }
+  return worker_data(phase)->get(worker_id);
 }
 
 void WeakProcessorPhaseTimes::record_worker_time_sec(uint worker_id,
                                                      WeakProcessorPhase phase,
                                                      double time_sec) {
-  if (active_workers() == 1) {
-    record_phase_time_sec(phase, time_sec);
-  } else {
-    worker_data(phase)->set(worker_id, time_sec);
-  }
+  worker_data(phase)->set(worker_id, time_sec);
 }
 
 void WeakProcessorPhaseTimes::record_worker_items(uint worker_id,
                                                   WeakProcessorPhase phase,
                                                   size_t num_dead,
                                                   size_t num_total) {
-  if (active_workers() == 1) {
-    record_phase_items(phase, num_dead, num_total);
-  } else {
-    worker_data(phase)->set_or_add_thread_work_item(worker_id, num_dead, DeadItems);
-    worker_data(phase)->set_or_add_thread_work_item(worker_id, num_total, TotalItems);
-  }
+  WorkerDataArray<double>* phase_data = worker_data(phase);
+  phase_data->set_or_add_thread_work_item(worker_id, num_dead, DeadItems);
+  phase_data->set_or_add_thread_work_item(worker_id, num_total, TotalItems);
 }
 
 static double elapsed_time_sec(Ticks start_time, Ticks end_time) {
@@ -219,7 +217,7 @@
   _worker_id(worker_id),
   _start_time(Ticks::now())
 {
-  assert_oop_storage_phase(_phase);
+  assert_oopstorage_phase(_phase);
   assert(_times == NULL || worker_id < _times->active_workers(),
          "Invalid worker_id %u", worker_id);
 }
@@ -231,7 +229,7 @@
   _worker_id(0),
   _start_time(Ticks::now())
 {
-  assert(is_serial_phase(phase), "Not a serial phase %u", phase_index(phase));
+  assert_serial_phase(phase);
 }
 
 WeakProcessorPhaseTimeTracker::~WeakProcessorPhaseTimeTracker() {
@@ -259,6 +257,7 @@
 
 void WeakProcessorPhaseTimes::log_st_phase(WeakProcessorPhase phase,
                                            uint indent) const {
+  assert_serial_phase(phase);
   log_debug(gc, phases)("%s%s: " TIME_FORMAT,
                         indent_str(indent),
                         WeakProcessorPhases::description(phase),
@@ -267,12 +266,12 @@
   log_debug(gc, phases)("%s%s: " SIZE_FORMAT,
                         indent_str(indent + 1),
                         "Dead",
-                        _phase_dead_items[phase_index(phase)]);
+                        _phase_dead_items[serial_phase_index(phase)]);
 
   log_debug(gc, phases)("%s%s: " SIZE_FORMAT,
                         indent_str(indent + 1),
                         "Total",
-                        _phase_total_items[phase_index(phase)]);
+                        _phase_total_items[serial_phase_index(phase)]);
 }
 
 void WeakProcessorPhaseTimes::log_mt_phase_summary(WeakProcessorPhase phase,
@@ -306,12 +305,12 @@
 
 void WeakProcessorPhaseTimes::log_print_phases(uint indent) const {
   if (log_is_enabled(Debug, gc, phases)) {
-    FOR_EACH_WEAK_PROCESSOR_PHASE(phase) {
-      if (is_serial_phase(phase) || (active_workers() == 1)) {
-        log_st_phase(phase, indent);
-      } else {
-        log_mt_phase_summary(phase, indent);
-      }
+    typedef WeakProcessorPhases::Iterator Iterator;
+    for (Iterator it = WeakProcessorPhases::serial_iterator(); !it.is_end(); ++it) {
+      log_st_phase(*it, indent);
+    }
+    for (Iterator it = WeakProcessorPhases::oopstorage_iterator(); !it.is_end(); ++it) {
+      log_mt_phase_summary(*it, indent);
     }
   }
 }
--- a/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/weakProcessorPhaseTimes.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,6 +25,7 @@
 #ifndef SHARE_GC_SHARED_WEAKPROCESSORPHASETIMES_HPP
 #define SHARE_GC_SHARED_WEAKPROCESSORPHASETIMES_HPP
 
+#include "gc/shared/oopStorageSet.hpp"
 #include "gc/shared/weakProcessorPhases.hpp"
 #include "memory/allocation.hpp"
 #include "utilities/globalDefinitions.hpp"
@@ -43,17 +44,20 @@
   // Total time for weak processor.
   double _total_time_sec;
 
-  // Total time for each serially processed phase.  Entries for phases
-  // processed by multiple threads are unused, as are entries for
-  // unexecuted phases.
-  double _phase_times_sec[WeakProcessorPhases::phase_count];
-  size_t _phase_dead_items[WeakProcessorPhases::phase_count];
-  size_t _phase_total_items[WeakProcessorPhases::phase_count];
+  // Total time and associated items for each serially processed phase.
+  static const uint phase_data_count = WeakProcessorPhases::serial_phase_count;
+  // +1 because serial_phase_count == 0 in some build configurations.
+  // Simpler to always allocate extra space than conditionalize.
+  double _phase_times_sec[phase_data_count + 1];
+  size_t _phase_dead_items[phase_data_count + 1];
+  size_t _phase_total_items[phase_data_count + 1];
+  void reset_phase_data();
 
-  // Per-worker times and linked items, if multiple threads used and the phase was executed.
-  WorkerDataArray<double>* _worker_data[WeakProcessorPhases::oop_storage_phase_count];
-  WorkerDataArray<size_t>* _worker_dead_items[WeakProcessorPhases::oop_storage_phase_count];
-  WorkerDataArray<size_t>* _worker_total_items[WeakProcessorPhases::oop_storage_phase_count];
+  // Per-worker times and linked items.
+  static const uint worker_data_count = WeakProcessorPhases::oopstorage_phase_count;
+  WorkerDataArray<double>* _worker_data[worker_data_count];
+  WorkerDataArray<size_t>* _worker_dead_items[worker_data_count];
+  WorkerDataArray<size_t>* _worker_total_items[worker_data_count];
 
   WorkerDataArray<double>* worker_data(WeakProcessorPhase phase) const;
 
@@ -114,7 +118,7 @@
 
   // For tracking possibly parallel phase times (even if processed by
   // only one thread).
-  // Precondition: WeakProcessorPhases::is_oop_storage(phase)
+  // Precondition: WeakProcessorPhases::is_oopstorage(phase)
   // Precondition: worker_id < times->max_threads().
   WeakProcessorPhaseTimeTracker(WeakProcessorPhaseTimes* times,
                                 WeakProcessorPhase phase,
--- a/src/hotspot/share/gc/shared/weakProcessorPhases.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/weakProcessorPhases.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -23,11 +23,8 @@
  */
 
 #include "precompiled.hpp"
-#include "classfile/stringTable.hpp"
-#include "classfile/systemDictionary.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "gc/shared/weakProcessorPhases.hpp"
-#include "prims/resolvedMethodTable.hpp"
-#include "runtime/jniHandles.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/macros.hpp"
 
@@ -39,53 +36,84 @@
 #include "prims/jvmtiExport.hpp"
 #endif // INCLUDE_JVMTI
 
-WeakProcessorPhases::Phase WeakProcessorPhases::phase(uint value) {
-  assert(value < phase_count, "Invalid phase value %u", value);
-  return static_cast<Phase>(value);
+// serial_phase_count is 0 if JFR and JVMTI are both not built,
+// requiring some code to be careful to avoid tautological checks
+// that some compilers warn about.
+
+#define HAVE_SERIAL_PHASES (INCLUDE_JVMTI || INCLUDE_JFR)
+
+WeakProcessorPhases::Phase WeakProcessorPhases::serial_phase(uint value) {
+#if HAVE_SERIAL_PHASES
+  assert(value < serial_phase_count, "Invalid serial phase value %u", value);
+  return static_cast<Phase>(value + serial_phase_start);
+#else
+  STATIC_ASSERT(serial_phase_count == 0);
+  fatal("invalid serial phase value %u", value);
+  return static_cast<Phase>(serial_phase_start);
+#endif // HAVE_SERIAL_PHASES
 }
 
-uint WeakProcessorPhases::index(Phase phase) {
-  uint value = static_cast<uint>(phase);
-  assert(value < phase_count, "Invalid phase %u", value);
-  return value;
+WeakProcessorPhases::Phase WeakProcessorPhases::oopstorage_phase(uint value) {
+  assert(value < oopstorage_phase_count, "Invalid oopstorage phase value %u", value);
+  return static_cast<Phase>(value + oopstorage_phase_start);
+}
+
+static uint raw_phase_index(WeakProcessorPhases::Phase phase) {
+  return static_cast<uint>(phase);
 }
 
 uint WeakProcessorPhases::serial_index(Phase phase) {
-  assert(is_serial(phase), "not serial phase %u", index(phase));
-  return index(phase) - serial_phase_start;
+  assert(is_serial(phase), "not serial phase %u", raw_phase_index(phase));
+  return raw_phase_index(phase) - serial_phase_start;
 }
 
-uint WeakProcessorPhases::oop_storage_index(Phase phase) {
-  assert(is_oop_storage(phase), "not oop storage phase %u", index(phase));
-  return index(phase) - oop_storage_phase_start;
+uint WeakProcessorPhases::oopstorage_index(Phase phase) {
+  assert(is_oopstorage(phase), "not oopstorage phase %u", raw_phase_index(phase));
+  return raw_phase_index(phase) - oopstorage_phase_start;
+}
+
+static bool is_phase(WeakProcessorPhases::Phase phase, uint start, uint count) {
+  return (raw_phase_index(phase) - start) < count;
 }
 
 bool WeakProcessorPhases::is_serial(Phase phase) {
-  // serial_phase_count is 0 if JFR and JVMTI are both not built,
-  // making this check with unsigned lhs redundant
-#if INCLUDE_JVMTI || INCLUDE_JFR
-  return (index(phase) - serial_phase_start) < serial_phase_count;
+#if HAVE_SERIAL_PHASES
+  return is_phase(phase, serial_phase_start, serial_phase_count);
 #else
   STATIC_ASSERT(serial_phase_count == 0);
   return false;
-#endif
+#endif // HAVE_SERIAL_PHASES
+}
+
+bool WeakProcessorPhases::is_oopstorage(Phase phase) {
+  return is_phase(phase, oopstorage_phase_start, oopstorage_phase_count);
 }
 
-bool WeakProcessorPhases::is_oop_storage(Phase phase) {
-  return (index(phase) - oop_storage_phase_start) < oop_storage_phase_count;
+#ifdef ASSERT
+
+void WeakProcessorPhases::Iterator::verify_nonsingular() const {
+  assert(_limit != singular_value, "precondition");
 }
 
+void WeakProcessorPhases::Iterator::verify_category_match(const Iterator& other) const {
+  verify_nonsingular();
+  assert(_limit == other._limit, "precondition");
+}
+
+void WeakProcessorPhases::Iterator::verify_dereferenceable() const {
+  verify_nonsingular();
+  assert(_index < _limit, "precondition");
+}
+
+#endif // ASSERT
+
 const char* WeakProcessorPhases::description(Phase phase) {
   switch (phase) {
   JVMTI_ONLY(case jvmti: return "JVMTI weak processing";)
   JFR_ONLY(case jfr: return "JFR weak processing";)
-  case jni: return "JNI weak processing";
-  case stringtable: return "StringTable weak processing";
-  case resolved_method_table: return "ResolvedMethodTable weak processing";
-  case vm: return "VM weak processing";
   default:
     ShouldNotReachHere();
-    return "Invalid weak processing phase";
+    return "Invalid serial weak processing phase";
   }
 }
 
@@ -98,23 +126,3 @@
     return NULL;
   }
 }
-
-OopStorage* WeakProcessorPhases::oop_storage(Phase phase) {
-  switch (phase) {
-  case jni: return JNIHandles::weak_global_handles();
-  case stringtable: return StringTable::weak_storage();
-  case resolved_method_table: return ResolvedMethodTable::weak_storage();
-  case vm: return SystemDictionary::vm_weak_oop_storage();
-  default:
-    ShouldNotReachHere();
-    return NULL;
-  }
-}
-
-bool WeakProcessorPhases::is_stringtable(Phase phase) {
-  return phase == stringtable;
-}
-
-bool WeakProcessorPhases::is_resolved_method_table(Phase phase) {
-  return phase == resolved_method_table;
-}
--- a/src/hotspot/share/gc/shared/weakProcessorPhases.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shared/weakProcessorPhases.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,6 +25,7 @@
 #ifndef SHARE_GC_SHARED_WEAKPROCESSORPHASES_HPP
 #define SHARE_GC_SHARED_WEAKPROCESSORPHASES_HPP
 
+#include "gc/shared/oopStorageSet.hpp"
 #include "memory/allocation.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
@@ -35,54 +36,117 @@
 
 class WeakProcessorPhases : AllStatic {
 public:
+  class Iterator;
+
   typedef void (*Processor)(BoolObjectClosure*, OopClosure*);
 
   enum Phase {
     // Serial phases.
-    JVMTI_ONLY(jvmti COMMA)
-    JFR_ONLY(jfr COMMA)
+    JVMTI_ONLY(jvmti JFR_ONLY(COMMA))
+    JFR_ONLY(jfr)
 
-    // OopStorage phases.
-    jni,
-    stringtable,
-    resolved_method_table,
-    vm
+    // Additional implicit phase values follow for oopstorages.
   };
 
   static const uint serial_phase_start = 0;
-  static const uint serial_phase_count = jni;
-  static const uint oop_storage_phase_start = serial_phase_count;
-  static const uint oop_storage_phase_count = (vm + 1) - oop_storage_phase_start;
-  static const uint phase_count = serial_phase_count + oop_storage_phase_count;
+  static const uint serial_phase_count = 0 JVMTI_ONLY(+ 1) JFR_ONLY(+ 1);
+  static const uint oopstorage_phase_start = serial_phase_count;
+  static const uint oopstorage_phase_count = OopStorageSet::weak_count;
+  static const uint phase_count = serial_phase_count + oopstorage_phase_count;
+
+  // Precondition: value < serial_phase_count
+  static Phase serial_phase(uint value);
 
-  static Phase phase(uint value);
-  static uint index(Phase phase);
+  // Precondition: value < oopstorage_phase_count
+  static Phase oopstorage_phase(uint value);
+
   // Indexes relative to the corresponding phase_start constant.
+  // Precondition: is_serial(phase) or is_oopstorage(phase) accordingly
   static uint serial_index(Phase phase);
-  static uint oop_storage_index(Phase phase);
+  static uint oopstorage_index(Phase phase);
 
   static bool is_serial(Phase phase);
-  static bool is_oop_storage(Phase phase);
+  static bool is_oopstorage(Phase phase);
 
+  static Iterator serial_iterator();
+  static Iterator oopstorage_iterator();
+
+  // Precondition: is_serial(phase)
   static const char* description(Phase phase);
-  static Processor processor(Phase phase); // Precondition: is_serial(phase)
-  static OopStorage* oop_storage(Phase phase); // Precondition: is_oop_storage(phase)
 
-  static bool is_stringtable(Phase phase);
-  static bool is_resolved_method_table(Phase phase);
+  // Precondition: is_serial(phase)
+  static Processor processor(Phase phase);
 };
 
 typedef WeakProcessorPhases::Phase WeakProcessorPhase;
 
-#define FOR_EACH_WEAK_PROCESSOR_PHASE(P)                                \
-  for (WeakProcessorPhase P = static_cast<WeakProcessorPhase>(0);       \
-       static_cast<uint>(P) <  WeakProcessorPhases::phase_count;        \
-       P = static_cast<WeakProcessorPhase>(static_cast<uint>(P) + 1))
+class WeakProcessorPhases::Iterator {
+  friend class WeakProcessorPhases;
+
+  uint _index;
+  uint _limit;
+
+  Iterator(uint index, uint limit) : _index(index), _limit(limit) {}
+
+  static const uint singular_value = UINT_MAX;
+  void verify_nonsingular() const NOT_DEBUG_RETURN;
+  void verify_category_match(const Iterator& other) const NOT_DEBUG_RETURN;
+  void verify_dereferenceable() const NOT_DEBUG_RETURN;
+
+public:
+  // Construct a singular iterator for later assignment.  The only valid
+  // operations are destruction and assignment.
+  Iterator() : _index(singular_value), _limit(singular_value) {}
+
+  bool is_end() const {
+    verify_nonsingular();
+    return _index == _limit;
+  }
+
+  bool operator==(const Iterator& other) const {
+    verify_category_match(other);
+    return _index == other._index;
+  }
+
+  bool operator!=(const Iterator& other) const {
+    return !operator==(other);
+  }
 
-#define FOR_EACH_WEAK_PROCESSOR_OOP_STORAGE_PHASE(P)                    \
-  for (WeakProcessorPhase P = static_cast<WeakProcessorPhase>(WeakProcessorPhases::oop_storage_phase_start); \
-       static_cast<uint>(P) < (WeakProcessorPhases::oop_storage_phase_start + \
-                               WeakProcessorPhases::oop_storage_phase_count); \
-       P = static_cast<WeakProcessorPhase>(static_cast<uint>(P) + 1))
+  Phase operator*() const {
+    verify_dereferenceable();
+    return static_cast<Phase>(_index);
+  }
+
+  // Phase doesn't have members, so no operator->().
+
+  Iterator& operator++() {
+    verify_dereferenceable();
+    ++_index;
+    return *this;
+  }
+
+  Iterator operator++(int) {
+    verify_dereferenceable();
+    return Iterator(_index++, _limit);
+  }
+
+  Iterator begin() const {
+    verify_nonsingular();
+    return *this;
+  }
+
+  Iterator end() const {
+    verify_nonsingular();
+    return Iterator(_limit, _limit);
+  }
+};
+
+inline WeakProcessorPhases::Iterator WeakProcessorPhases::serial_iterator() {
+  return Iterator(serial_phase_start, serial_phase_start + serial_phase_count);
+}
+
+inline WeakProcessorPhases::Iterator WeakProcessorPhases::oopstorage_iterator() {
+  return Iterator(oopstorage_phase_start, oopstorage_phase_start + oopstorage_phase_count);
+}
 
 #endif // SHARE_GC_SHARED_WEAKPROCESSORPHASES_HPP
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalAggressiveHeuristics.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -53,7 +53,7 @@
 }
 
 bool ShenandoahTraversalAggressiveHeuristics::is_experimental() {
-  return true;
+  return false;
 }
 
 bool ShenandoahTraversalAggressiveHeuristics::is_diagnostic() {
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -37,7 +37,7 @@
   _last_cset_select(0) {}
 
 bool ShenandoahTraversalHeuristics::is_experimental() {
-  return true;
+  return false;
 }
 
 bool ShenandoahTraversalHeuristics::is_diagnostic() {
--- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -363,7 +363,7 @@
   }
 }
 
-void ShenandoahAsserts::assert_locked_or_shenandoah_safepoint(const Monitor* lock, const char* file, int line) {
+void ShenandoahAsserts::assert_locked_or_shenandoah_safepoint(Mutex* lock, const char* file, int line) {
   if (ShenandoahSafepoint::is_at_shenandoah_safepoint()) {
     return;
   }
--- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -66,7 +66,7 @@
   static void assert_rp_isalive_not_installed(const char *file, int line);
   static void assert_rp_isalive_installed(const char *file, int line);
 
-  static void assert_locked_or_shenandoah_safepoint(const Monitor* lock, const char*file, int line);
+  static void assert_locked_or_shenandoah_safepoint(Mutex* lock, const char* file, int line);
 
 #ifdef ASSERT
 #define shenandoah_assert_in_heap(interior_loc, obj) \
--- a/src/hotspot/share/gc/shenandoah/shenandoahForwarding.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahForwarding.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,7 +26,7 @@
 
 #include "gc/shenandoah/shenandoahAsserts.hpp"
 #include "gc/shenandoah/shenandoahForwarding.hpp"
-#include "oops/markOop.inline.hpp"
+#include "oops/markWord.inline.hpp"
 #include "runtime/atomic.hpp"
 
 inline HeapWord* ShenandoahForwarding::get_forwardee_raw(oop obj) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -28,6 +28,7 @@
 #include "gc/shared/gcArguments.hpp"
 #include "gc/shared/gcTimer.hpp"
 #include "gc/shared/gcTraceTime.inline.hpp"
+#include "gc/shared/locationPrinter.inline.hpp"
 #include "gc/shared/memAllocator.hpp"
 #include "gc/shared/plab.hpp"
 
@@ -1133,6 +1134,10 @@
   return sp->block_is_obj(addr);
 }
 
+bool ShenandoahHeap::print_location(outputStream* st, void* addr) const {
+  return BlockLocationPrinter<ShenandoahHeap>::print_location(st, addr);
+}
+
 jlong ShenandoahHeap::millis_since_last_gc() {
   double v = heuristics()->time_since_last_gc() * 1000;
   assert(0 <= v && v <= max_jlong, "value should fit: %f", v);
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -536,6 +536,7 @@
   // Used for parsing heap during error printing
   HeapWord* block_start(const void* addr) const;
   bool block_is_obj(const HeapWord* addr) const;
+  bool print_location(outputStream* st, void* addr) const;
 
   // Used for native heap walkers: heap dumpers, mostly
   void object_iterate(ObjectClosure* cl);
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -71,10 +71,10 @@
 
 template <bool CONCURRENT>
 ShenandoahWeakRoots<CONCURRENT>::ShenandoahWeakRoots() :
-  _jni_roots(JNIHandles::weak_global_handles(), ShenandoahPhaseTimings::JNIWeakRoots),
-  _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
-  _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
-  _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
+  _jni_roots(OopStorageSet::jni_weak(), ShenandoahPhaseTimings::JNIWeakRoots),
+  _string_table_roots(OopStorageSet::string_table_weak(), ShenandoahPhaseTimings::StringTableRoots),
+  _resolved_method_table_roots(OopStorageSet::resolved_method_table_weak(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
+  _vm_roots(OopStorageSet::vm_weak(), ShenandoahPhaseTimings::VMWeakRoots) {
 }
 
 template <bool CONCURRENT>
@@ -87,10 +87,10 @@
 }
 
 inline ShenandoahWeakRoots<false /* concurrent */>::ShenandoahWeakRoots() :
-  _jni_roots(JNIHandles::weak_global_handles(), ShenandoahPhaseTimings::JNIWeakRoots),
-  _string_table_roots(StringTable::weak_storage(), ShenandoahPhaseTimings::StringTableRoots),
-  _resolved_method_table_roots(ResolvedMethodTable::weak_storage(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
-  _vm_roots(SystemDictionary::vm_weak_oop_storage(), ShenandoahPhaseTimings::VMWeakRoots) {
+  _jni_roots(OopStorageSet::jni_weak(), ShenandoahPhaseTimings::JNIWeakRoots),
+  _string_table_roots(OopStorageSet::string_table_weak(), ShenandoahPhaseTimings::StringTableRoots),
+  _resolved_method_table_roots(OopStorageSet::resolved_method_table_weak(), ShenandoahPhaseTimings::ResolvedMethodTableRoots),
+  _vm_roots(OopStorageSet::vm_weak(), ShenandoahPhaseTimings::VMWeakRoots) {
 }
 
 template <typename IsAliveClosure, typename KeepAliveClosure>
@@ -109,8 +109,8 @@
 
 template <bool CONCURRENT>
 ShenandoahVMRoots<CONCURRENT>::ShenandoahVMRoots() :
-  _jni_handle_roots(JNIHandles::global_handles(), ShenandoahPhaseTimings::JNIRoots),
-  _vm_global_roots(SystemDictionary::vm_global_oop_storage(), ShenandoahPhaseTimings::VMGlobalRoots) {
+  _jni_handle_roots(OopStorageSet::jni_global(), ShenandoahPhaseTimings::JNIRoots),
+  _vm_global_roots(OopStorageSet::vm_global(), ShenandoahPhaseTimings::VMGlobalRoots) {
 }
 
 template <bool CONCURRENT>
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -184,47 +184,3 @@
   ShenandoahThreadLocalData::set_worker_id(thr, ShenandoahThreadLocalData::INVALID_WORKER_ID);
 #endif
 }
-
-struct PhaseMap {
-   WeakProcessorPhases::Phase            _weak_processor_phase;
-   ShenandoahPhaseTimings::GCParPhases   _shenandoah_phase;
-};
-
-static const struct PhaseMap phase_mapping[] = {
-#if INCLUDE_JVMTI
-  {WeakProcessorPhases::jvmti,                 ShenandoahPhaseTimings::JVMTIWeakRoots},
-#endif
-#if INCLUDE_JFR
-  {WeakProcessorPhases::jfr,                   ShenandoahPhaseTimings::JFRWeakRoots},
-#endif
-  {WeakProcessorPhases::jni,                   ShenandoahPhaseTimings::JNIWeakRoots},
-  {WeakProcessorPhases::stringtable,           ShenandoahPhaseTimings::StringTableRoots},
-  {WeakProcessorPhases::resolved_method_table, ShenandoahPhaseTimings::ResolvedMethodTableRoots},
-  {WeakProcessorPhases::vm,                    ShenandoahPhaseTimings::VMWeakRoots}
-};
-
-STATIC_ASSERT(sizeof(phase_mapping) / sizeof(PhaseMap) == WeakProcessorPhases::phase_count);
-
-void ShenandoahTimingConverter::weak_processing_timing_to_shenandoah_timing(WeakProcessorPhaseTimes* weak_processing_timings,
-                                                                            ShenandoahWorkerTimings* sh_worker_times) {
-  assert(weak_processing_timings->max_threads() == weak_processing_timings->max_threads(), "Must match");
-  for (uint index = 0; index < WeakProcessorPhases::phase_count; index ++) {
-    weak_processing_phase_to_shenandoah_phase(phase_mapping[index]._weak_processor_phase,
-                                              weak_processing_timings,
-                                              phase_mapping[index]._shenandoah_phase,
-                                              sh_worker_times);
-  }
-}
-
-void ShenandoahTimingConverter::weak_processing_phase_to_shenandoah_phase(WeakProcessorPhases::Phase wpp,
-                                                                          WeakProcessorPhaseTimes* weak_processing_timings,
-                                                                          ShenandoahPhaseTimings::GCParPhases spp,
-                                                                          ShenandoahWorkerTimings* sh_worker_times) {
-  if (WeakProcessorPhases::is_serial(wpp)) {
-    sh_worker_times->record_time_secs(spp, 0, weak_processing_timings->phase_time_sec(wpp));
-  } else {
-    for (uint index = 0; index < weak_processing_timings->max_threads(); index ++) {
-      sh_worker_times->record_time_secs(spp, index, weak_processing_timings->worker_time_sec(index, wpp));
-    }
-  }
-}
--- a/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/shenandoah/shenandoahUtils.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -175,15 +175,4 @@
   }
 };
 
-class ShenandoahTimingConverter : public AllStatic {
-public:
-  static void weak_processing_timing_to_shenandoah_timing(WeakProcessorPhaseTimes* weak_processing_timings,
-                                                          ShenandoahWorkerTimings* sh_worker_times);
-private:
-  static void weak_processing_phase_to_shenandoah_phase(WeakProcessorPhases::Phase wpp,
-                                                        WeakProcessorPhaseTimes* weak_processing_timings,
-                                                        ShenandoahPhaseTimings::GCParPhases spp,
-                                                        ShenandoahWorkerTimings* sh_worker_times);
-};
-
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHUTILS_HPP
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -881,6 +881,18 @@
 
 #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,
@@ -894,7 +906,7 @@
     return false;
   }
 
-  Node* ctrl = phase->get_ctrl(node);
+  Node* ctrl = get_ctrl_normalized(phase, node);
   if (ctrl != start_ctrl) {
     // We are in a successor block - the node is ok.
     return false; // Unwind
@@ -911,7 +923,6 @@
 
   // Now all successors are outside
   // - Clone this node to both successors
-  int no_succs = node->outcnt();
   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
@@ -935,7 +946,7 @@
         new_ctrl = use->in(0);
         assert (new_ctrl != NULL, "");
       } else {
-        new_ctrl = phase->get_ctrl(use);
+        new_ctrl = get_ctrl_normalized(phase, use);
       }
 
       phase->set_ctrl(clone, new_ctrl);
@@ -990,16 +1001,12 @@
   // 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
-  int outcnt = load->outcnt();
-  uint index = 0;
-  for (int i = 0; i < outcnt; i++) {
-    if (index < load->outcnt()) {
-      Node *n = load->raw_out(index);
-      assert(!n->is_LoadBarrier(), "Sanity");
-      if (!fixup_uses_in_catch(phase, ctrl, n)) {
-        // if no successor was cloned, progress to next out.
-        index++;
-      }
+  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++;
     }
   }
 
@@ -1028,7 +1035,8 @@
     Node* load_use = load->raw_out(i);
 
     if (phase->has_ctrl(load_use)) {
-      load_use_control = phase->get_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);
     }
@@ -1209,10 +1217,10 @@
 }
 
 // Sort out the loads that are between a call ant its catch blocks
-static void process_catch_cleanup_candidate(PhaseIdealLoop* phase, LoadNode* load) {
+static void process_catch_cleanup_candidate(PhaseIdealLoop* phase, LoadNode* load, bool verify) {
   bool trace = phase->C->directive()->ZTraceLoadBarriersOption;
 
-  Node* ctrl = phase->get_ctrl(load);
+  Node* ctrl = get_ctrl_normalized(phase, load);
   if (!ctrl->is_Proj() || (ctrl->in(0) == NULL) || !ctrl->in(0)->isa_Call()) {
     return;
   }
@@ -1220,6 +1228,7 @@
   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);
@@ -1237,6 +1246,7 @@
   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);
@@ -1390,7 +1400,7 @@
 // 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) const {
+void ZBarrierSetC2::clean_catch_blocks(PhaseIdealLoop* phase, bool verify) const {
 
   Compile *C = phase->C;
   uint new_ids = C->unique();
@@ -1417,7 +1427,7 @@
       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);
+        process_catch_cleanup_candidate(phase, load, verify);
       }
     }
   }
@@ -1585,6 +1595,7 @@
   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);
 
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -207,7 +207,7 @@
 private:
   // Load barrier insertion and expansion internal
   void insert_barriers_on_unsafe(PhaseIdealLoop* phase) const;
-  void clean_catch_blocks(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;
--- a/src/hotspot/share/gc/z/zCollectedHeap.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -23,11 +23,13 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/gcHeapSummary.hpp"
+#include "gc/shared/locationPrinter.hpp"
 #include "gc/shared/suspendibleThreadSet.hpp"
 #include "gc/z/zCollectedHeap.hpp"
 #include "gc/z/zGlobals.hpp"
 #include "gc/z/zHeap.inline.hpp"
 #include "gc/z/zNMethod.hpp"
+#include "gc/z/zObjArrayAllocator.hpp"
 #include "gc/z/zServiceability.hpp"
 #include "gc/z/zStat.hpp"
 #include "gc/z/zUtils.inline.hpp"
@@ -127,6 +129,15 @@
   return (HeapWord*)addr;
 }
 
+oop ZCollectedHeap::array_allocate(Klass* klass, int size, int length, bool do_zero, TRAPS) {
+  if (!do_zero) {
+    return CollectedHeap::array_allocate(klass, size, length, false /* do_zero */, THREAD);
+  }
+
+  ZObjArrayAllocator allocator(klass, size, length, THREAD);
+  return allocator.allocate();
+}
+
 HeapWord* ZCollectedHeap::mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded) {
   const size_t size_in_bytes = ZUtils::words_to_bytes(align_object_size(size));
   return (HeapWord*)_heap.alloc_object(size_in_bytes);
@@ -239,14 +250,6 @@
   _heap.object_iterate(cl, true /* visit_weaks */);
 }
 
-HeapWord* ZCollectedHeap::block_start(const void* addr) const {
-  return (HeapWord*)_heap.block_start((uintptr_t)addr);
-}
-
-bool ZCollectedHeap::block_is_obj(const HeapWord* addr) const {
-  return _heap.block_is_obj((uintptr_t)addr);
-}
-
 void ZCollectedHeap::register_nmethod(nmethod* nm) {
   ZNMethod::register_nmethod(nm);
 }
@@ -346,6 +349,16 @@
   // Does nothing
 }
 
+bool ZCollectedHeap::print_location(outputStream* st, void* addr) const {
+  if (LocationPrinter::is_valid_obj(addr)) {
+    st->print(INTPTR_FORMAT " is a %s oop: ", p2i(addr),
+              ZAddress::is_good(reinterpret_cast<uintptr_t>(addr)) ? "good" : "bad");
+    cast_to_oop(addr)->print_on(st);
+    return true;
+  }
+  return false;
+}
+
 void ZCollectedHeap::verify(VerifyOption option /* ignored */) {
   _heap.verify();
 }
--- a/src/hotspot/share/gc/z/zCollectedHeap.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -75,6 +75,7 @@
 
   virtual uint32_t hash_oop(oop obj) const;
 
+  virtual oop array_allocate(Klass* klass, int size, int length, bool do_zero, TRAPS);
   virtual HeapWord* mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded);
   virtual MetaWord* satisfy_failed_metadata_allocation(ClassLoaderData* loader_data,
                                                        size_t size,
@@ -99,9 +100,6 @@
   virtual void object_iterate(ObjectClosure* cl);
   virtual void safe_object_iterate(ObjectClosure* cl);
 
-  virtual HeapWord* block_start(const void* addr) const;
-  virtual bool block_is_obj(const HeapWord* addr) const;
-
   virtual void register_nmethod(nmethod* nm);
   virtual void unregister_nmethod(nmethod* nm);
   virtual void flush_nmethod(nmethod* nm);
@@ -123,6 +121,7 @@
   virtual void print_extended_on(outputStream* st) const;
   virtual void print_gc_threads_on(outputStream* st) const;
   virtual void print_tracing_info() const;
+  virtual bool print_location(outputStream* st, void* addr) const;
 
   virtual void prepare_for_verify();
   virtual void verify(VerifyOption option /* ignored */);
--- a/src/hotspot/share/gc/z/zHeap.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zHeap.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -64,7 +64,7 @@
 
 ZHeap::ZHeap() :
     _workers(),
-    _object_allocator(_workers.nworkers()),
+    _object_allocator(),
     _page_allocator(heap_min_size(), heap_initial_size(), heap_max_size(), heap_max_reserve_size()),
     _page_table(),
     _forwarding_table(),
@@ -194,16 +194,6 @@
   return false;
 }
 
-uintptr_t ZHeap::block_start(uintptr_t addr) const {
-  const ZPage* const page = _page_table.get(addr);
-  return page->block_start(addr);
-}
-
-bool ZHeap::block_is_obj(uintptr_t addr) const {
-  const ZPage* const page = _page_table.get(addr);
-  return page->block_is_obj(addr);
-}
-
 uint ZHeap::nconcurrent_worker_threads() const {
   return _workers.nconcurrent();
 }
--- a/src/hotspot/share/gc/z/zHeap.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zHeap.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -107,10 +107,6 @@
   bool is_in(uintptr_t addr) const;
   uint32_t hash_oop(oop obj) const;
 
-  // Block
-  uintptr_t block_start(uintptr_t addr) const;
-  bool block_is_obj(uintptr_t addr) const;
-
   // Workers
   uint nconcurrent_worker_threads() const;
   uint nconcurrent_no_boost_worker_threads() const;
--- a/src/hotspot/share/gc/z/zHeapIterator.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zHeapIterator.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -193,7 +193,7 @@
   ZStatTimerDisable disable;
 
   // Push roots to visit
-  push_roots<ZRootsIterator,                     false /* Concurrent */, false /* Weak */>();
+  push_roots<ZRootsIteratorNoInvisible,          false /* Concurrent */, false /* Weak */>();
   push_roots<ZConcurrentRootsIteratorClaimOther, true  /* Concurrent */, false /* Weak */>();
   if (VisitWeaks) {
     push_roots<ZWeakRootsIterator,           false /* Concurrent */, true  /* Weak */>();
--- a/src/hotspot/share/gc/z/zMark.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zMark.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -156,7 +156,7 @@
   ZMarkRootsTask(ZMark* mark) :
       ZTask("ZMarkRootsTask"),
       _mark(mark),
-      _roots() {}
+      _roots(true /* visit_invisible */, false /* visit_jvmti_weak_export */) {}
 
   virtual void work() {
     _roots.oops_do(&_cl);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zObjArrayAllocator.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zThreadLocalData.hpp"
+#include "gc/z/zObjArrayAllocator.hpp"
+#include "gc/z/zUtils.inline.hpp"
+#include "memory/universe.hpp"
+#include "oops/arrayKlass.hpp"
+#include "runtime/interfaceSupport.inline.hpp"
+#include "runtime/handles.hpp"
+#include "runtime/os.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// To avoid delaying safepoints, clearing of arrays is split up in segments
+// with safepoint polling inbetween. However, we can't have a not-yet-cleared
+// array of oops on the heap when we safepoint since the GC will then stumble
+// across uninitialized oops. To avoid this we let an array of oops be an
+// array of a primitive type of the same size until the clearing has completed.
+// A max segment size of 64K was chosen because benchmarking suggests that is
+// offers a good trade-off between allocation time and time-to-safepoint.
+
+static Klass* substitute_object_array_klass(Klass* klass) {
+  if (!klass->is_objArray_klass()) {
+    return klass;
+  }
+
+  Klass* const substitute_klass = Universe::longArrayKlassObj();
+  const BasicType type = ArrayKlass::cast(klass)->element_type();
+  const BasicType substitute_type = ArrayKlass::cast(substitute_klass)->element_type();
+  assert(type2aelembytes(type) == type2aelembytes(substitute_type), "Element size mismatch");
+  return substitute_klass;
+}
+
+ZObjArrayAllocator::ZObjArrayAllocator(Klass* klass, size_t word_size, int length, Thread* thread) :
+    ObjArrayAllocator(substitute_object_array_klass(klass), word_size, length, false /* do_zero */, thread),
+    _final_klass(klass) {}
+
+oop ZObjArrayAllocator::finish(HeapWord* mem) const {
+  // Set mark word and initial klass pointer
+  ObjArrayAllocator::finish(mem);
+
+  // Keep the array alive across safepoints, but make it invisible
+  // to the heap itarator until the final klass pointer has been set
+  ZThreadLocalData::set_invisible_root(_thread, (oop*)&mem);
+
+  const size_t segment_max = ZUtils::bytes_to_words(64 * K);
+  const size_t skip = arrayOopDesc::header_size(ArrayKlass::cast(_klass)->element_type());
+  size_t remaining = _word_size - skip;
+
+  while (remaining > 0) {
+    // Clear segment
+    const size_t segment = MIN2(remaining, segment_max);
+    Copy::zero_to_words(mem + (_word_size - remaining), segment);
+    remaining -= segment;
+
+    if (remaining > 0) {
+      // Safepoint
+      ThreadBlockInVM tbivm((JavaThread*)_thread);
+    }
+  }
+
+  if (_klass != _final_klass) {
+    // Set final klass pointer
+    oopDesc::release_set_klass(mem, _final_klass);
+  }
+
+  // Make the array visible to the heap iterator
+  ZThreadLocalData::clear_invisible_root(_thread);
+
+  return oop(mem);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zObjArrayAllocator.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,39 @@
+/*
+ * 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_GC_Z_ZOBJARRAYALLOCATOR_HPP
+#define SHARE_GC_Z_ZOBJARRAYALLOCATOR_HPP
+
+#include "gc/shared/memAllocator.hpp"
+
+class ZObjArrayAllocator : public ObjArrayAllocator {
+private:
+  Klass* const _final_klass;
+
+public:
+  ZObjArrayAllocator(Klass* klass, size_t word_size, int length, Thread* thread);
+
+  virtual oop finish(HeapWord* mem) const;
+};
+
+#endif // SHARE_GC_Z_ZOBJARRAYALLOCATOR_HPP
--- a/src/hotspot/share/gc/z/zObjectAllocator.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zObjectAllocator.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -41,8 +41,7 @@
 static const ZStatCounter ZCounterUndoObjectAllocationSucceeded("Memory", "Undo Object Allocation Succeeded", ZStatUnitOpsPerSecond);
 static const ZStatCounter ZCounterUndoObjectAllocationFailed("Memory", "Undo Object Allocation Failed", ZStatUnitOpsPerSecond);
 
-ZObjectAllocator::ZObjectAllocator(uint nworkers) :
-    _nworkers(nworkers),
+ZObjectAllocator::ZObjectAllocator() :
     _used(0),
     _undone(0),
     _shared_medium_page(NULL),
--- a/src/hotspot/share/gc/z/zObjectAllocator.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zObjectAllocator.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -31,7 +31,6 @@
 
 class ZObjectAllocator {
 private:
-  const uint         _nworkers;
   ZPerCPU<size_t>    _used;
   ZPerCPU<size_t>    _undone;
   ZContended<ZPage*> _shared_medium_page;
@@ -64,7 +63,7 @@
   bool undo_alloc_object(ZPage* page, uintptr_t addr, size_t size);
 
 public:
-  ZObjectAllocator(uint nworkers);
+  ZObjectAllocator();
 
   uintptr_t alloc_object(size_t size);
 
--- a/src/hotspot/share/gc/z/zPage.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zPage.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -90,9 +90,6 @@
 
   bool is_in(uintptr_t addr) const;
 
-  uintptr_t block_start(uintptr_t addr) const;
-  bool block_is_obj(uintptr_t addr) const;
-
   bool is_marked() const;
   bool is_object_live(uintptr_t addr) const;
   bool is_object_strongly_live(uintptr_t addr) const;
--- a/src/hotspot/share/gc/z/zPage.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zPage.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -177,18 +177,6 @@
   return offset >= start() && offset < top();
 }
 
-inline uintptr_t ZPage::block_start(uintptr_t addr) const {
-  if (block_is_obj(addr)) {
-    return addr;
-  } else {
-    return ZAddress::good(top());
-  }
-}
-
-inline bool ZPage::block_is_obj(uintptr_t addr) const {
-  return ZAddress::offset(addr) < top();
-}
-
 inline bool ZPage::is_marked() const {
   assert(is_relocatable(), "Invalid page state");
   return _livemap.is_marked();
--- a/src/hotspot/share/gc/z/zPhysicalMemory.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zPhysicalMemory.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,7 +25,7 @@
 #define SHARE_GC_Z_ZPHYSICALMEMORY_HPP
 
 #include "memory/allocation.hpp"
-#include OS_CPU_HEADER(gc/z/zPhysicalMemoryBacking)
+#include OS_HEADER(gc/z/zPhysicalMemoryBacking)
 
 class ZPhysicalMemorySegment : public CHeapObj<mtGC> {
 private:
--- a/src/hotspot/share/gc/z/zRelocate.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zRelocate.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -69,12 +69,12 @@
 public:
   ZRelocateRootsTask() :
       ZTask("ZRelocateRootsTask"),
-      _roots() {}
+      _roots(true /* visit_invisible */, true /* visit_jvmti_weak_export */) {}
 
   virtual void work() {
     // During relocation we need to visit the JVMTI
     // export weak roots to rehash the JVMTI tag map
-    _roots.oops_do(&_cl, true /* visit_jvmti_weak_export */);
+    _roots.oops_do(&_cl);
   }
 };
 
--- a/src/hotspot/share/gc/z/zRootsIterator.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zRootsIterator.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -30,6 +30,7 @@
 #include "gc/shared/barrierSet.hpp"
 #include "gc/shared/barrierSetNMethod.hpp"
 #include "gc/shared/oopStorageParState.inline.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "gc/shared/suspendibleThreadSet.hpp"
 #include "gc/z/zBarrierSetNMethod.hpp"
 #include "gc/z/zGlobals.hpp"
@@ -43,7 +44,6 @@
 #include "prims/jvmtiExport.hpp"
 #include "prims/resolvedMethodTable.hpp"
 #include "runtime/atomic.hpp"
-#include "runtime/jniHandles.hpp"
 #include "runtime/thread.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/synchronizer.hpp"
@@ -159,19 +159,26 @@
 class ZRootsIteratorThreadClosure : public ThreadClosure {
 private:
   ZRootsIteratorClosure* _cl;
+  const bool             _visit_invisible;
 
 public:
-  ZRootsIteratorThreadClosure(ZRootsIteratorClosure* cl) :
-      _cl(cl) {}
+  ZRootsIteratorThreadClosure(ZRootsIteratorClosure* cl, bool visit_invisible) :
+      _cl(cl),
+      _visit_invisible(visit_invisible) {}
 
   virtual void do_thread(Thread* thread) {
     ZRootsIteratorCodeBlobClosure code_cl(_cl);
     thread->oops_do(_cl, ClassUnloading ? &code_cl : NULL);
     _cl->do_thread(thread);
+    if (_visit_invisible && ZThreadLocalData::has_invisible_root(thread)) {
+      _cl->do_oop(ZThreadLocalData::invisible_root(thread));
+    }
   }
 };
 
-ZRootsIterator::ZRootsIterator() :
+ZRootsIterator::ZRootsIterator(bool visit_invisible, bool visit_jvmti_weak_export) :
+    _visit_invisible(visit_invisible),
+    _visit_jvmti_weak_export(visit_jvmti_weak_export),
     _universe(this),
     _object_synchronizer(this),
     _management(this),
@@ -239,7 +246,7 @@
 void ZRootsIterator::do_threads(ZRootsIteratorClosure* cl) {
   ZStatTimer timer(ZSubPhasePauseRootsThreads);
   ResourceMark rm;
-  ZRootsIteratorThreadClosure thread_cl(cl);
+  ZRootsIteratorThreadClosure thread_cl(cl, _visit_invisible);
   Threads::possibly_parallel_threads_do(true, &thread_cl);
 }
 
@@ -248,7 +255,7 @@
   ZNMethod::oops_do(cl);
 }
 
-void ZRootsIterator::oops_do(ZRootsIteratorClosure* cl, bool visit_jvmti_weak_export) {
+void ZRootsIterator::oops_do(ZRootsIteratorClosure* cl) {
   ZStatTimer timer(ZSubPhasePauseRoots);
   _universe.oops_do(cl);
   _object_synchronizer.oops_do(cl);
@@ -259,14 +266,14 @@
   if (!ClassUnloading) {
     _code_cache.oops_do(cl);
   }
-  if (visit_jvmti_weak_export) {
+  if (_visit_jvmti_weak_export) {
     _jvmti_weak_export.oops_do(cl);
   }
 }
 
 ZConcurrentRootsIterator::ZConcurrentRootsIterator(int cld_claim) :
-    _jni_handles_iter(JNIHandles::global_handles()),
-    _vm_handles_iter(SystemDictionary::vm_global_oop_storage()),
+    _jni_handles_iter(OopStorageSet::jni_global()),
+    _vm_handles_iter(OopStorageSet::vm_global()),
     _cld_claim(cld_claim),
     _jni_handles(this),
     _vm_handles(this),
@@ -337,10 +344,10 @@
 }
 
 ZConcurrentWeakRootsIterator::ZConcurrentWeakRootsIterator() :
-    _vm_weak_handles_iter(SystemDictionary::vm_weak_oop_storage()),
-    _jni_weak_handles_iter(JNIHandles::weak_global_handles()),
-    _string_table_iter(StringTable::weak_storage()),
-    _resolved_method_table_iter(ResolvedMethodTable::weak_storage()),
+    _vm_weak_handles_iter(OopStorageSet::vm_weak()),
+    _jni_weak_handles_iter(OopStorageSet::jni_weak()),
+    _string_table_iter(OopStorageSet::string_table_weak()),
+    _resolved_method_table_iter(OopStorageSet::resolved_method_table_weak()),
     _vm_weak_handles(this),
     _jni_weak_handles(this),
     _string_table(this),
--- a/src/hotspot/share/gc/z/zRootsIterator.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zRootsIterator.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -84,6 +84,9 @@
 
 class ZRootsIterator {
 private:
+  bool _visit_invisible;
+  bool _visit_jvmti_weak_export;
+
   void do_universe(ZRootsIteratorClosure* cl);
   void do_object_synchronizer(ZRootsIteratorClosure* cl);
   void do_management(ZRootsIteratorClosure* cl);
@@ -103,10 +106,16 @@
   ZParallelOopsDo<ZRootsIterator, &ZRootsIterator::do_code_cache>        _code_cache;
 
 public:
-  ZRootsIterator();
+  ZRootsIterator(bool visit_invisible = true, bool visit_jvmti_weak_export = false);
   ~ZRootsIterator();
 
-  void oops_do(ZRootsIteratorClosure* cl, bool visit_jvmti_weak_export = false);
+  void oops_do(ZRootsIteratorClosure* cl);
+};
+
+class ZRootsIteratorNoInvisible : public ZRootsIterator {
+public:
+  ZRootsIteratorNoInvisible() :
+      ZRootsIterator(false /* visit_invisible */, false /* visit_jvmti_weak_export */) {}
 };
 
 class ZConcurrentRootsIterator {
--- a/src/hotspot/share/gc/z/zThreadLocalData.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zThreadLocalData.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -34,10 +34,12 @@
 private:
   uintptr_t              _address_bad_mask;
   ZMarkThreadLocalStacks _stacks;
+  oop*                   _invisible_root;
 
   ZThreadLocalData() :
       _address_bad_mask(0),
-      _stacks() {}
+      _stacks(),
+      _invisible_root(NULL) {}
 
   static ZThreadLocalData* data(Thread* thread) {
     return thread->gc_data<ZThreadLocalData>();
@@ -60,6 +62,25 @@
     return &data(thread)->_stacks;
   }
 
+  static void set_invisible_root(Thread* thread, oop* root) {
+    assert(!has_invisible_root(thread), "Already set");
+    data(thread)->_invisible_root = root;
+  }
+
+  static void clear_invisible_root(Thread* thread) {
+    assert(has_invisible_root(thread), "Should be set");
+    data(thread)->_invisible_root = NULL;
+  }
+
+  static bool has_invisible_root(Thread* thread) {
+    return data(thread)->_invisible_root != NULL;
+  }
+
+  static oop* invisible_root(Thread* thread) {
+    assert(has_invisible_root(thread), "Should be set");
+    return data(thread)->_invisible_root;
+  }
+
   static ByteSize address_bad_mask_offset() {
     return Thread::gc_data_offset() + byte_offset_of(ZThreadLocalData, _address_bad_mask);
   }
--- a/src/hotspot/share/gc/z/zValue.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/gc/z/zValue.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -30,6 +30,7 @@
 #include "gc/z/zNUMA.hpp"
 #include "gc/z/zThread.hpp"
 #include "gc/z/zUtils.hpp"
+#include "runtime/globals.hpp"
 #include "utilities/align.hpp"
 
 template <typename S>
--- a/src/hotspot/share/include/cds.h	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/include/cds.h	Wed Aug 28 11:58:56 2019 -0400
@@ -36,7 +36,7 @@
 #define NUM_CDS_REGIONS 8 // this must be the same as MetaspaceShared::n_regions
 #define CDS_ARCHIVE_MAGIC 0xf00baba2
 #define CDS_DYNAMIC_ARCHIVE_MAGIC 0xf00baba8
-#define CURRENT_CDS_ARCHIVE_VERSION 6
+#define CURRENT_CDS_ARCHIVE_VERSION 7
 #define INVALID_CDS_ARCHIVE_VERSION -1
 
 struct CDSFileMapRegion {
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -771,12 +771,7 @@
   Handle h_obj(thread, elem->obj());
   assert(Universe::heap()->is_in_reserved_or_null(h_obj()),
          "must be NULL or an object");
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, elem->lock(), true, CHECK);
-  } else {
-    ObjectSynchronizer::slow_enter(h_obj, elem->lock(), CHECK);
-  }
+  ObjectSynchronizer::enter(h_obj, elem->lock(), CHECK);
   assert(Universe::heap()->is_in_reserved_or_null(elem->obj()),
          "must be NULL or an object");
 #ifdef ASSERT
@@ -796,7 +791,7 @@
   if (elem == NULL || h_obj()->is_unlocked()) {
     THROW(vmSymbols::java_lang_IllegalMonitorStateException());
   }
-  ObjectSynchronizer::slow_exit(h_obj(), elem->lock(), thread);
+  ObjectSynchronizer::exit(h_obj(), elem->lock(), thread);
   // Free entry. This must be done here, since a pending exception might be installed on
   // exit. If it is not cleared, the exception handling code will try to unlock the monitor again.
   elem->set_obj(NULL);
--- a/src/hotspot/share/jfr/leakprofiler/chains/objectSampleMarker.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jfr/leakprofiler/chains/objectSampleMarker.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,7 +26,7 @@
 #define SHARE_JFR_LEAKPROFILER_CHAINS_OBJECTSAMPLEMARKER_HPP
 
 #include "memory/allocation.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "utilities/growableArray.hpp"
 //
 // This class will save the original mark oop of a object sample object.
--- a/src/hotspot/share/jfr/leakprofiler/chains/pathToGcRootsOperation.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jfr/leakprofiler/chains/pathToGcRootsOperation.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -43,7 +43,7 @@
 #include "jfr/leakprofiler/utilities/granularTimer.hpp"
 #include "logging/log.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/safepoint.hpp"
 #include "utilities/globalDefinitions.hpp"
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/eventEmitter.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -32,7 +32,7 @@
 #include "jfr/leakprofiler/sampling/objectSampler.hpp"
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/vmThread.hpp"
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/rootResolver.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -32,7 +32,7 @@
 #include "memory/iterator.hpp"
 #include "memory/universe.hpp"
 #include "oops/klass.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.hpp"
 #include "prims/jvmtiThreadState.hpp"
 #include "runtime/frame.inline.hpp"
--- a/src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jfr/leakprofiler/utilities/saveRestore.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,7 +27,7 @@
 
 #include "memory/allocation.hpp"
 #include "memory/iterator.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "utilities/growableArray.hpp"
 
 template <typename T, typename Impl>
--- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -356,9 +356,9 @@
   }
 
 #ifdef ASSERT
-  Monitor* owned_lock = thread->owned_locks();
+  Mutex* owned_lock = thread->owned_locks();
   while (owned_lock != NULL) {
-    Monitor* next = owned_lock->next();
+    Mutex* next = owned_lock->next();
     owned_lock->unlock();
     owned_lock = next;
   }
--- a/src/hotspot/share/jvmci/jvmci.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmci.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,13 +25,13 @@
 #include "classfile/systemDictionary.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/oopStorage.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "jvmci/jvmci.hpp"
 #include "jvmci/jvmciJavaClasses.hpp"
 #include "jvmci/jvmciRuntime.hpp"
 #include "jvmci/metadataHandleBlock.hpp"
 #include "memory/universe.hpp"
 
-OopStorage* JVMCI::_object_handles = NULL;
 MetadataHandleBlock* JVMCI::_metadata_handles = NULL;
 JVMCIRuntime* JVMCI::_compiler_runtime = NULL;
 JVMCIRuntime* JVMCI::_java_runtime = NULL;
@@ -58,7 +58,6 @@
 }
 
 void JVMCI::initialize_globals() {
-  _object_handles = SystemDictionary::vm_global_oop_storage();
   _metadata_handles = MetadataHandleBlock::allocate_block();
   if (UseJVMCINativeLibrary) {
     // There are two runtimes.
@@ -70,9 +69,9 @@
   }
 }
 
-OopStorage* JVMCI::object_handles() {
-  assert(_object_handles != NULL, "Uninitialized");
-  return _object_handles;
+// Handles to objects in the Hotspot heap.
+static OopStorage* object_handles() {
+  return OopStorageSet::vm_global();
 }
 
 jobject JVMCI::make_global(const Handle& obj) {
--- a/src/hotspot/share/jvmci/jvmci.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmci.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -45,11 +45,6 @@
   friend class JVMCIEnv;
 
  private:
-  // Handles to objects in the HotSpot heap.
-  static OopStorage* _object_handles;
-
-  static OopStorage* object_handles();
-
   // Handles to Metadata objects.
   static MetadataHandleBlock* _metadata_handles;
 
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -205,7 +205,7 @@
     JVMCI_THROW_NULL(NullPointerException);
   }
   const char* cstring = JVMCIENV->as_utf8_string(name);
-  JVMFlag* flag = JVMFlag::find_flag(cstring, strlen(cstring), /* allow_locked */ true, /* return_flag */ true);
+  const JVMFlag* flag = JVMFlag::find_declared_flag(cstring);
   if (flag == NULL) {
     return c2vm;
   }
--- a/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVMInit.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -369,7 +369,7 @@
 #define COUNT_FLAG(ignore) +1
 #ifdef ASSERT
 #define CHECK_FLAG(type, name) { \
-  JVMFlag* flag = JVMFlag::find_flag(#name, strlen(#name), /*allow_locked*/ true, /* return_flag */ true); \
+  const JVMFlag* flag = JVMFlag::find_declared_flag(#name); \
   assert(flag != NULL, "No such flag named " #name); \
   assert(flag->is_##type(), "JVMFlag " #name " is not of type " #type); \
 }
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -394,17 +394,7 @@
   }
   Handle h_obj(thread, obj);
   assert(oopDesc::is_oop(h_obj()), "must be NULL or an object");
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
-  } else {
-    if (JVMCIUseFastLocking) {
-      // When using fast locking, the compiled code has already tried the fast case
-      ObjectSynchronizer::slow_enter(h_obj, lock, THREAD);
-    } else {
-      ObjectSynchronizer::fast_enter(h_obj, lock, false, THREAD);
-    }
-  }
+  ObjectSynchronizer::enter(h_obj, lock, THREAD);
   TRACE_jvmci_3("%s: exiting locking slow with obj=" INTPTR_FORMAT, thread->name(), p2i(obj));
 JRT_END
 
@@ -426,12 +416,7 @@
   }
 #endif
 
-  if (JVMCIUseFastLocking) {
-    // When using fast locking, the compiled code has already tried the fast case
-    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
-  } else {
-    ObjectSynchronizer::fast_exit(obj, lock, THREAD);
-  }
+  ObjectSynchronizer::exit(obj, lock, THREAD);
   IF_TRACE_jvmci_3 {
     char type[O_BUFLEN];
     obj->klass()->name()->as_C_string(type, O_BUFLEN);
--- a/src/hotspot/share/logging/logTag.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/logging/logTag.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -171,7 +171,7 @@
   LOG_TAG(mirror) \
   LOG_TAG(verification) \
   LOG_TAG(verify) \
-  LOG_TAG(vmmonitor) \
+  LOG_TAG(vmmutex) \
   LOG_TAG(vmoperation) \
   LOG_TAG(vmthread) \
   LOG_TAG(vtables) \
--- a/src/hotspot/share/memory/allocation.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/memory/allocation.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,12 +25,12 @@
 #ifndef SHARE_MEMORY_ALLOCATION_HPP
 #define SHARE_MEMORY_ALLOCATION_HPP
 
-#include "runtime/globals.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/macros.hpp"
 
 #include <new>
 
+class outputStream;
 class Thread;
 
 class AllocFailStrategy {
--- a/src/hotspot/share/memory/allocation.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/memory/allocation.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,6 +26,7 @@
 #define SHARE_MEMORY_ALLOCATION_INLINE_HPP
 
 #include "runtime/atomic.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/os.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/align.hpp"
--- a/src/hotspot/share/memory/filemap.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/memory/filemap.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -55,6 +55,7 @@
 #include "runtime/vm_version.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/align.hpp"
+#include "utilities/classpathStream.hpp"
 #include "utilities/defaultStream.hpp"
 #if INCLUDE_G1GC
 #include "gc/g1/g1CollectedHeap.hpp"
@@ -240,7 +241,6 @@
   // JVM version string ... changes on each build.
   get_header_version(_jvm_ident);
 
-  ClassLoaderExt::finalize_shared_paths_misc_info();
   _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
   _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
   _num_module_paths = ClassLoader::num_module_path_entries();
@@ -256,6 +256,11 @@
   _base_archive_is_default = false;
 }
 
+void SharedClassPathEntry::init_as_non_existent(const char* path, TRAPS) {
+  _type = non_existent_entry;
+  set_name(path, THREAD);
+}
+
 void SharedClassPathEntry::init(bool is_modules_image,
                                 ClassPathEntry* cpe, TRAPS) {
   assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
@@ -287,26 +292,35 @@
     FileMapInfo::fail_stop("Unable to open file %s.", cpe->name());
   }
 
-  size_t len = strlen(cpe->name()) + 1;
+  // No need to save the name of the module file, as it will be computed at run time
+  // to allow relocation of the JDK directory.
+  const char* name = is_modules_image  ? "" : cpe->name();
+  set_name(name, THREAD);
+}
+
+void SharedClassPathEntry::set_name(const char* name, TRAPS) {
+  size_t len = strlen(name) + 1;
   _name = MetadataFactory::new_array<char>(ClassLoaderData::the_null_class_loader_data(), (int)len, THREAD);
-  strcpy(_name->data(), cpe->name());
+  strcpy(_name->data(), name);
 }
 
-bool SharedClassPathEntry::validate(bool is_class_path) {
+const char* SharedClassPathEntry::name() const {
+  if (UseSharedSpaces && is_modules_image()) {
+    // In order to validate the runtime modules image file size against the archived
+    // size information, we need to obtain the runtime modules image path. The recorded
+    // dump time modules image path in the archive may be different from the runtime path
+    // if the JDK image has beed moved after generating the archive.
+    return ClassLoader::get_jrt_entry()->name();
+  } else {
+    return _name->data();
+  }
+}
+
+bool SharedClassPathEntry::validate(bool is_class_path) const {
   assert(UseSharedSpaces, "runtime only");
 
   struct stat st;
-  const char* name;
-
-  // In order to validate the runtime modules image file size against the archived
-  // size information, we need to obtain the runtime modules image path. The recorded
-  // dump time modules image path in the archive may be different from the runtime path
-  // if the JDK image has beed moved after generating the archive.
-  if (is_modules_image()) {
-    name = ClassLoader::get_jrt_entry()->name();
-  } else {
-    name = this->name();
-  }
+  const char* name = this->name();
 
   bool ok = true;
   log_info(class, path)("checking shared classpath entry: %s", name);
@@ -344,6 +358,19 @@
   return ok;
 }
 
+bool SharedClassPathEntry::check_non_existent() const {
+  assert(_type == non_existent_entry, "must be");
+  log_info(class, path)("should be non-existent: %s", name());
+  struct stat st;
+  if (os::stat(name(), &st) != 0) {
+    log_info(class, path)("ok");
+    return true; // file doesn't exist
+  } else {
+    return false;
+  }
+}
+
+
 void SharedClassPathEntry::metaspace_pointers_do(MetaspaceClosure* it) {
   it->push(&_name);
   it->push(&_manifest);
@@ -358,10 +385,11 @@
 
 void SharedPathTable::dumptime_init(ClassLoaderData* loader_data, Thread* THREAD) {
   size_t entry_size = sizeof(SharedClassPathEntry);
-  int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
-  int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
-  int num_module_path_entries = ClassLoader::num_module_path_entries();
-  int num_entries = num_boot_classpath_entries + num_app_classpath_entries + num_module_path_entries;
+  int num_entries = 0;
+  num_entries += ClassLoader::num_boot_classpath_entries();
+  num_entries += ClassLoader::num_app_classpath_entries();
+  num_entries += ClassLoader::num_module_path_entries();
+  num_entries += FileMapInfo::num_non_existent_class_paths();
   size_t bytes = entry_size * num_entries;
 
   _table = MetadataFactory::new_array<u8>(loader_data, (int)(bytes + 7 / 8), THREAD);
@@ -371,7 +399,7 @@
 void FileMapInfo::allocate_shared_path_table() {
   assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "Sanity");
 
-  Thread* THREAD = Thread::current();
+  EXCEPTION_MARK; // The following calls should never throw, but would exit VM on error.
   ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
   ClassPathEntry* jrt = ClassLoader::get_jrt_entry();
 
@@ -382,47 +410,37 @@
 
   // 1. boot class path
   int i = 0;
-  ClassPathEntry* cpe = jrt;
+  i = add_shared_classpaths(i, "boot",   jrt, THREAD);
+  i = add_shared_classpaths(i, "app",    ClassLoader::app_classpath_entries(), THREAD);
+  i = add_shared_classpaths(i, "module", ClassLoader::module_path_entries(), THREAD);
+
+  for (int x = 0; x < num_non_existent_class_paths(); x++, i++) {
+    const char* path = _non_existent_class_paths->at(x);
+    shared_path(i)->init_as_non_existent(path, THREAD);
+  }
+
+  assert(i == _shared_path_table.size(), "number of shared path entry mismatch");
+}
+
+int FileMapInfo::add_shared_classpaths(int i, const char* which, ClassPathEntry *cpe, TRAPS) {
   while (cpe != NULL) {
-    bool is_jrt = (cpe == jrt);
+    bool is_jrt = (cpe == ClassLoader::get_jrt_entry());
     const char* type = (is_jrt ? "jrt" : (cpe->is_jar_file() ? "jar" : "dir"));
-    log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
+    log_info(class, path)("add %s shared path (%s) %s", which, type, cpe->name());
     SharedClassPathEntry* ent = shared_path(i);
     ent->init(is_jrt, cpe, THREAD);
-    if (!is_jrt) {    // No need to do the modules image.
-      EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
-      update_shared_classpath(cpe, ent, THREAD);
+    if (cpe->is_jar_file()) {
+      update_jar_manifest(cpe, ent, THREAD);
     }
-    cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
-    i++;
-  }
-  assert(i == ClassLoader::num_boot_classpath_entries(),
-         "number of boot class path entry mismatch");
-
-  // 2. app class path
-  ClassPathEntry *acpe = ClassLoader::app_classpath_entries();
-  while (acpe != NULL) {
-    log_info(class, path)("add app shared path %s", acpe->name());
-    SharedClassPathEntry* ent = shared_path(i);
-    ent->init(false, acpe, THREAD);
-    EXCEPTION_MARK;
-    update_shared_classpath(acpe, ent, THREAD);
-    acpe = acpe->next();
+    if (is_jrt) {
+      cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
+    } else {
+      cpe = cpe->next();
+    }
     i++;
   }
 
-  // 3. module path
-  ClassPathEntry *mpe = ClassLoader::module_path_entries();
-  while (mpe != NULL) {
-    log_info(class, path)("add module path %s",mpe->name());
-    SharedClassPathEntry* ent = shared_path(i);
-    ent->init(false, mpe, THREAD);
-    EXCEPTION_MARK;
-    update_shared_classpath(mpe, ent, THREAD);
-    mpe = mpe->next();
-    i++;
-  }
-  assert(i == _shared_path_table.size(), "number of shared path entry mismatch");
+  return i;
 }
 
 void FileMapInfo::check_nonempty_dir_in_shared_path_table() {
@@ -452,6 +470,24 @@
   }
 }
 
+void FileMapInfo::record_non_existent_class_path_entry(const char* path) {
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
+  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);
+  }
+  _non_existent_class_paths->append(os::strdup(path));
+}
+
+int FileMapInfo::num_non_existent_class_paths() {
+  assert(DumpSharedSpaces || DynamicDumpSharedSpaces, "dump time only");
+  if (_non_existent_class_paths != NULL) {
+    return _non_existent_class_paths->length();
+  } else {
+    return 0;
+  }
+}
+
 class ManifestStream: public ResourceObj {
   private:
   u1*   _buffer_start; // Buffer bottom
@@ -500,29 +536,27 @@
   }
 };
 
-void FileMapInfo::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) {
+void FileMapInfo::update_jar_manifest(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) {
   ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
   ResourceMark rm(THREAD);
   jint manifest_size;
 
-  if (cpe->is_jar_file()) {
-    assert(ent->is_jar(), "the shared class path entry is not a JAR file");
-    char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK);
-    if (manifest != NULL) {
-      ManifestStream* stream = new ManifestStream((u1*)manifest,
-                                                  manifest_size);
-      if (stream->check_is_signed()) {
-        ent->set_is_signed();
-      } else {
-        // Copy the manifest into the shared archive
-        manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
-        Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
-                                                        manifest_size,
-                                                        THREAD);
-        char* p = (char*)(buf->data());
-        memcpy(p, manifest, manifest_size);
-        ent->set_manifest(buf);
-      }
+  assert(cpe->is_jar_file() && ent->is_jar(), "the shared class path entry is not a JAR file");
+  char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK);
+  if (manifest != NULL) {
+    ManifestStream* stream = new ManifestStream((u1*)manifest,
+                                                manifest_size);
+    if (stream->check_is_signed()) {
+      ent->set_is_signed();
+    } else {
+      // Copy the manifest into the shared archive
+      manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
+      Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
+                                                      manifest_size,
+                                                      THREAD);
+      char* p = (char*)(buf->data());
+      memcpy(p, manifest, manifest_size);
+      ent->set_manifest(buf);
     }
   }
 }
@@ -566,32 +600,16 @@
   return npaths;
 }
 
-GrowableArray<char*>* FileMapInfo::create_path_array(const char* path) {
-  GrowableArray<char*>* path_array =  new(ResourceObj::RESOURCE_AREA, mtInternal)
-      GrowableArray<char*>(10);
-  char* begin_ptr = (char*)path;
-  char* end_ptr = strchr((char*)path, os::path_separator()[0]);
-  if (end_ptr == NULL) {
-    end_ptr = strchr((char*)path, '\0');
-  }
-  while (end_ptr != NULL) {
-    if ((end_ptr - begin_ptr) > 1) {
-      struct stat st;
-      char* temp_name = NEW_RESOURCE_ARRAY(char, (size_t)(end_ptr - begin_ptr + 1));
-      strncpy(temp_name, begin_ptr, end_ptr - begin_ptr);
-      temp_name[end_ptr - begin_ptr] = '\0';
-      if (os::stat(temp_name, &st) == 0) {
-        path_array->append(temp_name);
-      }
-    }
-    if (end_ptr < (path + strlen(path))) {
-      begin_ptr = ++end_ptr;
-      end_ptr = strchr(begin_ptr, os::path_separator()[0]);
-      if (end_ptr == NULL) {
-        end_ptr = strchr(begin_ptr, '\0');
-      }
-    } else {
-      break;
+GrowableArray<const char*>* FileMapInfo::create_path_array(const char* paths) {
+  GrowableArray<const char*>* path_array =  new(ResourceObj::RESOURCE_AREA, mtInternal)
+      GrowableArray<const char*>(10);
+
+  ClasspathStream cp_stream(paths);
+  while (cp_stream.has_next()) {
+    const char* path = cp_stream.get_next();
+    struct stat st;
+    if (os::stat(path, &st) == 0) {
+      path_array->append(path);
     }
   }
   return path_array;
@@ -603,7 +621,7 @@
   return false;
 }
 
-bool FileMapInfo::check_paths(int shared_path_start_idx, int num_paths, GrowableArray<char*>* rp_array) {
+bool FileMapInfo::check_paths(int shared_path_start_idx, int num_paths, GrowableArray<const char*>* rp_array) {
   int i = 0;
   int j = shared_path_start_idx;
   bool mismatch = false;
@@ -657,7 +675,7 @@
   } else if (dp_len > 0 && rp != NULL) {
     int num;
     ResourceMark rm;
-    GrowableArray<char*>* rp_array = create_path_array(rp);
+    GrowableArray<const char*>* rp_array = create_path_array(rp);
     int rp_len = rp_array->length();
     if (rp_len >= dp_len) {
       if (relaxed_check) {
@@ -690,11 +708,21 @@
   if (shared_app_paths_len != 0 && rp_len != 0) {
     // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar.
     ResourceMark rm;
-    GrowableArray<char*>* rp_array = create_path_array(appcp);
+    GrowableArray<const char*>* rp_array = create_path_array(appcp);
     if (rp_array->length() == 0) {
       // None of the jar file specified in the runtime -cp exists.
       return fail("None of the jar file specified in the runtime -cp exists: -Djava.class.path=", appcp);
     }
+
+    // Handling of non-existent entries in the classpath: we eliminate all the non-existent
+    // entries from both the dump time classpath (ClassLoader::update_class_path_entry_list)
+    // and the runtime classpath (FileMapInfo::create_path_array), and check the remaining
+    // entries. E.g.:
+    //
+    // dump : -cp a.jar:NE1:NE2:b.jar  -> a.jar:b.jar -> recorded in archive.
+    // run 1: -cp NE3:a.jar:NE4:b.jar  -> a.jar:b.jar -> matched
+    // run 2: -cp x.jar:NE4:b.jar      -> x.jar:b.jar -> mismatched
+
     int j = _header->_app_class_paths_start_index;
     mismatch = check_paths(j, shared_app_paths_len, rp_array);
     if (mismatch) {
@@ -704,6 +732,20 @@
   return true;
 }
 
+void FileMapInfo::log_paths(const char* msg, int start_idx, int end_idx) {
+  LogTarget(Info, class, path) lt;
+  if (lt.is_enabled()) {
+    LogStream ls(lt);
+    ls.print("%s", msg);
+    const char* prefix = "";
+    for (int i = start_idx; i < end_idx; i++) {
+      ls.print("%s%s", prefix, shared_path(i)->name());
+      prefix = os::path_separator();
+    }
+    ls.cr();
+  }
+}
+
 bool FileMapInfo::validate_shared_path_table() {
   assert(UseSharedSpaces, "runtime only");
 
@@ -732,6 +774,9 @@
     }
   }
 
+  log_paths("Expecting BOOT path=", 0, _header->_app_class_paths_start_index);
+  log_paths("Expecting -Djava.class.path=", _header->_app_class_paths_start_index, _header->_app_module_paths_start_index);
+
   int module_paths_start_index = _header->_app_module_paths_start_index;
   int shared_app_paths_len = 0;
 
@@ -772,6 +817,8 @@
     }
   }
 
+  validate_non_existent_class_paths();
+
   _validating_shared_path_table = false;
 
 #if INCLUDE_JVMTI
@@ -786,6 +833,26 @@
   return true;
 }
 
+void FileMapInfo::validate_non_existent_class_paths() {
+  // All of the recorded non-existent paths came from the Class-Path: attribute from the JAR
+  // files on the app classpath. If any of these are found to exist during runtime,
+  // it will change how classes are loading for the app loader. For safety, disable
+  // loading of archived platform/app classes (currently there's no way to disable just the
+  // app classes).
+
+  assert(UseSharedSpaces, "runtime only");
+  for (int i = _header->_app_module_paths_start_index + _header->_num_module_paths;
+       i < get_number_of_shared_paths();
+       i++) {
+    SharedClassPathEntry* ent = shared_path(i);
+    if (!ent->check_non_existent()) {
+      warning("Archived non-system classes are disabled because the "
+              "file %s exists", ent->name());
+      _header->_has_platform_or_app_classes = false;
+    }
+  }
+}
+
 bool FileMapInfo::check_archive(const char* archive_name, bool is_static) {
   int fd = os::open(archive_name, O_RDONLY | O_BINARY, 0);
   if (fd < 0) {
@@ -855,9 +922,6 @@
   if (dynamic_header->_base_archive_is_default) {
     *base_archive_name = Arguments::get_default_shared_archive_path();
   } else {
-    // skip over the _paths_misc_info
-    sz = dynamic_header->_paths_misc_info_size;
-    lseek(fd, (long)sz, SEEK_CUR);
     // read the base archive name
     size_t name_size = dynamic_header->_base_archive_name_size;
     if (name_size == 0) {
@@ -948,18 +1012,7 @@
     }
   }
 
-  _file_offset = n;
-
-  size_t info_size = _header->_paths_misc_info_size;
-  _paths_misc_info = NEW_C_HEAP_ARRAY(char, info_size, mtClass);
-  n = os::read(fd, _paths_misc_info, (unsigned int)info_size);
-  if (n != info_size) {
-    fail_continue("Unable to read the shared path info header.");
-    FREE_C_HEAP_ARRAY(char, _paths_misc_info);
-    _paths_misc_info = NULL;
-    return false;
-  }
-  _file_offset += n + _header->_base_archive_name_size; // accounts for the size of _base_archive_name
+  _file_offset = n + _header->_base_archive_name_size; // accounts for the size of _base_archive_name
 
   if (is_static) {
     // just checking the last region is sufficient since the archive is written
@@ -1041,10 +1094,6 @@
 // Write the header to the file, seek to the next allocation boundary.
 
 void FileMapInfo::write_header() {
-  int info_size = ClassLoader::get_shared_paths_misc_info_size();
-
-  _header->_paths_misc_info_size = info_size;
-
   char* base_archive_name = NULL;
   if (_header->_magic == CDS_DYNAMIC_ARCHIVE_MAGIC) {
     base_archive_name = (char*)Arguments::GetSharedArchivePath();
@@ -1054,7 +1103,6 @@
 
   assert(is_file_position_aligned(), "must be");
   write_bytes(_header, _header->_header_size);
-  write_bytes(ClassLoader::get_shared_paths_misc_info(), (size_t)info_size);
   if (base_archive_name != NULL) {
     write_bytes(base_archive_name, (size_t)_header->_base_archive_name_size);
   }
@@ -1743,6 +1791,7 @@
 SharedPathTable FileMapInfo::_shared_path_table;
 bool FileMapInfo::_validating_shared_path_table = false;
 bool FileMapInfo::_memory_mapping_failed = false;
+GrowableArray<const char*>* FileMapInfo::_non_existent_class_paths = NULL;
 
 // Open the shared archive file, read and validate the header
 // information (version, boot classpath, etc.).  If initialization
@@ -1751,7 +1800,7 @@
 //
 // Validation of the archive is done in two steps:
 //
-// [1] validate_header() - done here. This checks the header, including _paths_misc_info.
+// [1] validate_header() - done here.
 // [2] validate_shared_path_table - this is done later, because the table is in the RW
 //     region of the archive, which is not mapped yet.
 bool FileMapInfo::initialize(bool is_static) {
@@ -1855,22 +1904,7 @@
 }
 
 bool FileMapInfo::validate_header(bool is_static) {
-  bool status = _header->validate();
-
-  if (status) {
-    if (!ClassLoader::check_shared_paths_misc_info(_paths_misc_info, _header->_paths_misc_info_size, is_static)) {
-      if (!PrintSharedArchiveAndExit) {
-        fail_continue("shared class paths mismatch (hint: enable -Xlog:class+path=info to diagnose the failure)");
-        status = false;
-      }
-    }
-  }
-
-  if (_paths_misc_info != NULL) {
-    FREE_C_HEAP_ARRAY(char, _paths_misc_info);
-    _paths_misc_info = NULL;
-  }
-  return status;
+  return _header->validate();
 }
 
 // Check if a given address is within one of the shared regions
@@ -1922,7 +1956,7 @@
   ClassPathEntry* ent = _classpath_entries_for_jvmti[i];
   if (ent == NULL) {
     if (i == 0) {
-      ent = ClassLoader:: get_jrt_entry();
+      ent = ClassLoader::get_jrt_entry();
       assert(ent != NULL, "must be");
     } else {
       SharedClassPathEntry* scpe = shared_path(i);
--- a/src/hotspot/share/memory/filemap.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/memory/filemap.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -49,8 +49,12 @@
     jar_entry,
     signed_jar_entry,
     dir_entry,
+    non_existent_entry,
     unknown_entry
   };
+
+  void set_name(const char* name, TRAPS);
+
 protected:
   u1     _type;
   bool   _from_class_path_attr;
@@ -61,24 +65,25 @@
 
 public:
   void init(bool is_modules_image, ClassPathEntry* cpe, TRAPS);
+  void init_as_non_existent(const char* path, TRAPS);
   void metaspace_pointers_do(MetaspaceClosure* it);
-  bool validate(bool is_class_path = true);
+  bool validate(bool is_class_path = true) const;
 
   // The _timestamp only gets set for jar files.
-  bool has_timestamp() {
+  bool has_timestamp() const {
     return _timestamp != 0;
   }
-  bool is_dir()            { return _type == dir_entry; }
-  bool is_modules_image()  { return _type == modules_image_entry; }
-  bool is_jar()            { return _type == jar_entry; }
-  bool is_signed()         { return _type == signed_jar_entry; }
-  void set_is_signed()     {
+  bool is_dir()           const { return _type == dir_entry; }
+  bool is_modules_image() const { return _type == modules_image_entry; }
+  bool is_jar()           const { return _type == jar_entry; }
+  bool is_signed()        const { return _type == signed_jar_entry; }
+  void set_is_signed() {
     _type = signed_jar_entry;
   }
   bool from_class_path_attr() { return _from_class_path_attr; }
   time_t timestamp() const { return _timestamp; }
   long   filesize()  const { return _filesize; }
-  const char* name() const { return _name->data(); }
+  const char* name() const;
   const char* manifest() const {
     return (_manifest == NULL) ? NULL : (const char*)_manifest->data();
   }
@@ -88,6 +93,7 @@
   void set_manifest(Array<u1>* manifest) {
     _manifest = manifest;
   }
+  bool check_non_existent() const;
 };
 
 struct ArchiveHeapOopmapInfo {
@@ -147,30 +153,12 @@
   // size of the base archive name including NULL terminator
   int _base_archive_name_size;
 
-  // The _paths_misc_info is a variable-size structure that records "miscellaneous"
-  // information during dumping. It is generated and validated by the
-  // SharedPathsMiscInfo class. See SharedPathsMiscInfo.hpp for
-  // detailed description.
-  //
-  // The _paths_misc_info data is stored as a byte array in the archive file header,
-  // immediately after the _header field. This information is used only when
-  // checking the validity of the archive and is deallocated after the archive is loaded.
-  //
-  // Note that the _paths_misc_info does NOT include information for JAR files
-  // that existed during dump time. Their information is stored in _shared_path_table.
-  int _paths_misc_info_size;
-
-  // The following is a table of all the class path entries that were used
-  // during dumping. At run time, we require these files to exist and have the same
-  // size/modification time, or else the archive will refuse to load.
-  //
-  // All of these entries must be JAR files. The dumping process would fail if a non-empty
-  // directory was specified in the classpaths. If an empty directory was specified
-  // it is checked by the _paths_misc_info as described above.
-  //
-  // FIXME -- if JAR files in the tail of the list were specified but not used during dumping,
-  // they should be removed from this table, to save space and to avoid spurious
-  // loading failures during runtime.
+  // The following is a table of all the boot/app/module path entries that were used
+  // during dumping. At run time, we validate these entries according to their
+  // SharedClassPathEntry::_type. See:
+  //      check_nonempty_dir_in_shared_path_table()
+  //      validate_shared_path_table()
+  //      validate_non_existent_class_paths()
   SharedPathTable _shared_path_table;
 
   jshort _app_class_paths_start_index;  // Index of first app classpath entry
@@ -232,13 +220,14 @@
   FileMapHeader * _header;
 
   const char* _full_path;
-  char* _paths_misc_info;
   char* _base_archive_name;
 
   static FileMapInfo* _current_info;
   static FileMapInfo* _dynamic_archive_info;
   static bool _heap_pointers_need_patching;
   static bool _memory_mapping_failed;
+  static GrowableArray<const char*>* _non_existent_class_paths;
+
   static bool get_base_archive_name_from_header(const char* archive_name,
                                                 int* size, char** base_archive_name);
   static bool check_archive(const char* archive_name, bool is_static);
@@ -246,6 +235,8 @@
   bool  init_from_file(int fd, bool is_static);
   static void metaspace_pointers_do(MetaspaceClosure* it);
 
+  void log_paths(const char* msg, int start_idx, int end_idx);
+
 public:
   FileMapInfo(bool is_static);
   ~FileMapInfo();
@@ -353,9 +344,13 @@
   static void stop_sharing_and_unmap(const char* msg);
 
   static void allocate_shared_path_table();
+  static int add_shared_classpaths(int i, const char* which, ClassPathEntry *cpe, TRAPS);
   static void check_nonempty_dir_in_shared_path_table();
   bool validate_shared_path_table();
-  static void update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS);
+  void validate_non_existent_class_paths();
+  static void update_jar_manifest(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS);
+  static int num_non_existent_class_paths();
+  static void record_non_existent_class_path_entry(const char* path);
 
 #if INCLUDE_JVMTI
   static ClassFileStream* open_stream_for_jvmti(InstanceKlass* ik, Handle class_loader, TRAPS);
@@ -379,11 +374,10 @@
  private:
   char* skip_first_path_entry(const char* path) NOT_CDS_RETURN_(NULL);
   int   num_paths(const char* path) NOT_CDS_RETURN_(0);
-  GrowableArray<char*>* create_path_array(const char* path) NOT_CDS_RETURN_(NULL);
+  GrowableArray<const char*>* create_path_array(const char* path) NOT_CDS_RETURN_(NULL);
   bool  fail(const char* msg, const char* name) NOT_CDS_RETURN_(false);
-  bool  check_paths(int shared_path_start_idx,
-                    int num_paths,
-                    GrowableArray<char*>* rp_array) NOT_CDS_RETURN_(false);
+  bool  check_paths(int shared_path_start_idx, int num_paths,
+                    GrowableArray<const char*>* rp_array) NOT_CDS_RETURN_(false);
   bool  validate_boot_class_paths() NOT_CDS_RETURN_(false);
   bool  validate_app_class_paths(int shared_app_paths_len) NOT_CDS_RETURN_(false);
   bool  map_heap_data(MemRegion **heap_mem, int first, int max, int* num,
--- a/src/hotspot/share/memory/heapShared.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/memory/heapShared.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -79,6 +79,7 @@
   {"java/util/ImmutableCollections$MapN",      "EMPTY_MAP"},
   {"java/util/ImmutableCollections$SetN",      "EMPTY_SET"},
   {"java/lang/module/Configuration",           "EMPTY_CONFIGURATION"},
+  {"jdk/internal/math/FDBigInteger",           "archivedCaches"},
 };
 
 const static int num_closed_archive_subgraph_entry_fields =
--- a/src/hotspot/share/memory/metaspace.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/memory/metaspace.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -29,6 +29,7 @@
 #include "memory/metaspaceChunkFreeListSummary.hpp"
 #include "memory/virtualspace.hpp"
 #include "memory/metaspace/metaspaceSizesSnapshot.hpp"
+#include "runtime/globals.hpp"
 #include "utilities/exceptions.hpp"
 
 // Metaspace
--- a/src/hotspot/share/memory/universe.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/memory/universe.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -670,8 +670,6 @@
 
   Universe::initialize_tlab();
 
-  SystemDictionary::initialize_oop_storage();
-
   Metaspace::global_initialize();
 
   // Initialize performance counters for metaspaces
--- a/src/hotspot/share/memory/virtualspace.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/memory/virtualspace.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,7 +27,7 @@
 #include "memory/resourceArea.hpp"
 #include "memory/virtualspace.hpp"
 #include "oops/compressedOops.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/os.inline.hpp"
 #include "services/memTracker.hpp"
--- a/src/hotspot/share/oops/accessBackend.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/accessBackend.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -38,6 +38,7 @@
 #include "metaprogramming/isVolatile.hpp"
 #include "oops/accessDecorators.hpp"
 #include "oops/oopsHierarchy.hpp"
+#include "runtime/globals.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/globalDefinitions.hpp"
 
--- a/src/hotspot/share/oops/annotations.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/annotations.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2017, 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
@@ -86,7 +86,7 @@
 }
 
 void Annotations::print_value_on(outputStream* st) const {
-  st->print("Anotations(" INTPTR_FORMAT ")", p2i(this));
+  st->print("Annotations(" INTPTR_FORMAT ")", p2i(this));
 }
 
 #if INCLUDE_SERVICES
--- a/src/hotspot/share/oops/annotations.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/annotations.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -100,7 +100,7 @@
  private:
   static julong count_bytes(Array<AnnotationArray*>* p);
  public:
-  const char* internal_name() const { return "{constant pool}"; }
+  const char* internal_name() const { return "{annotations}"; }
 #ifndef PRODUCT
   void print_on(outputStream* st) const;
 #endif
--- a/src/hotspot/share/oops/instanceKlass.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -946,7 +946,7 @@
     while (is_being_initialized() && !is_reentrant_initialization(jt)) {
       wait = true;
       jt->set_class_to_be_initialized(this);
-      ol.waitUninterruptibly(jt);
+      ol.wait_uninterruptibly(jt);
       jt->set_class_to_be_initialized(NULL);
     }
 
--- a/src/hotspot/share/oops/klass.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/klass.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -568,6 +568,12 @@
     // Restore class_loader_data to the null class loader data
     set_class_loader_data(loader_data);
 
+    // Workaround for suspected bug.  Make sure other threads see this assignment.
+    // This shouldn't be necessary but the compiler thread seems to be behind
+    // the times, even though this thread takes MethodCompileQueue_lock and the thread
+    // that doesn't see this value also takes that lock.
+    OrderAccess::fence();
+
     // Add to null class loader list first before creating the mirror
     // (same order as class file parsing)
     loader_data->add_class(this);
--- a/src/hotspot/share/oops/klass.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/klass.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -28,7 +28,7 @@
 #include "classfile/classLoaderData.hpp"
 #include "memory/iterator.hpp"
 #include "memory/memRegion.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/metadata.hpp"
 #include "oops/oop.hpp"
 #include "oops/oopHandle.hpp"
--- a/src/hotspot/share/oops/klass.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/klass.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,7 +27,7 @@
 
 #include "oops/compressedOops.hpp"
 #include "oops/klass.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.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");
--- a/src/hotspot/share/oops/markOop.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "oops/markOop.hpp"
-#include "runtime/thread.inline.hpp"
-#include "runtime/objectMonitor.hpp"
-
-void markWord::print_on(outputStream* st) const {
-  if (is_marked()) {  // last bits = 11
-    st->print(" marked(" INTPTR_FORMAT ")", value());
-  } else if (has_monitor()) {  // last bits = 10
-    // have to check has_monitor() before is_locked()
-    st->print(" monitor(" INTPTR_FORMAT ")=", value());
-    ObjectMonitor* mon = monitor();
-    if (mon == NULL) {
-      st->print("NULL (this should never be seen!)");
-    } else {
-      mon->print_on(st);
-    }
-  } else if (is_locked()) {  // last bits != 01 => 00
-    // thin locked
-    st->print(" locked(" INTPTR_FORMAT ")", value());
-  } else {
-    st->print(" mark(");
-    // Biased bit is 3rd rightmost bit
-    if (is_neutral()) {   // last bits = 001
-      st->print("is_neutral");
-      if (has_no_hash()) {
-        st->print(" no_hash");
-      } else {
-        st->print(" hash=" INTPTR_FORMAT, hash());
-      }
-    } else if (has_bias_pattern()) {  // last bits = 101
-      st->print("is_biased");
-      JavaThread* jt = biased_locker();
-      st->print(" biased_locker=" INTPTR_FORMAT " epoch=%d", p2i(jt), bias_epoch());
-    } else {
-      st->print("??");
-    }
-    st->print(" age=%d)", age());
-  }
-}
--- a/src/hotspot/share/oops/markOop.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,433 +0,0 @@
-/*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_OOPS_MARKOOP_HPP
-#define SHARE_OOPS_MARKOOP_HPP
-
-#include "metaprogramming/integralConstant.hpp"
-#include "metaprogramming/primitiveConversions.hpp"
-#include "oops/oopsHierarchy.hpp"
-
-// The markWord describes the header of an object.
-//
-// Bit-format of an object header (most significant first, big endian layout below):
-//
-//  32 bits:
-//  --------
-//             hash:25 ------------>| age:4    biased_lock:1 lock:2 (normal object)
-//             JavaThread*:23 epoch:2 age:4    biased_lock:1 lock:2 (biased object)
-//             size:32 ------------------------------------------>| (CMS free block)
-//             PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)
-//
-//  64 bits:
-//  --------
-//  unused:25 hash:31 -->| unused:1   age:4    biased_lock:1 lock:2 (normal object)
-//  JavaThread*:54 epoch:2 unused:1   age:4    biased_lock:1 lock:2 (biased object)
-//  PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)
-//  size:64 ----------------------------------------------------->| (CMS free block)
-//
-//  unused:25 hash:31 -->| cms_free:1 age:4    biased_lock:1 lock:2 (COOPs && normal object)
-//  JavaThread*:54 epoch:2 cms_free:1 age:4    biased_lock:1 lock:2 (COOPs && biased object)
-//  narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)
-//  unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)
-//
-//  - hash contains the identity hash value: largest value is
-//    31 bits, see os::random().  Also, 64-bit vm's require
-//    a hash value no bigger than 32 bits because they will not
-//    properly generate a mask larger than that: see library_call.cpp
-//    and c1_CodePatterns_sparc.cpp.
-//
-//  - the biased lock pattern is used to bias a lock toward a given
-//    thread. When this pattern is set in the low three bits, the lock
-//    is either biased toward a given thread or "anonymously" biased,
-//    indicating that it is possible for it to be biased. When the
-//    lock is biased toward a given thread, locking and unlocking can
-//    be performed by that thread without using atomic operations.
-//    When a lock's bias is revoked, it reverts back to the normal
-//    locking scheme described below.
-//
-//    Note that we are overloading the meaning of the "unlocked" state
-//    of the header. Because we steal a bit from the age we can
-//    guarantee that the bias pattern will never be seen for a truly
-//    unlocked object.
-//
-//    Note also that the biased state contains the age bits normally
-//    contained in the object header. Large increases in scavenge
-//    times were seen when these bits were absent and an arbitrary age
-//    assigned to all biased objects, because they tended to consume a
-//    significant fraction of the eden semispaces and were not
-//    promoted promptly, causing an increase in the amount of copying
-//    performed. The runtime system aligns all JavaThread* pointers to
-//    a very large value (currently 128 bytes (32bVM) or 256 bytes (64bVM))
-//    to make room for the age bits & the epoch bits (used in support of
-//    biased locking), and for the CMS "freeness" bit in the 64bVM (+COOPs).
-//
-//    [JavaThread* | epoch | age | 1 | 01]       lock is biased toward given thread
-//    [0           | epoch | age | 1 | 01]       lock is anonymously biased
-//
-//  - the two lock bits are used to describe three states: locked/unlocked and monitor.
-//
-//    [ptr             | 00]  locked             ptr points to real header on stack
-//    [header      | 0 | 01]  unlocked           regular object header
-//    [ptr             | 10]  monitor            inflated lock (header is wapped out)
-//    [ptr             | 11]  marked             used by markSweep to mark an object
-//                                               not valid at any other time
-//
-//    We assume that stack/thread pointers have the lowest two bits cleared.
-
-class BasicLock;
-class ObjectMonitor;
-class JavaThread;
-
-class markWord {
- private:
-  uintptr_t _value;
-
- public:
-  explicit markWord(uintptr_t value) : _value(value) {}
-
-  markWord() { /* uninitialized */}
-
-  // It is critical for performance that this class be trivially
-  // destructable, copyable, and assignable.
-
-  static markWord from_pointer(void* ptr) {
-    return markWord((uintptr_t)ptr);
-  }
-  void* to_pointer() const {
-    return (void*)_value;
-  }
-
-  bool operator==(const markWord& other) const {
-    return _value == other._value;
-  }
-  bool operator!=(const markWord& other) const {
-    return !operator==(other);
-  }
-
-  // Conversion
-  uintptr_t value() const { return _value; }
-
-  // Constants
-  enum { age_bits                 = 4,
-         lock_bits                = 2,
-         biased_lock_bits         = 1,
-         max_hash_bits            = BitsPerWord - age_bits - lock_bits - biased_lock_bits,
-         hash_bits                = max_hash_bits > 31 ? 31 : max_hash_bits,
-         cms_bits                 = LP64_ONLY(1) NOT_LP64(0),
-         epoch_bits               = 2
-  };
-
-  // The biased locking code currently requires that the age bits be
-  // contiguous to the lock bits.
-  enum { lock_shift               = 0,
-         biased_lock_shift        = lock_bits,
-         age_shift                = lock_bits + biased_lock_bits,
-         cms_shift                = age_shift + age_bits,
-         hash_shift               = cms_shift + cms_bits,
-         epoch_shift              = hash_shift
-  };
-
-  enum { lock_mask                = right_n_bits(lock_bits),
-         lock_mask_in_place       = lock_mask << lock_shift,
-         biased_lock_mask         = right_n_bits(lock_bits + biased_lock_bits),
-         biased_lock_mask_in_place= biased_lock_mask << lock_shift,
-         biased_lock_bit_in_place = 1 << biased_lock_shift,
-         age_mask                 = right_n_bits(age_bits),
-         age_mask_in_place        = age_mask << age_shift,
-         epoch_mask               = right_n_bits(epoch_bits),
-         epoch_mask_in_place      = epoch_mask << epoch_shift,
-         cms_mask                 = right_n_bits(cms_bits),
-         cms_mask_in_place        = cms_mask << cms_shift
-  };
-
-  const static uintptr_t hash_mask = right_n_bits(hash_bits);
-  const static uintptr_t hash_mask_in_place = hash_mask << hash_shift;
-
-  // Alignment of JavaThread pointers encoded in object header required by biased locking
-  enum { biased_lock_alignment    = 2 << (epoch_shift + epoch_bits)
-  };
-
-  enum { locked_value             = 0,
-         unlocked_value           = 1,
-         monitor_value            = 2,
-         marked_value             = 3,
-         biased_lock_pattern      = 5
-  };
-
-  enum { no_hash                  = 0 };  // no hash value assigned
-
-  enum { no_hash_in_place         = (address_word)no_hash << hash_shift,
-         no_lock_in_place         = unlocked_value
-  };
-
-  enum { max_age                  = age_mask };
-
-  enum { max_bias_epoch           = epoch_mask };
-
-  // Creates a markWord with all bits set to zero.
-  static markWord zero() { return markWord(uintptr_t(0)); }
-
-  // Biased Locking accessors.
-  // These must be checked by all code which calls into the
-  // ObjectSynchronizer and other code. The biasing is not understood
-  // by the lower-level CAS-based locking code, although the runtime
-  // fixes up biased locks to be compatible with it when a bias is
-  // revoked.
-  bool has_bias_pattern() const {
-    return (mask_bits(value(), biased_lock_mask_in_place) == biased_lock_pattern);
-  }
-  JavaThread* biased_locker() const {
-    assert(has_bias_pattern(), "should not call this otherwise");
-    return (JavaThread*) ((intptr_t) (mask_bits(value(), ~(biased_lock_mask_in_place | age_mask_in_place | epoch_mask_in_place))));
-  }
-  // Indicates that the mark has the bias bit set but that it has not
-  // yet been biased toward a particular thread
-  bool is_biased_anonymously() const {
-    return (has_bias_pattern() && (biased_locker() == NULL));
-  }
-  // Indicates epoch in which this bias was acquired. If the epoch
-  // changes due to too many bias revocations occurring, the biases
-  // from the previous epochs are all considered invalid.
-  int bias_epoch() const {
-    assert(has_bias_pattern(), "should not call this otherwise");
-    return (mask_bits(value(), epoch_mask_in_place) >> epoch_shift);
-  }
-  markWord set_bias_epoch(int epoch) {
-    assert(has_bias_pattern(), "should not call this otherwise");
-    assert((epoch & (~epoch_mask)) == 0, "epoch overflow");
-    return markWord(mask_bits(value(), ~epoch_mask_in_place) | (epoch << epoch_shift));
-  }
-  markWord incr_bias_epoch() {
-    return set_bias_epoch((1 + bias_epoch()) & epoch_mask);
-  }
-  // Prototype mark for initialization
-  static markWord biased_locking_prototype() {
-    return markWord( biased_lock_pattern );
-  }
-
-  // lock accessors (note that these assume lock_shift == 0)
-  bool is_locked()   const {
-    return (mask_bits(value(), lock_mask_in_place) != unlocked_value);
-  }
-  bool is_unlocked() const {
-    return (mask_bits(value(), biased_lock_mask_in_place) == unlocked_value);
-  }
-  bool is_marked()   const {
-    return (mask_bits(value(), lock_mask_in_place) == marked_value);
-  }
-  bool is_neutral()  const { return (mask_bits(value(), biased_lock_mask_in_place) == unlocked_value); }
-
-  // Special temporary state of the markWord while being inflated.
-  // Code that looks at mark outside a lock need to take this into account.
-  bool is_being_inflated() const { return (value() == 0); }
-
-  // Distinguished markword value - used when inflating over
-  // an existing stacklock.  0 indicates the markword is "BUSY".
-  // Lockword mutators that use a LD...CAS idiom should always
-  // check for and avoid overwriting a 0 value installed by some
-  // other thread.  (They should spin or block instead.  The 0 value
-  // is transient and *should* be short-lived).
-  static markWord INFLATING() { return zero(); }    // inflate-in-progress
-
-  // Should this header be preserved during GC?
-  inline bool must_be_preserved(oop obj_containing_mark) const;
-  inline bool must_be_preserved_with_bias(oop obj_containing_mark) const;
-
-  // Should this header (including its age bits) be preserved in the
-  // case of a promotion failure during scavenge?
-  // Note that we special case this situation. We want to avoid
-  // calling BiasedLocking::preserve_marks()/restore_marks() (which
-  // decrease the number of mark words that need to be preserved
-  // during GC) during each scavenge. During scavenges in which there
-  // is no promotion failure, we actually don't need to call the above
-  // routines at all, since we don't mutate and re-initialize the
-  // marks of promoted objects using init_mark(). However, during
-  // scavenges which result in promotion failure, we do re-initialize
-  // the mark words of objects, meaning that we should have called
-  // these mark word preservation routines. Currently there's no good
-  // place in which to call them in any of the scavengers (although
-  // guarded by appropriate locks we could make one), but the
-  // observation is that promotion failures are quite rare and
-  // reducing the number of mark words preserved during them isn't a
-  // high priority.
-  inline bool must_be_preserved_for_promotion_failure(oop obj_containing_mark) const;
-  inline bool must_be_preserved_with_bias_for_promotion_failure(oop obj_containing_mark) const;
-
-  // Should this header be preserved during a scavenge where CMS is
-  // the old generation?
-  // (This is basically the same body as must_be_preserved_for_promotion_failure(),
-  // but takes the Klass* as argument instead)
-  inline bool must_be_preserved_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const;
-  inline bool must_be_preserved_with_bias_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const;
-
-  // WARNING: The following routines are used EXCLUSIVELY by
-  // synchronization functions. They are not really gc safe.
-  // They must get updated if markWord layout get changed.
-  markWord set_unlocked() const {
-    return markWord(value() | unlocked_value);
-  }
-  bool has_locker() const {
-    return ((value() & lock_mask_in_place) == locked_value);
-  }
-  BasicLock* locker() const {
-    assert(has_locker(), "check");
-    return (BasicLock*) value();
-  }
-  bool has_monitor() const {
-    return ((value() & monitor_value) != 0);
-  }
-  ObjectMonitor* monitor() const {
-    assert(has_monitor(), "check");
-    // Use xor instead of &~ to provide one extra tag-bit check.
-    return (ObjectMonitor*) (value() ^ monitor_value);
-  }
-  bool has_displaced_mark_helper() const {
-    return ((value() & unlocked_value) == 0);
-  }
-  markWord displaced_mark_helper() const {
-    assert(has_displaced_mark_helper(), "check");
-    intptr_t ptr = (value() & ~monitor_value);
-    return *(markWord*)ptr;
-  }
-  void set_displaced_mark_helper(markWord m) const {
-    assert(has_displaced_mark_helper(), "check");
-    intptr_t ptr = (value() & ~monitor_value);
-    ((markWord*)ptr)->_value = m._value;
-  }
-  markWord copy_set_hash(intptr_t hash) const {
-    intptr_t tmp = value() & (~hash_mask_in_place);
-    tmp |= ((hash & hash_mask) << hash_shift);
-    return markWord(tmp);
-  }
-  // it is only used to be stored into BasicLock as the
-  // indicator that the lock is using heavyweight monitor
-  static markWord unused_mark() {
-    return markWord(marked_value);
-  }
-  // the following two functions create the markWord to be
-  // stored into object header, it encodes monitor info
-  static markWord encode(BasicLock* lock) {
-    return from_pointer(lock);
-  }
-  static markWord encode(ObjectMonitor* monitor) {
-    intptr_t tmp = (intptr_t) monitor;
-    return markWord(tmp | monitor_value);
-  }
-  static markWord encode(JavaThread* thread, uint age, int bias_epoch) {
-    intptr_t tmp = (intptr_t) thread;
-    assert(UseBiasedLocking && ((tmp & (epoch_mask_in_place | age_mask_in_place | biased_lock_mask_in_place)) == 0), "misaligned JavaThread pointer");
-    assert(age <= max_age, "age too large");
-    assert(bias_epoch <= max_bias_epoch, "bias epoch too large");
-    return markWord(tmp | (bias_epoch << epoch_shift) | (age << age_shift) | biased_lock_pattern);
-  }
-
-  // used to encode pointers during GC
-  markWord clear_lock_bits() { return markWord(value() & ~lock_mask_in_place); }
-
-  // age operations
-  markWord set_marked()   { return markWord((value() & ~lock_mask_in_place) | marked_value); }
-  markWord set_unmarked() { return markWord((value() & ~lock_mask_in_place) | unlocked_value); }
-
-  uint     age()           const { return mask_bits(value() >> age_shift, age_mask); }
-  markWord set_age(uint v) const {
-    assert((v & ~age_mask) == 0, "shouldn't overflow age field");
-    return markWord((value() & ~age_mask_in_place) | (((uintptr_t)v & age_mask) << age_shift));
-  }
-  markWord incr_age()      const { return age() == max_age ? markWord(_value) : set_age(age() + 1); }
-
-  // hash operations
-  intptr_t hash() const {
-    return mask_bits(value() >> hash_shift, hash_mask);
-  }
-
-  bool has_no_hash() const {
-    return hash() == no_hash;
-  }
-
-  // Prototype mark for initialization
-  static markWord prototype() {
-    return markWord( no_hash_in_place | no_lock_in_place );
-  }
-
-  // Helper function for restoration of unmarked mark oops during GC
-  static inline markWord prototype_for_object(oop obj);
-
-  // Debugging
-  void print_on(outputStream* st) const;
-
-  // Prepare address of oop for placement into mark
-  inline static markWord encode_pointer_as_mark(void* p) { return from_pointer(p).set_marked(); }
-
-  // Recover address of oop from encoded form used in mark
-  inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return (void*)clear_lock_bits().value(); }
-
-  // These markWords indicate cms free chunk blocks and not objects.
-  // In 64 bit, the markWord is set to distinguish them from oops.
-  // These are defined in 32 bit mode for vmStructs.
-  const static uintptr_t cms_free_chunk_pattern  = 0x1;
-
-  // Constants for the size field.
-  enum { size_shift                = cms_shift + cms_bits,
-         size_bits                 = 35    // need for compressed oops 32G
-       };
-  // These values are too big for Win64
-  const static uintptr_t size_mask = LP64_ONLY(right_n_bits(size_bits))
-                                     NOT_LP64(0);
-  const static uintptr_t size_mask_in_place =
-                                     (address_word)size_mask << size_shift;
-
-#ifdef _LP64
-  static markWord cms_free_prototype() {
-    return markWord(((intptr_t)prototype().value() & ~cms_mask_in_place) |
-                    ((cms_free_chunk_pattern & cms_mask) << cms_shift));
-  }
-  uintptr_t cms_encoding() const {
-    return mask_bits(value() >> cms_shift, cms_mask);
-  }
-  bool is_cms_free_chunk() const {
-    return is_neutral() &&
-           (cms_encoding() & cms_free_chunk_pattern) == cms_free_chunk_pattern;
-  }
-
-  size_t get_size() const       { return (size_t)(value() >> size_shift); }
-  static markWord set_size_and_free(size_t size) {
-    assert((size & ~size_mask) == 0, "shouldn't overflow size field");
-    return markWord(((intptr_t)cms_free_prototype().value() & ~size_mask_in_place) |
-                    (((intptr_t)size & size_mask) << size_shift));
-  }
-#endif // _LP64
-};
-
-// Support atomic operations.
-template<>
-struct PrimitiveConversions::Translate<markWord> : public TrueType {
-  typedef markWord Value;
-  typedef uintptr_t Decayed;
-
-  static Decayed decay(const Value& x) { return x.value(); }
-  static Value recover(Decayed x) { return Value(x); }
-};
-
-#endif // SHARE_OOPS_MARKOOP_HPP
--- a/src/hotspot/share/oops/markOop.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * 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_OOPS_MARKOOP_INLINE_HPP
-#define SHARE_OOPS_MARKOOP_INLINE_HPP
-
-#include "oops/klass.hpp"
-#include "oops/markOop.hpp"
-#include "oops/oop.inline.hpp"
-#include "runtime/globals.hpp"
-
-// Should this header be preserved during GC (when biased locking is enabled)?
-inline bool markWord::must_be_preserved_with_bias(oop obj_containing_mark) const {
-  assert(UseBiasedLocking, "unexpected");
-  if (has_bias_pattern()) {
-    // Will reset bias at end of collection
-    // Mark words of biased and currently locked objects are preserved separately
-    return false;
-  }
-  markWord prototype_header = prototype_for_object(obj_containing_mark);
-  if (prototype_header.has_bias_pattern()) {
-    // Individual instance which has its bias revoked; must return
-    // true for correctness
-    return true;
-  }
-  return (!is_unlocked() || !has_no_hash());
-}
-
-// Should this header be preserved during GC?
-inline bool markWord::must_be_preserved(oop obj_containing_mark) const {
-  if (!UseBiasedLocking)
-    return (!is_unlocked() || !has_no_hash());
-  return must_be_preserved_with_bias(obj_containing_mark);
-}
-
-// Should this header be preserved in the case of a promotion failure
-// during scavenge (when biased locking is enabled)?
-inline bool markWord::must_be_preserved_with_bias_for_promotion_failure(oop obj_containing_mark) const {
-  assert(UseBiasedLocking, "unexpected");
-  // We don't explicitly save off the mark words of biased and
-  // currently-locked objects during scavenges, so if during a
-  // promotion failure we encounter either a biased mark word or a
-  // klass which still has a biasable prototype header, we have to
-  // preserve the mark word. This results in oversaving, but promotion
-  // failures are rare, and this avoids adding more complex logic to
-  // the scavengers to call new variants of
-  // BiasedLocking::preserve_marks() / restore_marks() in the middle
-  // of a scavenge when a promotion failure has first been detected.
-  if (has_bias_pattern() ||
-      prototype_for_object(obj_containing_mark).has_bias_pattern()) {
-    return true;
-  }
-  return (!is_unlocked() || !has_no_hash());
-}
-
-// Should this header be preserved in the case of a promotion failure
-// during scavenge?
-inline bool markWord::must_be_preserved_for_promotion_failure(oop obj_containing_mark) const {
-  if (!UseBiasedLocking)
-    return (!is_unlocked() || !has_no_hash());
-  return must_be_preserved_with_bias_for_promotion_failure(obj_containing_mark);
-}
-
-
-// Same as must_be_preserved_with_bias_for_promotion_failure() except that
-// it takes a Klass* argument, instead of the object of which this is the mark word.
-inline bool markWord::must_be_preserved_with_bias_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const {
-  assert(UseBiasedLocking, "unexpected");
-  // CMS scavenges preserve mark words in similar fashion to promotion failures; see above
-  if (has_bias_pattern() ||
-      klass_of_obj_containing_mark->prototype_header().has_bias_pattern()) {
-    return true;
-  }
-  return (!is_unlocked() || !has_no_hash());
-}
-
-// Same as must_be_preserved_for_promotion_failure() except that
-// it takes a Klass* argument, instead of the object of which this is the mark word.
-inline bool markWord::must_be_preserved_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const {
-  if (!UseBiasedLocking)
-    return (!is_unlocked() || !has_no_hash());
-  return must_be_preserved_with_bias_for_cms_scavenge(klass_of_obj_containing_mark);
-}
-
-inline markWord markWord::prototype_for_object(oop obj) {
-#ifdef ASSERT
-  markWord prototype_header = obj->klass()->prototype_header();
-  assert(prototype_header == prototype() || prototype_header.has_bias_pattern(), "corrupt prototype header");
-#endif
-  return obj->klass()->prototype_header();
-}
-
-#endif // SHARE_OOPS_MARKOOP_INLINE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/oops/markWord.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "oops/markWord.hpp"
+#include "runtime/thread.inline.hpp"
+#include "runtime/objectMonitor.hpp"
+
+void markWord::print_on(outputStream* st) const {
+  if (is_marked()) {  // last bits = 11
+    st->print(" marked(" INTPTR_FORMAT ")", value());
+  } else if (has_monitor()) {  // last bits = 10
+    // have to check has_monitor() before is_locked()
+    st->print(" monitor(" INTPTR_FORMAT ")=", value());
+    ObjectMonitor* mon = monitor();
+    if (mon == NULL) {
+      st->print("NULL (this should never be seen!)");
+    } else {
+      mon->print_on(st);
+    }
+  } else if (is_locked()) {  // last bits != 01 => 00
+    // thin locked
+    st->print(" locked(" INTPTR_FORMAT ")", value());
+  } else {
+    st->print(" mark(");
+    // Biased bit is 3rd rightmost bit
+    if (is_neutral()) {   // last bits = 001
+      st->print("is_neutral");
+      if (has_no_hash()) {
+        st->print(" no_hash");
+      } else {
+        st->print(" hash=" INTPTR_FORMAT, hash());
+      }
+    } else if (has_bias_pattern()) {  // last bits = 101
+      st->print("is_biased");
+      JavaThread* jt = biased_locker();
+      st->print(" biased_locker=" INTPTR_FORMAT " epoch=%d", p2i(jt), bias_epoch());
+    } else {
+      st->print("??");
+    }
+    st->print(" age=%d)", age());
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/oops/markWord.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_OOPS_MARKWORD_HPP
+#define SHARE_OOPS_MARKWORD_HPP
+
+#include "metaprogramming/integralConstant.hpp"
+#include "metaprogramming/primitiveConversions.hpp"
+#include "oops/oopsHierarchy.hpp"
+#include "runtime/globals.hpp"
+
+// The markWord describes the header of an object.
+//
+// Bit-format of an object header (most significant first, big endian layout below):
+//
+//  32 bits:
+//  --------
+//             hash:25 ------------>| age:4    biased_lock:1 lock:2 (normal object)
+//             JavaThread*:23 epoch:2 age:4    biased_lock:1 lock:2 (biased object)
+//             size:32 ------------------------------------------>| (CMS free block)
+//             PromotedObject*:29 ---------->| promo_bits:3 ----->| (CMS promoted object)
+//
+//  64 bits:
+//  --------
+//  unused:25 hash:31 -->| unused:1   age:4    biased_lock:1 lock:2 (normal object)
+//  JavaThread*:54 epoch:2 unused:1   age:4    biased_lock:1 lock:2 (biased object)
+//  PromotedObject*:61 --------------------->| promo_bits:3 ----->| (CMS promoted object)
+//  size:64 ----------------------------------------------------->| (CMS free block)
+//
+//  unused:25 hash:31 -->| cms_free:1 age:4    biased_lock:1 lock:2 (COOPs && normal object)
+//  JavaThread*:54 epoch:2 cms_free:1 age:4    biased_lock:1 lock:2 (COOPs && biased object)
+//  narrowOop:32 unused:24 cms_free:1 unused:4 promo_bits:3 ----->| (COOPs && CMS promoted object)
+//  unused:21 size:35 -->| cms_free:1 unused:7 ------------------>| (COOPs && CMS free block)
+//
+//  - hash contains the identity hash value: largest value is
+//    31 bits, see os::random().  Also, 64-bit vm's require
+//    a hash value no bigger than 32 bits because they will not
+//    properly generate a mask larger than that: see library_call.cpp
+//    and c1_CodePatterns_sparc.cpp.
+//
+//  - the biased lock pattern is used to bias a lock toward a given
+//    thread. When this pattern is set in the low three bits, the lock
+//    is either biased toward a given thread or "anonymously" biased,
+//    indicating that it is possible for it to be biased. When the
+//    lock is biased toward a given thread, locking and unlocking can
+//    be performed by that thread without using atomic operations.
+//    When a lock's bias is revoked, it reverts back to the normal
+//    locking scheme described below.
+//
+//    Note that we are overloading the meaning of the "unlocked" state
+//    of the header. Because we steal a bit from the age we can
+//    guarantee that the bias pattern will never be seen for a truly
+//    unlocked object.
+//
+//    Note also that the biased state contains the age bits normally
+//    contained in the object header. Large increases in scavenge
+//    times were seen when these bits were absent and an arbitrary age
+//    assigned to all biased objects, because they tended to consume a
+//    significant fraction of the eden semispaces and were not
+//    promoted promptly, causing an increase in the amount of copying
+//    performed. The runtime system aligns all JavaThread* pointers to
+//    a very large value (currently 128 bytes (32bVM) or 256 bytes (64bVM))
+//    to make room for the age bits & the epoch bits (used in support of
+//    biased locking), and for the CMS "freeness" bit in the 64bVM (+COOPs).
+//
+//    [JavaThread* | epoch | age | 1 | 01]       lock is biased toward given thread
+//    [0           | epoch | age | 1 | 01]       lock is anonymously biased
+//
+//  - the two lock bits are used to describe three states: locked/unlocked and monitor.
+//
+//    [ptr             | 00]  locked             ptr points to real header on stack
+//    [header      | 0 | 01]  unlocked           regular object header
+//    [ptr             | 10]  monitor            inflated lock (header is wapped out)
+//    [ptr             | 11]  marked             used by markSweep to mark an object
+//                                               not valid at any other time
+//
+//    We assume that stack/thread pointers have the lowest two bits cleared.
+
+class BasicLock;
+class ObjectMonitor;
+class JavaThread;
+
+class markWord {
+ private:
+  uintptr_t _value;
+
+ public:
+  explicit markWord(uintptr_t value) : _value(value) {}
+
+  markWord() { /* uninitialized */}
+
+  // It is critical for performance that this class be trivially
+  // destructable, copyable, and assignable.
+
+  static markWord from_pointer(void* ptr) {
+    return markWord((uintptr_t)ptr);
+  }
+  void* to_pointer() const {
+    return (void*)_value;
+  }
+
+  bool operator==(const markWord& other) const {
+    return _value == other._value;
+  }
+  bool operator!=(const markWord& other) const {
+    return !operator==(other);
+  }
+
+  // Conversion
+  uintptr_t value() const { return _value; }
+
+  // Constants
+  enum { age_bits                 = 4,
+         lock_bits                = 2,
+         biased_lock_bits         = 1,
+         max_hash_bits            = BitsPerWord - age_bits - lock_bits - biased_lock_bits,
+         hash_bits                = max_hash_bits > 31 ? 31 : max_hash_bits,
+         cms_bits                 = LP64_ONLY(1) NOT_LP64(0),
+         epoch_bits               = 2
+  };
+
+  // The biased locking code currently requires that the age bits be
+  // contiguous to the lock bits.
+  enum { lock_shift               = 0,
+         biased_lock_shift        = lock_bits,
+         age_shift                = lock_bits + biased_lock_bits,
+         cms_shift                = age_shift + age_bits,
+         hash_shift               = cms_shift + cms_bits,
+         epoch_shift              = hash_shift
+  };
+
+  enum { lock_mask                = right_n_bits(lock_bits),
+         lock_mask_in_place       = lock_mask << lock_shift,
+         biased_lock_mask         = right_n_bits(lock_bits + biased_lock_bits),
+         biased_lock_mask_in_place= biased_lock_mask << lock_shift,
+         biased_lock_bit_in_place = 1 << biased_lock_shift,
+         age_mask                 = right_n_bits(age_bits),
+         age_mask_in_place        = age_mask << age_shift,
+         epoch_mask               = right_n_bits(epoch_bits),
+         epoch_mask_in_place      = epoch_mask << epoch_shift,
+         cms_mask                 = right_n_bits(cms_bits),
+         cms_mask_in_place        = cms_mask << cms_shift
+  };
+
+  const static uintptr_t hash_mask = right_n_bits(hash_bits);
+  const static uintptr_t hash_mask_in_place = hash_mask << hash_shift;
+
+  // Alignment of JavaThread pointers encoded in object header required by biased locking
+  enum { biased_lock_alignment    = 2 << (epoch_shift + epoch_bits)
+  };
+
+  enum { locked_value             = 0,
+         unlocked_value           = 1,
+         monitor_value            = 2,
+         marked_value             = 3,
+         biased_lock_pattern      = 5
+  };
+
+  enum { no_hash                  = 0 };  // no hash value assigned
+
+  enum { no_hash_in_place         = (address_word)no_hash << hash_shift,
+         no_lock_in_place         = unlocked_value
+  };
+
+  enum { max_age                  = age_mask };
+
+  enum { max_bias_epoch           = epoch_mask };
+
+  // Creates a markWord with all bits set to zero.
+  static markWord zero() { return markWord(uintptr_t(0)); }
+
+  // Biased Locking accessors.
+  // These must be checked by all code which calls into the
+  // ObjectSynchronizer and other code. The biasing is not understood
+  // by the lower-level CAS-based locking code, although the runtime
+  // fixes up biased locks to be compatible with it when a bias is
+  // revoked.
+  bool has_bias_pattern() const {
+    return (mask_bits(value(), biased_lock_mask_in_place) == biased_lock_pattern);
+  }
+  JavaThread* biased_locker() const {
+    assert(has_bias_pattern(), "should not call this otherwise");
+    return (JavaThread*) ((intptr_t) (mask_bits(value(), ~(biased_lock_mask_in_place | age_mask_in_place | epoch_mask_in_place))));
+  }
+  // Indicates that the mark has the bias bit set but that it has not
+  // yet been biased toward a particular thread
+  bool is_biased_anonymously() const {
+    return (has_bias_pattern() && (biased_locker() == NULL));
+  }
+  // Indicates epoch in which this bias was acquired. If the epoch
+  // changes due to too many bias revocations occurring, the biases
+  // from the previous epochs are all considered invalid.
+  int bias_epoch() const {
+    assert(has_bias_pattern(), "should not call this otherwise");
+    return (mask_bits(value(), epoch_mask_in_place) >> epoch_shift);
+  }
+  markWord set_bias_epoch(int epoch) {
+    assert(has_bias_pattern(), "should not call this otherwise");
+    assert((epoch & (~epoch_mask)) == 0, "epoch overflow");
+    return markWord(mask_bits(value(), ~epoch_mask_in_place) | (epoch << epoch_shift));
+  }
+  markWord incr_bias_epoch() {
+    return set_bias_epoch((1 + bias_epoch()) & epoch_mask);
+  }
+  // Prototype mark for initialization
+  static markWord biased_locking_prototype() {
+    return markWord( biased_lock_pattern );
+  }
+
+  // lock accessors (note that these assume lock_shift == 0)
+  bool is_locked()   const {
+    return (mask_bits(value(), lock_mask_in_place) != unlocked_value);
+  }
+  bool is_unlocked() const {
+    return (mask_bits(value(), biased_lock_mask_in_place) == unlocked_value);
+  }
+  bool is_marked()   const {
+    return (mask_bits(value(), lock_mask_in_place) == marked_value);
+  }
+  bool is_neutral()  const { return (mask_bits(value(), biased_lock_mask_in_place) == unlocked_value); }
+
+  // Special temporary state of the markWord while being inflated.
+  // Code that looks at mark outside a lock need to take this into account.
+  bool is_being_inflated() const { return (value() == 0); }
+
+  // Distinguished markword value - used when inflating over
+  // an existing stacklock.  0 indicates the markword is "BUSY".
+  // Lockword mutators that use a LD...CAS idiom should always
+  // check for and avoid overwriting a 0 value installed by some
+  // other thread.  (They should spin or block instead.  The 0 value
+  // is transient and *should* be short-lived).
+  static markWord INFLATING() { return zero(); }    // inflate-in-progress
+
+  // Should this header be preserved during GC?
+  template <typename KlassProxy>
+  inline bool must_be_preserved(KlassProxy klass) const;
+
+  // Should this header (including its age bits) be preserved in the
+  // case of a promotion failure during scavenge?
+  // Note that we special case this situation. We want to avoid
+  // calling BiasedLocking::preserve_marks()/restore_marks() (which
+  // decrease the number of mark words that need to be preserved
+  // during GC) during each scavenge. During scavenges in which there
+  // is no promotion failure, we actually don't need to call the above
+  // routines at all, since we don't mutate and re-initialize the
+  // marks of promoted objects using init_mark(). However, during
+  // scavenges which result in promotion failure, we do re-initialize
+  // the mark words of objects, meaning that we should have called
+  // these mark word preservation routines. Currently there's no good
+  // place in which to call them in any of the scavengers (although
+  // guarded by appropriate locks we could make one), but the
+  // observation is that promotion failures are quite rare and
+  // reducing the number of mark words preserved during them isn't a
+  // high priority.
+  template <typename KlassProxy>
+  inline bool must_be_preserved_for_promotion_failure(KlassProxy klass) const;
+
+  // Should this header be preserved during a scavenge where CMS is
+  // the old generation?
+  // (This is basically the same body as must_be_preserved_for_promotion_failure(),
+  // but takes the Klass* as argument instead)
+  inline bool must_be_preserved_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const;
+
+  // WARNING: The following routines are used EXCLUSIVELY by
+  // synchronization functions. They are not really gc safe.
+  // They must get updated if markWord layout get changed.
+  markWord set_unlocked() const {
+    return markWord(value() | unlocked_value);
+  }
+  bool has_locker() const {
+    return ((value() & lock_mask_in_place) == locked_value);
+  }
+  BasicLock* locker() const {
+    assert(has_locker(), "check");
+    return (BasicLock*) value();
+  }
+  bool has_monitor() const {
+    return ((value() & monitor_value) != 0);
+  }
+  ObjectMonitor* monitor() const {
+    assert(has_monitor(), "check");
+    // Use xor instead of &~ to provide one extra tag-bit check.
+    return (ObjectMonitor*) (value() ^ monitor_value);
+  }
+  bool has_displaced_mark_helper() const {
+    return ((value() & unlocked_value) == 0);
+  }
+  markWord displaced_mark_helper() const {
+    assert(has_displaced_mark_helper(), "check");
+    intptr_t ptr = (value() & ~monitor_value);
+    return *(markWord*)ptr;
+  }
+  void set_displaced_mark_helper(markWord m) const {
+    assert(has_displaced_mark_helper(), "check");
+    intptr_t ptr = (value() & ~monitor_value);
+    ((markWord*)ptr)->_value = m._value;
+  }
+  markWord copy_set_hash(intptr_t hash) const {
+    intptr_t tmp = value() & (~hash_mask_in_place);
+    tmp |= ((hash & hash_mask) << hash_shift);
+    return markWord(tmp);
+  }
+  // it is only used to be stored into BasicLock as the
+  // indicator that the lock is using heavyweight monitor
+  static markWord unused_mark() {
+    return markWord(marked_value);
+  }
+  // the following two functions create the markWord to be
+  // stored into object header, it encodes monitor info
+  static markWord encode(BasicLock* lock) {
+    return from_pointer(lock);
+  }
+  static markWord encode(ObjectMonitor* monitor) {
+    intptr_t tmp = (intptr_t) monitor;
+    return markWord(tmp | monitor_value);
+  }
+  static markWord encode(JavaThread* thread, uint age, int bias_epoch) {
+    intptr_t tmp = (intptr_t) thread;
+    assert(UseBiasedLocking && ((tmp & (epoch_mask_in_place | age_mask_in_place | biased_lock_mask_in_place)) == 0), "misaligned JavaThread pointer");
+    assert(age <= max_age, "age too large");
+    assert(bias_epoch <= max_bias_epoch, "bias epoch too large");
+    return markWord(tmp | (bias_epoch << epoch_shift) | (age << age_shift) | biased_lock_pattern);
+  }
+
+  // used to encode pointers during GC
+  markWord clear_lock_bits() { return markWord(value() & ~lock_mask_in_place); }
+
+  // age operations
+  markWord set_marked()   { return markWord((value() & ~lock_mask_in_place) | marked_value); }
+  markWord set_unmarked() { return markWord((value() & ~lock_mask_in_place) | unlocked_value); }
+
+  uint     age()           const { return mask_bits(value() >> age_shift, age_mask); }
+  markWord set_age(uint v) const {
+    assert((v & ~age_mask) == 0, "shouldn't overflow age field");
+    return markWord((value() & ~age_mask_in_place) | (((uintptr_t)v & age_mask) << age_shift));
+  }
+  markWord incr_age()      const { return age() == max_age ? markWord(_value) : set_age(age() + 1); }
+
+  // hash operations
+  intptr_t hash() const {
+    return mask_bits(value() >> hash_shift, hash_mask);
+  }
+
+  bool has_no_hash() const {
+    return hash() == no_hash;
+  }
+
+  // Prototype mark for initialization
+  static markWord prototype() {
+    return markWord( no_hash_in_place | no_lock_in_place );
+  }
+
+  // Helper function for restoration of unmarked mark oops during GC
+  static inline markWord prototype_for_klass(const Klass* klass);
+
+  // Debugging
+  void print_on(outputStream* st) const;
+
+  // Prepare address of oop for placement into mark
+  inline static markWord encode_pointer_as_mark(void* p) { return from_pointer(p).set_marked(); }
+
+  // Recover address of oop from encoded form used in mark
+  inline void* decode_pointer() { if (UseBiasedLocking && has_bias_pattern()) return NULL; return (void*)clear_lock_bits().value(); }
+
+  // These markWords indicate cms free chunk blocks and not objects.
+  // In 64 bit, the markWord is set to distinguish them from oops.
+  // These are defined in 32 bit mode for vmStructs.
+  const static uintptr_t cms_free_chunk_pattern  = 0x1;
+
+  // Constants for the size field.
+  enum { size_shift                = cms_shift + cms_bits,
+         size_bits                 = 35    // need for compressed oops 32G
+       };
+  // These values are too big for Win64
+  const static uintptr_t size_mask = LP64_ONLY(right_n_bits(size_bits))
+                                     NOT_LP64(0);
+  const static uintptr_t size_mask_in_place =
+                                     (address_word)size_mask << size_shift;
+
+#ifdef _LP64
+  static markWord cms_free_prototype() {
+    return markWord(((intptr_t)prototype().value() & ~cms_mask_in_place) |
+                    ((cms_free_chunk_pattern & cms_mask) << cms_shift));
+  }
+  uintptr_t cms_encoding() const {
+    return mask_bits(value() >> cms_shift, cms_mask);
+  }
+  bool is_cms_free_chunk() const {
+    return is_neutral() &&
+           (cms_encoding() & cms_free_chunk_pattern) == cms_free_chunk_pattern;
+  }
+
+  size_t get_size() const       { return (size_t)(value() >> size_shift); }
+  static markWord set_size_and_free(size_t size) {
+    assert((size & ~size_mask) == 0, "shouldn't overflow size field");
+    return markWord(((intptr_t)cms_free_prototype().value() & ~size_mask_in_place) |
+                    (((intptr_t)size & size_mask) << size_shift));
+  }
+#endif // _LP64
+};
+
+// Support atomic operations.
+template<>
+struct PrimitiveConversions::Translate<markWord> : public TrueType {
+  typedef markWord Value;
+  typedef uintptr_t Decayed;
+
+  static Decayed decay(const Value& x) { return x.value(); }
+  static Value recover(Decayed x) { return Value(x); }
+};
+
+#endif // SHARE_OOPS_MARKWORD_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/oops/markWord.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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_OOPS_MARKWORD_INLINE_HPP
+#define SHARE_OOPS_MARKWORD_INLINE_HPP
+
+#include "oops/klass.hpp"
+#include "oops/markWord.hpp"
+#include "runtime/globals.hpp"
+
+// Should this header be preserved during GC?
+template <typename KlassProxy>
+inline bool markWord::must_be_preserved(KlassProxy klass) const {
+  if (UseBiasedLocking) {
+    if (has_bias_pattern()) {
+      // Will reset bias at end of collection
+      // Mark words of biased and currently locked objects are preserved separately
+      return false;
+    }
+    markWord prototype_header = prototype_for_klass(klass);
+    if (prototype_header.has_bias_pattern()) {
+      // Individual instance which has its bias revoked; must return
+      // true for correctness
+      return true;
+    }
+  }
+  return (!is_unlocked() || !has_no_hash());
+}
+
+// Should this header be preserved in the case of a promotion failure during scavenge?
+template <typename KlassProxy>
+inline bool markWord::must_be_preserved_for_promotion_failure(KlassProxy klass) const {
+  if (UseBiasedLocking) {
+    // We don't explicitly save off the mark words of biased and
+    // currently-locked objects during scavenges, so if during a
+    // promotion failure we encounter either a biased mark word or a
+    // klass which still has a biasable prototype header, we have to
+    // preserve the mark word. This results in oversaving, but promotion
+    // failures are rare, and this avoids adding more complex logic to
+    // the scavengers to call new variants of
+    // BiasedLocking::preserve_marks() / restore_marks() in the middle
+    // of a scavenge when a promotion failure has first been detected.
+    if (has_bias_pattern() || prototype_for_klass(klass).has_bias_pattern()) {
+      return true;
+    }
+  }
+  return (!is_unlocked() || !has_no_hash());
+}
+
+// Same as must_be_preserved_for_promotion_failure().
+inline bool markWord::must_be_preserved_for_cms_scavenge(Klass* klass_of_obj_containing_mark) const {
+  return must_be_preserved_for_promotion_failure(klass_of_obj_containing_mark);
+}
+
+inline markWord markWord::prototype_for_klass(const Klass* klass) {
+  markWord prototype_header = klass->prototype_header();
+  assert(prototype_header == prototype() || prototype_header.has_bias_pattern(), "corrupt prototype header");
+
+  return prototype_header;
+}
+
+#endif // SHARE_OOPS_MARKWORD_INLINE_HPP
--- a/src/hotspot/share/oops/oop.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/oop.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -173,35 +173,6 @@
   }
 }
 
-bool oopDesc::is_valid(oop obj) {
-  if (!is_object_aligned(obj)) return false;
-  if ((size_t)(oopDesc*)obj < os::min_page_size()) return false;
-
-  // We need at least the mark and the klass word in the committed region.
-  if (!os::is_readable_range(obj, (oopDesc*)obj + 1)) return false;
-  if (!Universe::heap()->is_in(obj)) return false;
-
-  Klass* k = (Klass*)load_klass_raw(obj);
-  return Klass::is_valid(k);
-}
-
-oop oopDesc::oop_or_null(address addr) {
-  if (is_valid(oop(addr))) {
-    // We were just given an oop directly.
-    return oop(addr);
-  }
-
-  // Try to find addr using block_start.
-  HeapWord* p = Universe::heap()->block_start(addr);
-  if (p != NULL && Universe::heap()->block_is_obj(p)) {
-    if (!is_valid(oop(p))) return NULL;
-    return oop(p);
-  }
-
-  // If we can't find it it just may mean that heap wasn't parsable.
-  return NULL;
-}
-
 oop oopDesc::obj_field_acquire(int offset) const                      { return HeapAccess<MO_ACQUIRE>::oop_load_at(as_oop(), offset); }
 
 void oopDesc::obj_field_put_raw(int offset, oop value)                { RawAccess<>::oop_store_at(as_oop(), offset, value); }
--- a/src/hotspot/share/oops/oop.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/oop.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -28,7 +28,7 @@
 #include "memory/iterator.hpp"
 #include "memory/memRegion.hpp"
 #include "oops/access.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/metadata.hpp"
 #include "runtime/atomic.hpp"
 #include "utilities/macros.hpp"
@@ -313,6 +313,11 @@
   inline markWord displaced_mark_raw() const;
   inline void     set_displaced_mark_raw(markWord m);
 
+  // Checks if the mark word needs to be preserved
+  inline bool mark_must_be_preserved() const;
+  inline bool mark_must_be_preserved(markWord m) const;
+  inline bool mark_must_be_preserved_for_promotion_failure(markWord m) const;
+
   static bool has_klass_gap();
 
   // for code generation
@@ -326,8 +331,6 @@
   // for error reporting
   static void* load_klass_raw(oop obj);
   static void* load_oop_raw(oop obj, int offset);
-  static bool  is_valid(oop obj);
-  static oop   oop_or_null(address addr);
 };
 
 #endif // SHARE_OOPS_OOP_HPP
--- a/src/hotspot/share/oops/oop.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/oop.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -32,7 +32,7 @@
 #include "oops/arrayOop.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/klass.inline.hpp"
-#include "oops/markOop.inline.hpp"
+#include "oops/markWord.inline.hpp"
 #include "oops/oop.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/orderAccess.hpp"
@@ -82,11 +82,11 @@
 }
 
 void oopDesc::init_mark() {
-  set_mark(markWord::prototype_for_object(this));
+  set_mark(markWord::prototype_for_klass(klass()));
 }
 
 void oopDesc::init_mark_raw() {
-  set_mark_raw(markWord::prototype_for_object(this));
+  set_mark_raw(markWord::prototype_for_klass(klass()));
 }
 
 Klass* oopDesc::klass() const {
@@ -483,4 +483,34 @@
   mark_raw().set_displaced_mark_helper(m);
 }
 
+// Supports deferred calling of obj->klass().
+class DeferredObjectToKlass {
+  const oopDesc* _obj;
+
+public:
+  DeferredObjectToKlass(const oopDesc* obj) : _obj(obj) {}
+
+  // Implicitly convertible to const Klass*.
+  operator const Klass*() const {
+    return _obj->klass();
+  }
+};
+
+bool oopDesc::mark_must_be_preserved() const {
+  return mark_must_be_preserved(mark_raw());
+}
+
+bool oopDesc::mark_must_be_preserved(markWord m) const {
+  // There's a circular dependency between oop.inline.hpp and
+  // markWord.inline.hpp because markWord::must_be_preserved wants to call
+  // oopDesc::klass(). This could be solved by calling klass() here. However,
+  // not all paths inside must_be_preserved calls klass(). Defer the call until
+  // the klass is actually needed.
+  return m.must_be_preserved(DeferredObjectToKlass(this));
+}
+
+bool oopDesc::mark_must_be_preserved_for_promotion_failure(markWord m) const {
+  return m.must_be_preserved_for_promotion_failure(DeferredObjectToKlass(this));
+}
+
 #endif // SHARE_OOPS_OOP_INLINE_HPP
--- a/src/hotspot/share/oops/oopsHierarchy.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/oopsHierarchy.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -73,7 +73,7 @@
 class PromotedObject;
 class oopDesc;
 
-extern bool CheckUnhandledOops;
+extern "C" bool CheckUnhandledOops;
 
 class oop {
   oopDesc* _o;
--- a/src/hotspot/share/oops/weakHandle.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/oops/weakHandle.cpp	Wed Aug 28 11:58:56 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,26 +23,24 @@
  */
 
 #include "precompiled.hpp"
-#include "classfile/systemDictionary.hpp"
-#include "classfile/stringTable.hpp"
 #include "gc/shared/oopStorage.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "oops/access.inline.hpp"
 #include "oops/oop.hpp"
 #include "oops/weakHandle.inline.hpp"
-#include "prims/resolvedMethodTable.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/ostream.hpp"
 
 template <> OopStorage* WeakHandle<vm_class_loader_data>::get_storage() {
-  return SystemDictionary::vm_weak_oop_storage();
+  return OopStorageSet::vm_weak();
 }
 
 template <> OopStorage* WeakHandle<vm_string_table_data>::get_storage() {
-  return StringTable::weak_storage();
+  return OopStorageSet::string_table_weak();
 }
 
 template <> OopStorage* WeakHandle<vm_resolved_method_table_data>::get_storage() {
-  return ResolvedMethodTable::weak_storage();
+  return OopStorageSet::resolved_method_table_weak();
 }
 
 template <WeakHandleType T>
@@ -50,7 +48,9 @@
   assert(obj() != NULL, "no need to create weak null oop");
   oop* oop_addr = get_storage()->allocate();
   if (oop_addr == NULL) {
-    vm_exit_out_of_memory(sizeof(oop*), OOM_MALLOC_ERROR, "Unable to create new weak oop handle in OopStorage");
+    vm_exit_out_of_memory(sizeof(oop*), OOM_MALLOC_ERROR,
+                          "Unable to create new weak oop handle in OopStorage %s",
+                          get_storage()->name());
   }
   // Create WeakHandle with address returned and store oop into it.
   NativeAccess<ON_PHANTOM_OOP_REF>::oop_store(oop_addr, obj());
--- a/src/hotspot/share/opto/c2compiler.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/opto/c2compiler.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -453,6 +453,15 @@
   case vmIntrinsics::_minD:
     if (!Matcher::match_rule_supported(Op_MinD)) return false;
     break;
+  case vmIntrinsics::_writeback0:
+    if (!Matcher::match_rule_supported(Op_CacheWB)) return false;
+    break;
+  case vmIntrinsics::_writebackPreSync0:
+    if (!Matcher::match_rule_supported(Op_CacheWBPreSync)) return false;
+    break;
+  case vmIntrinsics::_writebackPostSync0:
+    if (!Matcher::match_rule_supported(Op_CacheWBPostSync)) return false;
+    break;
   case vmIntrinsics::_hashCode:
   case vmIntrinsics::_identityHashCode:
   case vmIntrinsics::_getClass:
--- a/src/hotspot/share/opto/classes.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/opto/classes.hpp	Wed Aug 28 11:58:56 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
@@ -51,6 +51,9 @@
 macro(ReverseBytesUS)
 macro(ReverseBytesS)
 macro(CProj)
+macro(CacheWB)
+macro(CacheWBPreSync)
+macro(CacheWBPostSync)
 macro(CallDynamicJava)
 macro(CallJava)
 macro(CallLeaf)
--- a/src/hotspot/share/opto/library_call.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/opto/library_call.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -253,6 +253,8 @@
   static bool klass_needs_init_guard(Node* kls);
   bool inline_unsafe_allocate();
   bool inline_unsafe_newArray(bool uninitialized);
+  bool inline_unsafe_writeback0();
+  bool inline_unsafe_writebackSync0(bool is_pre);
   bool inline_unsafe_copyMemory();
   bool inline_native_currentThread();
 
@@ -755,6 +757,9 @@
 #endif
   case vmIntrinsics::_currentTimeMillis:        return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeMillis), "currentTimeMillis");
   case vmIntrinsics::_nanoTime:                 return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeNanos), "nanoTime");
+  case vmIntrinsics::_writeback0:               return inline_unsafe_writeback0();
+  case vmIntrinsics::_writebackPreSync0:        return inline_unsafe_writebackSync0(true);
+  case vmIntrinsics::_writebackPostSync0:       return inline_unsafe_writebackSync0(false);
   case vmIntrinsics::_allocateInstance:         return inline_unsafe_allocate();
   case vmIntrinsics::_copyMemory:               return inline_unsafe_copyMemory();
   case vmIntrinsics::_getLength:                return inline_native_getLength();
@@ -2848,6 +2853,55 @@
   return !ik->is_initialized();
 }
 
+//----------------------------inline_unsafe_writeback0-------------------------
+// public native void Unsafe.writeback0(long address)
+bool LibraryCallKit::inline_unsafe_writeback0() {
+  if (!Matcher::has_match_rule(Op_CacheWB)) {
+    return false;
+  }
+#ifndef PRODUCT
+  assert(Matcher::has_match_rule(Op_CacheWBPreSync), "found match rule for CacheWB but not CacheWBPreSync");
+  assert(Matcher::has_match_rule(Op_CacheWBPostSync), "found match rule for CacheWB but not CacheWBPostSync");
+  ciSignature* sig = callee()->signature();
+  assert(sig->type_at(0)->basic_type() == T_LONG, "Unsafe_writeback0 address is long!");
+#endif
+  null_check_receiver();  // null-check, then ignore
+  Node *addr = argument(1);
+  addr = new CastX2PNode(addr);
+  addr = _gvn.transform(addr);
+  Node *flush = new CacheWBNode(control(), memory(TypeRawPtr::BOTTOM), addr);
+  flush = _gvn.transform(flush);
+  set_memory(flush, TypeRawPtr::BOTTOM);
+  return true;
+}
+
+//----------------------------inline_unsafe_writeback0-------------------------
+// public native void Unsafe.writeback0(long address)
+bool LibraryCallKit::inline_unsafe_writebackSync0(bool is_pre) {
+  if (is_pre && !Matcher::has_match_rule(Op_CacheWBPreSync)) {
+    return false;
+  }
+  if (!is_pre && !Matcher::has_match_rule(Op_CacheWBPostSync)) {
+    return false;
+  }
+#ifndef PRODUCT
+  assert(Matcher::has_match_rule(Op_CacheWB),
+         (is_pre ? "found match rule for CacheWBPreSync but not CacheWB"
+                : "found match rule for CacheWBPostSync but not CacheWB"));
+
+#endif
+  null_check_receiver();  // null-check, then ignore
+  Node *sync;
+  if (is_pre) {
+    sync = new CacheWBPreSyncNode(control(), memory(TypeRawPtr::BOTTOM));
+  } else {
+    sync = new CacheWBPostSyncNode(control(), memory(TypeRawPtr::BOTTOM));
+  }
+  sync = _gvn.transform(sync);
+  set_memory(sync, TypeRawPtr::BOTTOM);
+  return true;
+}
+
 //----------------------------inline_unsafe_allocate---------------------------
 // public native Object Unsafe.allocateInstance(Class<?> cls);
 bool LibraryCallKit::inline_unsafe_allocate() {
@@ -3976,7 +4030,7 @@
   // Get the hash value and check to see that it has been properly assigned.
   // We depend on hash_mask being at most 32 bits and avoid the use of
   // hash_mask_in_place because it could be larger than 32 bits in a 64-bit
-  // vm: see markOop.hpp.
+  // vm: see markWord.hpp.
   Node *hash_mask      = _gvn.intcon(markWord::hash_mask);
   Node *hash_shift     = _gvn.intcon(markWord::hash_shift);
   Node *hshifted_header= _gvn.transform(new URShiftXNode(header, hash_shift));
--- a/src/hotspot/share/opto/loopopts.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/opto/loopopts.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -324,7 +324,7 @@
       }
       return NULL;
     }
-    assert(m->is_Phi() || is_dominator(get_ctrl(m), n_ctrl), "m has strange control");
+    assert(n->is_Phi() || m->is_Phi() || is_dominator(get_ctrl(m), n_ctrl), "m has strange control");
   }
 
   return n_ctrl;
--- a/src/hotspot/share/opto/memnode.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/opto/memnode.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1642,6 +1642,42 @@
   }
 };
 
+// cachewb node for guaranteeing writeback of the cache line at a
+// given address to (non-volatile) RAM
+class CacheWBNode : public Node {
+public:
+  CacheWBNode(Node *ctrl, Node *mem, Node *addr) : Node(ctrl, mem, addr) {}
+  virtual int Opcode() const;
+  virtual uint ideal_reg() const { return NotAMachineReg; }
+  virtual uint match_edge(uint idx) const { return (idx == 2); }
+  virtual const TypePtr *adr_type() const { return TypePtr::BOTTOM; }
+  virtual const Type *bottom_type() const { return Type::MEMORY; }
+};
+
+// cachewb pre sync node for ensuring that writebacks are serialised
+// relative to preceding or following stores
+class CacheWBPreSyncNode : public Node {
+public:
+  CacheWBPreSyncNode(Node *ctrl, Node *mem) : Node(ctrl, mem) {}
+  virtual int Opcode() const;
+  virtual uint ideal_reg() const { return NotAMachineReg; }
+  virtual uint match_edge(uint idx) const { return false; }
+  virtual const TypePtr *adr_type() const { return TypePtr::BOTTOM; }
+  virtual const Type *bottom_type() const { return Type::MEMORY; }
+};
+
+// cachewb pre sync node for ensuring that writebacks are serialised
+// relative to preceding or following stores
+class CacheWBPostSyncNode : public Node {
+public:
+  CacheWBPostSyncNode(Node *ctrl, Node *mem) : Node(ctrl, mem) {}
+  virtual int Opcode() const;
+  virtual uint ideal_reg() const { return NotAMachineReg; }
+  virtual uint match_edge(uint idx) const { return false; }
+  virtual const TypePtr *adr_type() const { return TypePtr::BOTTOM; }
+  virtual const Type *bottom_type() const { return Type::MEMORY; }
+};
+
 //------------------------------Prefetch---------------------------------------
 
 // Allocation prefetch which may fault, TLAB size have to be adjusted.
--- a/src/hotspot/share/prims/cdsoffsets.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/cdsoffsets.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -53,7 +53,6 @@
     ADD_NEXT(_all, "FileMapHeader::_space[0]", offset_of(FileMapHeader, _space));           \
     ADD_NEXT(_all, "CDSFileMapRegion::_crc", offset_of(CDSFileMapRegion, _crc));            \
     ADD_NEXT(_all, "CDSFileMapRegion::_used", offset_of(CDSFileMapRegion, _used));          \
-    ADD_NEXT(_all, "FileMapHeader::_paths_misc_info_size", offset_of(FileMapHeader, _paths_misc_info_size)); \
     ADD_NEXT(_all, "file_header_size", sizeof(FileMapHeader));                              \
     ADD_NEXT(_all, "DynamicArchiveHeader::_base_archive_crc", offset_of(DynamicArchiveHeader, _base_archive_crc)); \
     ADD_NEXT(_all, "CDSFileMapRegion_size", sizeof(CDSFileMapRegion));
--- a/src/hotspot/share/prims/jni.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/jni.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -50,7 +50,7 @@
 #include "oops/arrayOop.inline.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/instanceOop.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
--- a/src/hotspot/share/prims/jniCheck.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/jniCheck.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1927,6 +1927,12 @@
   checked_jni_DeleteWeakGlobalRef(JNIEnv *env,
                                   jweak ref))
     functionEnterExceptionAllowed(thr);
+    IN_VM(
+      if (ref && !JNIHandles::is_weak_global_handle(ref)) {
+        ReportJNIFatalError(thr,
+             "Invalid weak global JNI handle passed to DeleteWeakGlobalRef");
+      }
+    )
     UNCHECKED()->DeleteWeakGlobalRef(env, ref);
     functionExit(thr);
 JNI_END
--- a/src/hotspot/share/prims/jvmti.xml	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmti.xml	Wed Aug 28 11:58:56 2019 -0400
@@ -341,12 +341,14 @@
    <!ELEMENT table  (tr)+>
 
    <!ELEMENT tr  (td|th)*>
+   <!ATTLIST tr class CDATA #IMPLIED>
 
    <!ELEMENT td  ANY>
    <!ATTLIST td class CDATA #IMPLIED>
 
    <!ELEMENT th  ANY>
-   <!ATTLIST th class CDATA #IMPLIED>
+   <!ATTLIST th class CDATA #IMPLIED
+                scope (col|row) #IMPLIED>
 
    <!ELEMENT ul  (li)+>
    <!ATTLIST ul type (disc|circle|square) "disc">
@@ -3523,10 +3525,15 @@
             An instance of class <code>C1</code> will have the
             following field indices:
             <blockquote><table>
+              <tr class="bgLight">
+                <th class="centered" scope="col">Field</th>
+                <th class="centered" scope="col">Index</th>
+                <th scope="col">Description</th>
+              </tr>
               <tr>
-                <td class="centered">
+                <th class="centered" scope="row">
                   a
-                </td>
+                </th>
                 <td class="centered">
                   2
                 </td>
@@ -3538,9 +3545,9 @@
                 </td>
               </tr>
               <tr>
-                <td class="centered">
+                <th class="centered" scope="row">
                   b
-                </td>
+                </th>
                 <td class="centered">
                   3
                 </td>
@@ -3554,10 +3561,15 @@
             An instance of class <code>C2</code> will have the
             following field indices:
             <blockquote><table>
+              <tr class="bgLight">
+                <th class="centered" scope="col">Field</th>
+                <th class="centered" scope="col">Index</th>
+                <th scope="col">Description</th>
+              </tr>
               <tr>
-                <td class="centered">
+                <th class="centered" scope="row">
                   a
-                </td>
+                </th>
                 <td class="centered">
                   3
                 </td>
@@ -3571,9 +3583,9 @@
                 </td>
               </tr>
               <tr>
-                <td class="centered">
+                <th class="centered" scope="row">
                   b
-                </td>
+                </th>
                 <td class="centered">
                   4
                 </td>
@@ -3582,9 +3594,9 @@
                 </td>
               </tr>
               <tr>
-                <td class="centered">
+                <th class="centered" scope="row">
                   q
-                </td>
+                </th>
                 <td class="centered">
                   5
                 </td>
@@ -3593,9 +3605,9 @@
                 </td>
               </tr>
               <tr>
-                <td class="centered">
+                <th class="centered" scope="row">
                   r
-                </td>
+                </th>
                 <td class="centered">
                   6
                 </td>
@@ -3613,10 +3625,15 @@
             The interface <code>I1</code> will have the
             following field indices:
             <blockquote><table>
+              <tr class="bgLight">
+                <th class="centered" scope="col">Field</th>
+                <th class="centered" scope="col">Index</th>
+                <th scope="col">Description</th>
+              </tr>
               <tr>
-                <td class="centered">
+                <th class="centered" scope="row">
                   x
-                </td>
+                </th>
                 <td class="centered">
                   1
                 </td>
@@ -4468,20 +4485,14 @@
         The table below summarizes this:
         <p/>
         <table>
-          <tr>
+          <tr class="bgLight">
             <th/>
-            <th>
-              Controls objects visited
-            </th>
-            <th>
-              Controls objects reported
-            </th>
-            <th>
-              Controls primitives reported
-            </th>
+            <th class="centered" scope="col">Controls objects visited</th>
+            <th class="centered" scope="col">Controls objects reported</th>
+            <th class="centered" scope="col">Controls primitives reported</th>
           </tr>
           <tr>
-            <th class="leftAligned">
+            <th scope="row">
               the
               <datalink id="jvmtiHeapVisitControl">Heap Visit Control Flags</datalink>
               returned by <functionlink id="jvmtiHeapReferenceCallback"/>
@@ -4497,7 +4508,7 @@
             </td>
           </tr>
           <tr>
-            <th class="leftAligned">
+            <th scope="row">
               <fieldlink id="array_primitive_value_callback" struct="jvmtiHeapCallbacks"/>
               in <paramlink id="callbacks"/> set
             </th>
@@ -4512,7 +4523,7 @@
             </td>
           </tr>
           <tr>
-            <th class="leftAligned">
+            <th scope="row">
               <paramlink id="heap_filter"/>
             </th>
             <td class="centered">
@@ -4526,7 +4537,7 @@
             </td>
           </tr>
           <tr>
-            <th class="leftAligned">
+            <th scope="row">
               <paramlink id="klass"/>
             </th>
             <td class="centered">
@@ -4660,20 +4671,14 @@
         <functionlink id="FollowReferences"/>):
         <p/>
         <table>
-          <tr>
+          <tr class="bgLight">
             <th/>
-            <th>
-              Controls objects visited
-            </th>
-            <th>
-              Controls objects reported
-            </th>
-            <th>
-              Controls primitives reported
-            </th>
+            <th class="centered" scope="col">Controls objects visited</th>
+            <th class="centered" scope="col">Controls objects reported</th>
+            <th class="centered" scope="col">Controls primitives reported</th>
           </tr>
           <tr>
-            <th class="leftAligned">
+            <th scope="row">
               the
               <datalink id="jvmtiHeapVisitControl">Heap Visit Control Flags</datalink>
               returned by <functionlink id="jvmtiHeapIterationCallback"/>
@@ -4689,7 +4694,7 @@
             </td>
           </tr>
           <tr>
-            <th class="leftAligned">
+            <th scope="row">
               <fieldlink id="array_primitive_value_callback" struct="jvmtiHeapCallbacks"/>
               in <paramlink id="callbacks"/> set
             </th>
@@ -4704,7 +4709,7 @@
             </td>
           </tr>
           <tr>
-            <th class="leftAligned">
+            <th scope="row">
               <paramlink id="heap_filter"/>
             </th>
             <td class="centered">
@@ -4718,7 +4723,7 @@
             </td>
           </tr>
           <tr>
-            <th class="leftAligned">
+            <th scope="row">
               <paramlink id="klass"/>
             </th>
             <td class="centered">
--- a/src/hotspot/share/prims/jvmti.xsl	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmti.xsl	Wed Aug 28 11:58:56 2019 -0400
@@ -46,22 +46,48 @@
           .rightAligned { text-align: right; }
           .bgLight { background-color: #EEEEFF; }
           .bgDark { background-color: #CCCCFF}
-          th { background-color: #EEEEFF; }
-          td.tableHeader {font-size: larger; text-align:center; }
+          th { font-weight: normal; text-align: left; }
           div.sep { height: 10px; }
           div.callbackCtnr { margin: 0 5%; }
           hr { border-width:0; color:gray; background-color:gray; }
           hr.thick { height:3px; }
           hr.thin { height:1px; }
-          table.bordered { border: 1px solid gray; border-spacing: 0; border-collapse: separate; }
-          table.bordered td, table.bordered th { padding: 3px; border: 1px solid black; }
-          table.wide { width: 100%; }
+          table.bordered, div.bordered { border: 2px solid black; border-spacing: 0; border-collapse: collapse; }
+          table.bordered td, table.bordered th, div.bordered div.divTableHead, div.bordered .divTableCell {
+            padding: 3px;
+            border: 2px solid black;
+          }
+          .wide { width: 100%; }
+          table.bordered caption, divCaption {
+            border: 2px solid black;
+            border-bottom-width: 0;
+          }
+          .captionTitle {
+            background-color: #CCCCFF;
+            font-size: larger;
+            text-align:center;
+            padding: 3px;
+          }
+          .captionDescr {
+            border-top: 2px solid black;
+            padding: 3px;
+            text-align: left;
+          }
+          div.divTable { display: table; }
+          <!-- workaround for <div> with border, display: table & width: 100% -->
+          div.wideDivTableCtnr { padding-right: 2px; }
+          div.divTableRow { display: table-row; }
+          div.divTableHead, div.divTableCell { display: table-cell; vertical-align: middle; }
+          div.divTableHead { font-weight: bold; text-align: center; }
+          table.bordered td.noPadding { padding: 0; }
+          div.withPadding { padding: 3px; }
+          div.topBorder { border-top: 2px solid black; }
         </style>
   </head>
   <body>
-    <div class="centered" role="banner">
+    <header class="centered">
       <xsl:apply-templates select="title"/>
-    </div>
+    </header>
     <nav>
       <ul>
         <li>
@@ -169,7 +195,7 @@
       </ul>
     </nav>
     <!-- end table of contents, begin body -->
-    <div role="main">
+    <main>
     <div class="sep"/>
     <hr class="thick"/>
     <div class="sep"/>
@@ -205,7 +231,7 @@
     </xsl:if>
     <p id="ChangeHistory"/>
       <xsl:apply-templates select="changehistory"/>
-    </div>
+    </main>
   </body>
 </html>
 </xsl:template>
@@ -349,76 +375,62 @@
 </xsl:template>
 
 <xsl:template match="function" mode="generalinfo">
-  <table class="bordered wide">
-     <tr class="bgLight">
-      <td >
-        <a href="#jvmtiPhase">Phase</a>
-      </td>
-      <td>
-        <a href="#heapCallbacks">Callback Safe</a>
-      </td>
-      <td>
-        <a href="#FunctionTable">Position</a>
-      </td>
-      <td>
-        <a href="#ChangeHistory">Since</a>
-      </td>
-    </tr>
-    <tr>
-      <td>
+  <div class="wideDivTableCtnr">
+  <div class="divTable bordered wide">
+    <div class="divTableRow bgLight">
+      <div class="divTableCell"><a href="#jvmtiPhase">Phase</a></div>
+      <div class="divTableCell"><a href="#heapCallbacks">Callback Safe</a></div>
+      <div class="divTableCell"><a href="#FunctionTable">Position</a></div>
+      <div class="divTableCell"><a href="#ChangeHistory">Since</a></div>
+    </div>
+    <div class="divTableRow">
+      <div class="divTableCell">
         <xsl:apply-templates select="." mode="phaseinfo"/>
-      </td>
-      <td>
+      </div>
+      <div class="divTableCell">
         <xsl:apply-templates select="." mode="callbacksafeinfo"/>
-      </td>
-      <td>
+      </div>
+      <div class="divTableCell">
         <xsl:value-of select="@num"/>
-      </td>
-      <td>
+      </div>
+      <div class="divTableCell">
         <xsl:value-of select="@since"/>
-      </td>
-    </tr>
-  </table>
+      </div>
+    </div>
+  </div>
+  </div>
 </xsl:template>
 
 <xsl:template match="event" mode="generalinfo">
-  <table class="bordered wide">
-    <tr class="bgLight">
-      <td >
-        <a href="#jvmtiPhase">Phase</a>
-      </td>
-      <td>
-        <a href="#jvmtiEvent">Event Type</a>
-      </td>
-      <td>
-        <a href="#jvmtiEvent">Number</a>
-      </td>
-      <td>
-        <a href="#enablingevents">Enabling</a>
-      </td>
-      <td>
-        <a href="#ChangeHistory">Since</a>
-      </td>
-    </tr>
-    <tr>
-      <td >
+  <div class="wideDivTableCtnr">
+  <div class="divTable bordered wide">
+    <div class="divTableRow bgLight">
+      <div class="divTableCell"><a href="#jvmtiPhase">Phase</a></div>
+      <div class="divTableCell"><a href="#heapCallbacks">Event Type</a></div>
+      <div class="divTableCell"><a href="#FunctionTable">Number</a></div>
+      <div class="divTableCell"><a href="#FunctionTable">Enabling</a></div>
+      <div class="divTableCell"><a href="#ChangeHistory">Since</a></div>
+    </div>
+    <div class="divTableRow">
+      <div class="divTableCell">
         <xsl:apply-templates select="." mode="phaseinfo"/>
-      </td>
-      <td>
+      </div>
+      <div class="divTableCell">
         <code><xsl:value-of select="@const"/></code>
-      </td>
-      <td>
+      </div>
+      <div class="divTableCell">
         <xsl:value-of select="@num"/>
-      </td>
-      <td>
-          <code><a href="#SetEventNotificationMode">SetEventNotificationMode</a>(JVMTI_ENABLE, 
-          <xsl:value-of select="@const"/>, NULL)</code>
-      </td>
-      <td>
+      </div>
+      <div class="divTableCell">
+        <code><a href="#SetEventNotificationMode">SetEventNotificationMode</a>(JVMTI_ENABLE, 
+        <xsl:value-of select="@const"/>, NULL)</code>
+      </div>
+      <div class="divTableCell">
         <xsl:value-of select="@since"/>
-      </td>
-    </tr>
-  </table>
+      </div>
+    </div>
+  </div>
+  </div>
 </xsl:template>
 
 <xsl:template match="function" mode="phaseinfo">
@@ -674,21 +686,13 @@
 
 <xsl:template match="typedef|uniontypedef" mode="justbody">
     <table class="bordered wide">
-      <tr class="bgDark">
-        <td colspan="3" class="tableHeader">
-          <code><xsl:value-of select="@id"/></code> - <xsl:value-of select="@label"/>
-        </td>
-      </tr>
+      <caption class="captionTitle">
+        <code><xsl:value-of select="@id"/></code> - <xsl:value-of select="@label"/>
+      </caption>
       <tr class="bgLight">
-        <td>
-          Field
-        </td>
-        <td>
-          Type
-        </td>
-        <td>
-          Description
-        </td>
+        <th scope="col">Field</th>
+        <th scope="col">Type</th>
+        <th scope="col">Description</th>
       </tr>
       <xsl:apply-templates select="field" mode="body"/>
     </table>
@@ -705,26 +709,16 @@
 
 <xsl:template match="capabilitiestypedef" mode="justbody">
     <table class="bordered wide">
-      <tr class="bgDark">
-        <td colspan="3" class="tableHeader">
+      <caption>
+        <div class="captionTitle">
           <code><xsl:value-of select="@id"/></code> - <xsl:value-of select="@label"/>
-        </td>
-      </tr>
+        </div>
+        <div class="captionDescr">All types are <code>unsigned int : 1</code></div>
+      </caption>
       <tr class="bgLight">
-        <td colspan="3">
-          All types are <code>unsigned int : 1</code>
-        </td>
-      </tr>
-      <tr class="bgLight">
-        <td>
-          Field
-        </td>
-        <td>
-          Description
-        </td>
-        <td>
-          <a href="#ChangeHistory">Since</a>
-        </td>
+        <th scope="col">Field</th>
+        <th scope="col">Description</th>
+        <th scope="col"><a href="#ChangeHistory">Since</a></th>
       </tr>
       <xsl:apply-templates select="capabilityfield" mode="body"/>
     </table>
@@ -732,7 +726,7 @@
 
 <xsl:template match="typedef|uniontypedef|capabilitiestypedef|constants" mode="tableentry">
   <tr>
-    <td>
+    <th scope="row">
       <a>
         <xsl:attribute name="href">
           <xsl:text>#</xsl:text>
@@ -740,7 +734,7 @@
         </xsl:attribute>
         <code><xsl:value-of select="@id"/></code>
       </a>
-    </td>
+    </th>
     <td>
       <xsl:value-of select="@label"/>
     </td>
@@ -749,14 +743,14 @@
 
 <xsl:template match="field" mode="body">
   <tr>
-    <td>
+    <th scope="row">
       <code>
         <xsl:attribute name="id">
           <xsl:value-of select="../@id"/>.<xsl:value-of select="@id"/>
         </xsl:attribute>
         <xsl:value-of select="@id"/>
       </code>
-    </td>
+    </th>
     <td>
       <code>
         <xsl:apply-templates select="child::*[position()=1]" mode="link"/>
@@ -770,7 +764,7 @@
 
 <xsl:template match="capabilityfield" mode="body">
   <tr>
-    <td>
+    <th scope="row">
       <code>
         <xsl:choose>
           <xsl:when test="@disp1!=''">
@@ -783,7 +777,7 @@
           </xsl:otherwise>
         </xsl:choose>
       </code>
-    </td>
+    </th>
     <td>
       <xsl:attribute name="id">
         <xsl:value-of select="../@id"/>.<xsl:value-of select="@id"/>
@@ -798,7 +792,7 @@
 
 <xsl:template match="callback" mode="tableentry">
   <tr>
-    <td>
+    <th scope="row">
       <a>
         <xsl:attribute name="href">
           <xsl:text>#</xsl:text>
@@ -808,7 +802,7 @@
           <xsl:value-of select="@id"/>
         </code>
       </a>
-    </td>
+    </th>
     <td>
       <xsl:apply-templates select="synopsis" mode="index"/>
     </td>
@@ -821,28 +815,21 @@
       <xsl:attribute name="id">
         <xsl:value-of select="@id"/>
       </xsl:attribute>
-      <tr class="bgDark">
-        <td colspan="3" class="tableHeader">
-            <xsl:value-of select="@label"/>
-            <xsl:if test="@kind='enum'">
-              <xsl:text> (</xsl:text>
-              <code>
-                <xsl:value-of select="@id"/>
-              </code>
-              <xsl:text>)</xsl:text>
-            </xsl:if>
-        </td>
-      </tr>
+      <caption class="captionTitle">
+        <xsl:value-of select="@label"/>
+        <xsl:if test="@kind='enum'">
+          <xsl:text> (</xsl:text>
+          <code>
+            <xsl:value-of select="@id"/>
+          </code>
+          <xsl:text>)</xsl:text>
+        </xsl:if>
+      </caption>
+
       <tr class="bgLight">
-        <td>
-          Constant
-        </td>
-        <td>
-          Value
-        </td>
-        <td>
-          Description
-        </td>
+        <th scope="col">Constant</th>
+        <th scope="col">Value</th>
+        <th scope="col">Description</th>
       </tr>
       <xsl:apply-templates select="constant" mode="body"/>
     </table>
@@ -862,14 +849,14 @@
 
 <xsl:template match="constant" mode="body">
   <tr>
-    <td>
+    <th scope="row">
       <code>
         <xsl:attribute name="id">
           <xsl:value-of select="@id"/>
         </xsl:attribute>
         <xsl:value-of select="@id"/>
       </code>
-    </td>
+    </th>
     <td class="rightAligned">
       <xsl:value-of select="@num"/>
     </td>
@@ -886,74 +873,47 @@
     </xsl:attribute>
   </p>
     <table class="bordered wide">
-      <tr class="bgDark">
-        <td colspan="2" class="tableHeader">
-          <xsl:value-of select="@label"/>
-        </td>
-      </tr>
+      <caption class="captionTitle"><xsl:value-of select="@label"/></caption>
       <tr class="bgLight">
-        <td>
-          Type
-        </td>
-        <td>
-          Description
-        </td>
+        <th scope="col">Type</th>
+        <th scope="col">Description</th>
       </tr>
       <xsl:apply-templates select="basetype" mode="body"/>
     </table>
 </xsl:template>
 
 <xsl:template match="basetype" mode="body">
-  <xsl:choose>
-    <xsl:when test="count(definition)=0">
-      <tr>
-        <td>
-          <code>
-            <xsl:value-of select="@id"/>
-          </code>
-        </td>
-        <td>
-          <a>
-            <xsl:attribute name="id">
-              <xsl:choose>
-                <xsl:when test="count(@name)=1">
-                  <xsl:value-of select="@name"/>
-                </xsl:when>
-                <xsl:otherwise>
-                  <xsl:value-of select="@id"/>
-                </xsl:otherwise>
-              </xsl:choose>
-            </xsl:attribute>
-          </a>
-          <xsl:apply-templates select="description" mode="brief"/>
-        </td>
-      </tr>
-    </xsl:when>
-    <xsl:otherwise>
-      <tr>
-        <td rowspan="2">
-          <code>
-            <xsl:value-of select="@id"/>
-          </code>
-        </td>
-        <td>
-          <a>
-            <xsl:attribute name="id">
-              <xsl:value-of select="@id"/>
-            </xsl:attribute>
-          </a>
-          <xsl:apply-templates select="description" mode="brief"/>
-        </td>
-      </tr>
-      <tr>
-        <td>
+  <tr>
+    <th scope="row">
+      <code>
+        <xsl:value-of select="@id"/>
+      </code>
+    </th>
+    <td class="noPadding">
+      <div class="withPadding">
+        <a>
+          <xsl:attribute name="id">
+            <xsl:choose>
+              <xsl:when test="count(@name)=1">
+                <xsl:value-of select="@name"/>
+              </xsl:when>
+              <xsl:otherwise>
+                <xsl:value-of select="@id"/>
+              </xsl:otherwise>
+            </xsl:choose>
+          </xsl:attribute>
+        </a>
+        <xsl:apply-templates select="description" mode="brief"/>
+      </div>
+      <xsl:if test="count(definition)!=0">
+        <div class="withPadding topBorder">
           <pre>
             <xsl:apply-templates select="definition"/>
           </pre>
-        </td>
-      </tr>
-    </xsl:otherwise>
-  </xsl:choose>
+        </div>
+      </xsl:if>
+    </td>
+  </tr>
 </xsl:template>
 
 <xsl:template match="description">
@@ -1074,37 +1034,40 @@
 
 <xsl:template match="parameters" mode="body">
   <div class="sep"/>
-  <table class="bordered wide">
-    <tr class="bgDark">
-      <td colspan="3" class="tableHeader">
-        Parameters
-      </td>
-    </tr>
-    <tr class="bgLight">
-      <td>
-        Name
-      </td>
-      <td>
-        Type
-      </td>
-      <td>
-        Description
-      </td>
-    </tr>
-    <xsl:apply-templates select="param[count(jclass/@method)=0]" mode="body"/>
-  </table>
+  <!--
+  docchecker complains if a table has only one row.
+  -->
+  <xsl:choose>
+    <xsl:when test="count(param)!=0">
+      <table class="bordered wide">
+        <caption class="captionTitle">Parameters</caption>
+        <tr class="bgLight">
+          <th scope="col">Name</th>
+          <th scope="col">Type</th>
+          <th scope="col">Description</th>
+        </tr>
+        <xsl:apply-templates select="param[count(jclass/@method)=0]" mode="body"/>
+      </table>
+    </xsl:when>
+    <xsl:otherwise>
+      <div class="bordered">
+        <div class="captionTitle">Parameters</div>
+        <div class="captionDescr">None</div>
+      </div>
+    </xsl:otherwise>
+  </xsl:choose>
 </xsl:template>
 
 <xsl:template match="param" mode="body">
   <tr>
-    <td>
+    <th scope="row">
       <code>
         <xsl:attribute name="id">
           <xsl:value-of select="../../@id"/>.<xsl:value-of select="@id"/>
         </xsl:attribute>
         <xsl:value-of select="@id"/>
       </code>
-    </td>
+    </th>
     <td>
       <code>
         <xsl:apply-templates select="child::*[position()=1]" mode="link"/>
@@ -1122,120 +1085,97 @@
 <xsl:template match="capabilities">
   <div class="sep"/>
   <!--
-  W3C Validator reports error if all cells has colspan==2.
-  The workaround is to detect the case and set colspan = 1 for all cells
-  which fills the entire row.
+  docchecker complains if a table has only one column.
   -->
-  <xsl:variable name="fullRowColspan">
-    <xsl:choose>
-      <xsl:when test="count(required)!=0 or count(capability)!=0">2</xsl:when>
-      <xsl:otherwise>1</xsl:otherwise>
-    </xsl:choose>
-  </xsl:variable>
-  <table class="bordered wide">
-    <tr class="bgDark">
-      <td colspan="{$fullRowColspan}" class="tableHeader">
-        Capabilities
-      </td>
-    </tr>
-    <xsl:choose>
-      <xsl:when test="count(required)=0">
-        <tr>
-          <td colspan="{$fullRowColspan}">
-            <b>Required Functionality</b>
-          </td>
-        </tr>
-      </xsl:when>
-      <xsl:otherwise>
-        <tr>
-          <td colspan="2">
-            <b>Optional Functionality:</b> might not be implemented for all
-            virtual machines.
-            <xsl:choose>
-              <xsl:when test="count(required)=1">
-                The following capability
-              </xsl:when>
-              <xsl:otherwise>
-                One of the following capabilities
-              </xsl:otherwise>
-            </xsl:choose>
-            (as returned by
-            <a href="#GetCapabilities"><code>GetCapabilities</code></a>)
-            must be true to use this
-            <xsl:choose>
-              <xsl:when test="ancestor::function">
-                function.
-              </xsl:when>
-              <xsl:otherwise>
-                event.
-              </xsl:otherwise>
-            </xsl:choose>
-          </td>
-        </tr>
-        <tr class="bgLight">
-          <td >
-            Capability
-          </td>
-          <td>
-            Effect
-          </td>
-        </tr>
-        <xsl:apply-templates select="required"/>
-      </xsl:otherwise>
-    </xsl:choose>
-    <xsl:if test="count(capability)!=0">
-      <tr class="bgDark">
-        <td colspan="{$fullRowColspan}" class="centered">
-          Optional Features
-        </td>
-      </tr>
-      <xsl:if test="count(required)=0">
-        <tr class="bgLight">
-          <td >
-            Capability
-          </td>
-          <td>
-            Effect
-          </td>
-        </tr>
-      </xsl:if>
-      <xsl:apply-templates select="capability"/>
-    </xsl:if>
-  </table>
+  <xsl:choose>
+    <xsl:when test="count(required)!=0 or count(capability)!=0">
+      <table class="bordered wide">
+        <caption>
+          <div class="captionTitle">Capabilities</div>
+          <xsl:choose>
+            <xsl:when test="count(required)=0">
+              <div class="captionDescr"><b>Required Functionality</b></div>
+            </xsl:when>
+            <xsl:otherwise>
+              <div class="captionDescr">
+                <b>Optional Functionality:</b> might not be implemented for all virtual machines.
+                <xsl:choose>
+                  <xsl:when test="count(required)=1">
+                    The following capability
+                  </xsl:when>
+                  <xsl:otherwise>
+                    One of the following capabilities
+                  </xsl:otherwise>
+                </xsl:choose>
+                (as returned by <a href="#GetCapabilities"><code>GetCapabilities</code></a>)
+                must be true to use this
+                <xsl:choose>
+                  <xsl:when test="ancestor::function">
+                    function.
+                  </xsl:when>
+                  <xsl:otherwise>
+                    event.
+                  </xsl:otherwise>
+                </xsl:choose>
+              </div>
+            </xsl:otherwise>
+          </xsl:choose>
+        </caption>
+        <xsl:if test="count(required)!=0">
+          <tr class="bgLight">
+            <th scope="col">Capability</th>
+            <th scope="col">Effect</th>
+          </tr>
+          <xsl:apply-templates select="required"/>
+        </xsl:if>
+
+        <xsl:if test="count(capability)!=0">
+          <tr class="bgDark">
+            <th colspan="2" scope="rowgroup" class="centered">
+              Optional Features
+            </th>
+          </tr>
+          <xsl:if test="count(required)=0">
+            <tr class="bgLight">
+              <th scope="col">Capability</th>
+              <th scope="col">Effect</th>
+            </tr>
+          </xsl:if>
+          <xsl:apply-templates select="capability"/>
+        </xsl:if>
+      </table>
+    </xsl:when>
+    <xsl:otherwise>
+      <div class="bordered">
+        <div class="captionTitle">Capabilities</div>
+        <div class="captionDescr"><b>Required Functionality</b></div>
+      </div>
+    </xsl:otherwise>
+  </xsl:choose>
 </xsl:template>
 
 <xsl:template match="eventcapabilities">
   <div class="sep"/>
   <table class="bordered wide">
+    <caption>
+      <div class="captionTitle">Capabilities</div>
+      <div class="captionDescr"><b>Required Functionality</b></div>
+    </caption>
     <tr class="bgDark">
-      <td colspan="2" class="tableHeader">
-        Capabilities
-      </td>
-    </tr>
-    <tr>
-      <td colspan="2">
-        <b>Required Functionality</b>
-      </td>
-    </tr>
-    <tr class="bgDark">
-      <td colspan="2" class="centered">
+      <th colspan="2" scope="rowgroup" class="centered">
         Event Enabling Capabilities
-      </td>
+      </th>
     </tr>
     <tr class="bgLight">
-      <td >
-        Capability
-      </td>
-      <td>
-        Events
-      </td>
+      <th scope="col">Capability</th>
+      <th scope="col">Events</th>
     </tr>
     <xsl:for-each select="//capabilityfield">
       <xsl:variable name="capa" select="@id"/>
       <xsl:variable name="events" select="//event[capabilities/required/@id=$capa]"/>
       <xsl:if test="count($events)">
         <tr>
-          <td>
+          <th scope="row">
             <a>
               <xsl:attribute name="href">#jvmtiCapabilities.<xsl:value-of select="@id"/>
               </xsl:attribute>
@@ -1243,7 +1183,7 @@
                 <xsl:value-of select="@id"/>
               </code>
             </a>
-          </td>
+          </th>
           <td>
             <xsl:for-each select="$events">
               <a>
@@ -1264,7 +1204,7 @@
 
 <xsl:template match="capability|required">
   <tr>
-    <td>
+    <th scope="row">
       <a>
         <xsl:attribute name="href">#jvmtiCapabilities.<xsl:value-of select="@id"/>
         </xsl:attribute>
@@ -1272,7 +1212,7 @@
           <xsl:value-of select="@id"/>
         </code>
       </a>
-    </td>
+    </th>
     <td>
       <xsl:choose>
         <xsl:when test=".=''">
@@ -1297,53 +1237,38 @@
   </xsl:variable>
   <div class="sep"/>
   <!--
-  W3C Validator reports error if all cells has colspan==2.
-  The workaround is to detect the case and set colspan = 1 for all cells
-  which fills the entire row.
+  docchecker complains if a table has only one column.
   -->
-  <xsl:variable name="fullRowColspan">
-    <xsl:choose>
-      <xsl:when test="contains($haserrors,'yes')">2</xsl:when>
-      <xsl:otherwise>1</xsl:otherwise>
-    </xsl:choose>
-  </xsl:variable>
-  <table class="bordered wide">
-    <tr class="bgDark">
-      <td colspan="{$fullRowColspan}" class="tableHeader">
-        Errors
-      </td>
-    </tr>
-    <xsl:choose>
-      <xsl:when test="contains($haserrors,'yes')">
-        <tr>
-          <td colspan="2">
+  <xsl:choose>
+    <xsl:when test="contains($haserrors,'yes')">
+      <table class="bordered wide">
+        <caption>
+          <div class="captionTitle">Errors</div>
+          <div class="captionDescr">
             This function returns either a
             <a href="#universal-error">universal error</a>
             or one of the following errors
-          </td>
-        </tr>
+          </div>
+        </caption>
         <tr class="bgLight">
-          <td>
-            Error
-          </td>
-          <td>
-            Description
-          </td>
+          <th scope="col">Error</th>
+          <th scope="col">Description</th>
         </tr>
         <xsl:apply-templates select="capabilities/required" mode="errors"/>
         <xsl:apply-templates select="errors/error"/>
         <xsl:apply-templates select="parameters/param" mode="errors"/>
-      </xsl:when>
-      <xsl:otherwise>
-        <tr>
-          <td colspan="{$fullRowColspan}">
+      </table>
+    </xsl:when>
+    <xsl:otherwise>
+      <div class="bordered">
+        <div class="captionTitle">Errors</div>
+        <div class="captionDescr">
             This function returns a
             <a href="#universal-error">universal error</a>
-          </td>
-        </tr>
-      </xsl:otherwise>
-    </xsl:choose>
-  </table>
+        </div>
+      </div>
+    </xsl:otherwise>
+  </xsl:choose>
 </xsl:template>
 
 <xsl:template match="required" mode="haserrors">
@@ -1352,13 +1277,13 @@
 
 <xsl:template match="required" mode="errors">
   <tr>
-    <td>
+    <th scope="row">
       <a href="#JVMTI_ERROR_MUST_POSSESS_CAPABILITY">
         <code>
           JVMTI_ERROR_MUST_POSSESS_CAPABILITY
         </code>
       </a>
-    </td>
+    </th>
     <td>
       The environment does not possess the capability
       <a>
@@ -1391,14 +1316,14 @@
     </xsl:variable>
     <xsl:variable name="errorid" select="normalize-space($erroridraw)"/>
     <tr>
-      <td>
+      <th scope="row">
         <a>
           <xsl:attribute name="href">#<xsl:value-of select="$errorid"/></xsl:attribute>
           <code>
             <xsl:value-of select="$errorid"/>
           </code>
         </a>
-      </td>
+      </th>
       <td>
         <xsl:apply-templates mode="errordesc">
           <xsl:with-param name="id" select="@id"/>
@@ -1418,14 +1343,14 @@
     </xsl:variable>
     <xsl:variable name="errorid2" select="normalize-space($erroridraw2)"/>
     <tr>
-      <td>
+      <th scope="row">
         <a>
           <xsl:attribute name="href">#<xsl:value-of select="$errorid2"/></xsl:attribute>
           <code>
             <xsl:value-of select="$errorid2"/>
           </code>
         </a>
-      </td>
+      </th>
       <td>
         <xsl:apply-templates mode="errordesc2">
           <xsl:with-param name="id" select="@id"/>
@@ -1689,14 +1614,14 @@
 
 <xsl:template match="error">
   <tr>
-    <td>
+    <th scope="row">
       <a>
         <xsl:attribute name="href">#<xsl:value-of select="@id"/></xsl:attribute>
         <code>
           <xsl:value-of select="@id"/>
         </code>
       </a>
-    </td>
+    </th>
     <td>
       <xsl:apply-templates/>
     </td>
@@ -1727,18 +1652,10 @@
   <xsl:apply-templates select="basetypes"/>
   <div class="sep"/>
   <table id="StructureTypeDefinitions" class="bordered wide">
-    <tr class="bgDark">
-      <td colspan="2" class="tableHeader">
-        Structure Type Definitions
-      </td>
-    </tr>
+    <caption class="captionTitle">Structure Type Definitions</caption>
     <tr class="bgLight">
-      <td>
-        Type
-      </td>
-      <td>
-        Description
-      </td>
+      <th scope="col">Type</th>
+      <th scope="col">Description</th>
     </tr>
     <xsl:apply-templates select="//typedef|//uniontypedef|//capabilitiestypedef" mode="tableentry">
       <xsl:sort select="@id"/>
@@ -1746,18 +1663,10 @@
   </table>
   <div class="sep"/>
   <table id="FunctionTypeDefinitions" class="bordered wide">
-    <tr class="bgDark">
-      <td colspan="2" class="tableHeader">
-        Function Type Definitions
-      </td>
-    </tr>
+    <caption class="captionTitle">Function Type Definitions</caption>
     <tr class="bgLight">
-      <td>
-        Type
-      </td>
-      <td>
-        Description
-      </td>
+      <th scope="col">Type</th>
+      <th scope="col">Description</th>
     </tr>
     <xsl:apply-templates select="//callback" mode="tableentry">
       <xsl:sort select="@id"/>
@@ -1765,18 +1674,10 @@
   </table>
   <div class="sep"/>
   <table id="EnumerationDefinitions" class="bordered wide">
-    <tr class="bgDark">
-      <td colspan="2" class="tableHeader">
-        Enumeration Definitions
-      </td>
-    </tr>
+    <caption class="captionTitle">Enumeration Definitions</caption>
     <tr class="bgLight">
-      <td>
-        Type
-      </td>
-      <td>
-        Description
-      </td>
+      <th scope="col">Type</th>
+      <th scope="col">Description</th>
     </tr>
     <xsl:apply-templates select="//constants[@kind='enum']" mode="tableentry">
       <xsl:sort select="@id"/>
@@ -1784,21 +1685,11 @@
   </table>
   <div class="sep"/>
   <table id="FunctionTable" class="bordered wide">
-    <tr class="bgDark">
-      <td colspan="3" class="tableHeader">
-        Function Table Layout
-      </td>
-    </tr>
+    <caption class="captionTitle">Function Table Layout</caption>
     <tr class="bgLight">
-      <td>
-        Position
-      </td>
-      <td>
-        Function
-      </td>
-      <td>
-        Declaration
-      </td>
+      <th scope="col">Position</th>
+      <th scope="col">Function</th>
+      <th scope="col">Declaration</th>
     </tr>
     <xsl:call-template name="funcStruct">
       <xsl:with-param name="funcs" select="//functionsection/category/function[count(@hide)=0]"/>
@@ -1814,9 +1705,9 @@
   <xsl:param name="index"/>
   <xsl:variable name="thisFunction" select="$funcs[@num=$index]"/>
   <tr>
-    <td class="rightAligned">
+    <th scope="row" class="rightAligned">
       <xsl:number value="$index" format="  1"/>
-    </td>
+    </th>
     <xsl:choose>
       <xsl:when test="count($thisFunction)=1">
         <td>
@@ -1920,13 +1811,13 @@
     <div class="sep"/>
     <table class="bordered wide">
       <tr class="bgLight">
-        <td>
+        <th scope="col">
           <b>Version</b><br/>
           <b>Date</b>
-        </td>
-        <td>
+        </th>
+        <th scope="col">
           <b>Changes</b>
-        </td>
+        </th>
       </tr>
       <xsl:apply-templates select="change"/>
     </table>
@@ -1934,7 +1825,7 @@
 
 <xsl:template match="change">
   <tr>
-    <td>
+    <th scope="row">
       <xsl:if test="count(@version)">
         <b>
           <xsl:value-of select="@version"/>
@@ -1942,7 +1833,7 @@
         <br/>
       </xsl:if>
       <xsl:value-of select="@date"/>
-    </td>
+    </th>
     <td>
       <xsl:apply-templates/>
     </td>
@@ -2023,6 +1914,11 @@
 
 <xsl:template match="tr">
   <tr>
+    <xsl:if test="@class">
+      <xsl:attribute name="class">
+        <xsl:value-of select="@class"/>
+      </xsl:attribute>
+    </xsl:if>
     <xsl:apply-templates/>
   </tr>
 </xsl:template>
@@ -2045,6 +1941,11 @@
         <xsl:value-of select="@class"/>
       </xsl:attribute>
     </xsl:if>
+    <xsl:if test="@scope">
+      <xsl:attribute name="scope">
+        <xsl:value-of select="@scope"/>
+      </xsl:attribute>
+    </xsl:if>
     <xsl:apply-templates/>
   </th>
 </xsl:template>
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -960,7 +960,7 @@
     if (at_safepoint) {
       BiasedLocking::revoke_at_safepoint(hobj);
     } else {
-      BiasedLocking::revoke_and_rebias(hobj, false, calling_thread);
+      BiasedLocking::revoke(hobj, calling_thread);
     }
 
     address owner = NULL;
--- a/src/hotspot/share/prims/jvmtiTagMap.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/jvmtiTagMap.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1712,7 +1712,7 @@
   // object's mark word
   markWord mark = o->mark();
 
-  if (mark.must_be_preserved(o)) {
+  if (o->mark_must_be_preserved(mark)) {
     _saved_mark_stack->push(mark);
     _saved_oop_stack->push(o);
   }
--- a/src/hotspot/share/prims/resolvedMethodTable.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/resolvedMethodTable.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,13 +25,14 @@
 #include "precompiled.hpp"
 #include "classfile/javaClasses.hpp"
 #include "gc/shared/oopStorage.inline.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "logging/log.hpp"
 #include "memory/allocation.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/access.inline.hpp"
+#include "oops/method.hpp"
 #include "oops/oop.inline.hpp"
-#include "oops/method.hpp"
 #include "oops/weakHandle.inline.hpp"
 #include "prims/resolvedMethodTable.hpp"
 #include "runtime/handles.inline.hpp"
@@ -90,7 +91,6 @@
 static ResolvedMethodTableHash* _local_table           = NULL;
 static size_t                   _current_size          = (size_t)1 << ResolvedMethodTableSizeLog;
 
-OopStorage*              ResolvedMethodTable::_weak_handles          = NULL;
 volatile bool            ResolvedMethodTable::_has_work              = false;
 
 volatile size_t          _items_count           = 0;
@@ -98,9 +98,6 @@
 
 void ResolvedMethodTable::create_table() {
   _local_table  = new ResolvedMethodTableHash(ResolvedMethodTableSizeLog, END_SIZE, GROW_HINT);
-  _weak_handles = new OopStorage("ResolvedMethodTable weak",
-                                 ResolvedMethodTableWeakAlloc_lock,
-                                 ResolvedMethodTableWeakActive_lock);
   log_trace(membername, table)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")",
                                _current_size, ResolvedMethodTableSizeLog);
 }
--- a/src/hotspot/share/prims/resolvedMethodTable.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/resolvedMethodTable.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,7 +25,6 @@
 #ifndef SHARE_PRIMS_RESOLVEDMETHODTABLE_HPP
 #define SHARE_PRIMS_RESOLVEDMETHODTABLE_HPP
 
-#include "gc/shared/oopStorage.hpp"
 #include "memory/allocation.hpp"
 #include "oops/symbol.hpp"
 #include "oops/weakHandle.hpp"
@@ -34,9 +33,8 @@
 class ResolvedMethodTableConfig;
 
 class ResolvedMethodTable : public AllStatic {
-  static OopStorage*              _weak_handles;
+  static volatile bool            _has_work;
 
-  static volatile bool            _has_work;
 public:
   // Initialization
   static void create_table();
@@ -54,9 +52,6 @@
   // Cleaning
   static bool has_work() { return _has_work; }
 
-  // GC Support - Backing storage for the oop*s
-  static OopStorage* weak_storage() { return _weak_handles; }
-
   // Cleaning and table management
 
   static double get_load_factor();
--- a/src/hotspot/share/prims/unsafe.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/unsafe.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -44,6 +44,7 @@
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/orderAccess.hpp"
 #include "runtime/reflection.hpp"
+#include "runtime/sharedRuntime.hpp"
 #include "runtime/thread.hpp"
 #include "runtime/threadSMR.hpp"
 #include "runtime/vm_version.hpp"
@@ -445,6 +446,46 @@
   }
 } UNSAFE_END
 
+UNSAFE_LEAF (void, Unsafe_WriteBack0(JNIEnv *env, jobject unsafe, jlong line)) {
+  assert(VM_Version::supports_data_cache_line_flush(), "should not get here");
+#ifdef ASSERT
+  if (TraceMemoryWriteback) {
+    tty->print_cr("Unsafe: writeback 0x%p", addr_from_java(line));
+  }
+#endif
+
+  assert(StubRoutines::data_cache_writeback() != NULL, "sanity");
+  (StubRoutines::DataCacheWriteback_stub())(addr_from_java(line));
+} UNSAFE_END
+
+static void doWriteBackSync0(bool is_pre)
+{
+  assert(StubRoutines::data_cache_writeback_sync() != NULL, "sanity");
+  (StubRoutines::DataCacheWritebackSync_stub())(is_pre);
+}
+
+UNSAFE_LEAF (void, Unsafe_WriteBackPreSync0(JNIEnv *env, jobject unsafe)) {
+  assert(VM_Version::supports_data_cache_line_flush(), "should not get here");
+#ifdef ASSERT
+  if (TraceMemoryWriteback) {
+      tty->print_cr("Unsafe: writeback pre-sync");
+  }
+#endif
+
+  doWriteBackSync0(true);
+} UNSAFE_END
+
+UNSAFE_LEAF (void, Unsafe_WriteBackPostSync0(JNIEnv *env, jobject unsafe)) {
+  assert(VM_Version::supports_data_cache_line_flush(), "should not get here");
+#ifdef ASSERT
+  if (TraceMemoryWriteback) {
+    tty->print_cr("Unsafe: writeback pre-sync");
+  }
+#endif
+
+  doWriteBackSync0(false);
+} UNSAFE_END
+
 ////// Random queries
 
 static jlong find_field_offset(jclass clazz, jstring name, TRAPS) {
@@ -1073,6 +1114,9 @@
 
     {CC "copyMemory0",        CC "(" OBJ "J" OBJ "JJ)V", FN_PTR(Unsafe_CopyMemory0)},
     {CC "copySwapMemory0",    CC "(" OBJ "J" OBJ "JJJ)V", FN_PTR(Unsafe_CopySwapMemory0)},
+    {CC "writeback0",         CC "(" "J" ")V",           FN_PTR(Unsafe_WriteBack0)},
+    {CC "writebackPreSync0",  CC "()V",                  FN_PTR(Unsafe_WriteBackPreSync0)},
+    {CC "writebackPostSync0", CC "()V",                  FN_PTR(Unsafe_WriteBackPostSync0)},
     {CC "setMemory0",         CC "(" OBJ "JJB)V",        FN_PTR(Unsafe_SetMemory0)},
 
     {CC "defineAnonymousClass0", CC "(" DAC_Args ")" CLS, FN_PTR(Unsafe_DefineAnonymousClass0)},
--- a/src/hotspot/share/prims/whitebox.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/prims/whitebox.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1137,27 +1137,29 @@
 WB_END
 
 template <typename T>
-static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, JVMFlag::Error (*TAt)(const char*, T*, bool, bool)) {
+static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, JVMFlag::Error (*TAt)(const JVMFlag*, T*)) {
   if (name == NULL) {
     return false;
   }
   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
   const char* flag_name = env->GetStringUTFChars(name, NULL);
   CHECK_JNI_EXCEPTION_(env, false);
-  JVMFlag::Error result = (*TAt)(flag_name, value, true, true);
+  const JVMFlag* flag = JVMFlag::find_declared_flag(flag_name);
+  JVMFlag::Error result = (*TAt)(flag, value);
   env->ReleaseStringUTFChars(name, flag_name);
   return (result == JVMFlag::SUCCESS);
 }
 
 template <typename T>
-static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, JVMFlag::Error (*TAtPut)(const char*, T*, JVMFlag::Flags)) {
+static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, JVMFlag::Error (*TAtPut)(JVMFlag* flag, T*, JVMFlag::Flags)) {
   if (name == NULL) {
     return false;
   }
   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
   const char* flag_name = env->GetStringUTFChars(name, NULL);
   CHECK_JNI_EXCEPTION_(env, false);
-  JVMFlag::Error result = (*TAtPut)(flag_name, value, JVMFlag::INTERNAL);
+  JVMFlag* flag = JVMFlag::find_flag(flag_name);
+  JVMFlag::Error result = (*TAtPut)(flag, value, JVMFlag::INTERNAL);
   env->ReleaseStringUTFChars(name, flag_name);
   return (result == JVMFlag::SUCCESS);
 }
@@ -1192,22 +1194,22 @@
   return box(thread, env, vmSymbols::java_lang_Double(), vmSymbols::Double_valueOf_signature(), value);
 }
 
-static JVMFlag* getVMFlag(JavaThread* thread, JNIEnv* env, jstring name) {
+static const JVMFlag* getVMFlag(JavaThread* thread, JNIEnv* env, jstring name) {
   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
   const char* flag_name = env->GetStringUTFChars(name, NULL);
   CHECK_JNI_EXCEPTION_(env, NULL);
-  JVMFlag* result = JVMFlag::find_flag(flag_name, strlen(flag_name), true, true);
+  const JVMFlag* result = JVMFlag::find_declared_flag(flag_name);
   env->ReleaseStringUTFChars(name, flag_name);
   return result;
 }
 
 WB_ENTRY(jboolean, WB_IsConstantVMFlag(JNIEnv* env, jobject o, jstring name))
-  JVMFlag* flag = getVMFlag(thread, env, name);
+  const JVMFlag* flag = getVMFlag(thread, env, name);
   return (flag != NULL) && flag->is_constant_in_binary();
 WB_END
 
 WB_ENTRY(jboolean, WB_IsLockedVMFlag(JNIEnv* env, jobject o, jstring name))
-  JVMFlag* flag = getVMFlag(thread, env, name);
+  const JVMFlag* flag = getVMFlag(thread, env, name);
   return (flag != NULL) && !(flag->is_unlocked() || flag->is_unlocker());
 WB_END
 
--- a/src/hotspot/share/runtime/arguments.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/arguments.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -750,7 +750,7 @@
 
       // if flag has become obsolete it should not have a "globals" flag defined anymore.
       if (!version_less_than(JDK_Version::current(), flag.obsolete_in)) {
-        if (JVMFlag::find_flag(flag.name) != NULL) {
+        if (JVMFlag::find_declared_flag(flag.name) != NULL) {
           // Temporarily disable the warning: 8196739
           // warning("Global variable for obsolete special flag entry \"%s\" should be removed", flag.name);
         }
@@ -760,7 +760,7 @@
     if (!flag.expired_in.is_undefined()) {
       // if flag has become expired it should not have a "globals" flag defined anymore.
       if (!version_less_than(JDK_Version::current(), flag.expired_in)) {
-        if (JVMFlag::find_flag(flag.name) != NULL) {
+        if (JVMFlag::find_declared_flag(flag.name) != NULL) {
           // Temporarily disable the warning: 8196739
           // warning("Global variable for expired flag entry \"%s\" should be removed", flag.name);
         }
@@ -844,15 +844,15 @@
   }
 }
 
-static bool set_bool_flag(const char* name, bool value, JVMFlag::Flags origin) {
-  if (JVMFlag::boolAtPut(name, &value, origin) == JVMFlag::SUCCESS) {
+static bool set_bool_flag(JVMFlag* flag, bool value, JVMFlag::Flags origin) {
+  if (JVMFlag::boolAtPut(flag, &value, origin) == JVMFlag::SUCCESS) {
     return true;
   } else {
     return false;
   }
 }
 
-static bool set_fp_numeric_flag(const char* name, char* value, JVMFlag::Flags origin) {
+static bool set_fp_numeric_flag(JVMFlag* flag, char* value, JVMFlag::Flags origin) {
   char* end;
   errno = 0;
   double v = strtod(value, &end);
@@ -860,26 +860,25 @@
     return false;
   }
 
-  if (JVMFlag::doubleAtPut(name, &v, origin) == JVMFlag::SUCCESS) {
+  if (JVMFlag::doubleAtPut(flag, &v, origin) == JVMFlag::SUCCESS) {
     return true;
   }
   return false;
 }
 
-static bool set_numeric_flag(const char* name, char* value, JVMFlag::Flags origin) {
+static bool set_numeric_flag(JVMFlag* flag, char* value, JVMFlag::Flags origin) {
   julong v;
   int int_v;
   intx intx_v;
   bool is_neg = false;
-  JVMFlag* result = JVMFlag::find_flag(name, strlen(name));
-
-  if (result == NULL) {
+
+  if (flag == NULL) {
     return false;
   }
 
   // Check the sign first since atojulong() parses only unsigned values.
   if (*value == '-') {
-    if (!result->is_intx() && !result->is_int()) {
+    if (!flag->is_intx() && !flag->is_int()) {
       return false;
     }
     value++;
@@ -888,48 +887,48 @@
   if (!Arguments::atojulong(value, &v)) {
     return false;
   }
-  if (result->is_int()) {
+  if (flag->is_int()) {
     int_v = (int) v;
     if (is_neg) {
       int_v = -int_v;
     }
-    return JVMFlag::intAtPut(result, &int_v, origin) == JVMFlag::SUCCESS;
-  } else if (result->is_uint()) {
+    return JVMFlag::intAtPut(flag, &int_v, origin) == JVMFlag::SUCCESS;
+  } else if (flag->is_uint()) {
     uint uint_v = (uint) v;
-    return JVMFlag::uintAtPut(result, &uint_v, origin) == JVMFlag::SUCCESS;
-  } else if (result->is_intx()) {
+    return JVMFlag::uintAtPut(flag, &uint_v, origin) == JVMFlag::SUCCESS;
+  } else if (flag->is_intx()) {
     intx_v = (intx) v;
     if (is_neg) {
       intx_v = -intx_v;
     }
-    return JVMFlag::intxAtPut(result, &intx_v, origin) == JVMFlag::SUCCESS;
-  } else if (result->is_uintx()) {
+    return JVMFlag::intxAtPut(flag, &intx_v, origin) == JVMFlag::SUCCESS;
+  } else if (flag->is_uintx()) {
     uintx uintx_v = (uintx) v;
-    return JVMFlag::uintxAtPut(result, &uintx_v, origin) == JVMFlag::SUCCESS;
-  } else if (result->is_uint64_t()) {
+    return JVMFlag::uintxAtPut(flag, &uintx_v, origin) == JVMFlag::SUCCESS;
+  } else if (flag->is_uint64_t()) {
     uint64_t uint64_t_v = (uint64_t) v;
-    return JVMFlag::uint64_tAtPut(result, &uint64_t_v, origin) == JVMFlag::SUCCESS;
-  } else if (result->is_size_t()) {
+    return JVMFlag::uint64_tAtPut(flag, &uint64_t_v, origin) == JVMFlag::SUCCESS;
+  } else if (flag->is_size_t()) {
     size_t size_t_v = (size_t) v;
-    return JVMFlag::size_tAtPut(result, &size_t_v, origin) == JVMFlag::SUCCESS;
-  } else if (result->is_double()) {
+    return JVMFlag::size_tAtPut(flag, &size_t_v, origin) == JVMFlag::SUCCESS;
+  } else if (flag->is_double()) {
     double double_v = (double) v;
-    return JVMFlag::doubleAtPut(result, &double_v, origin) == JVMFlag::SUCCESS;
+    return JVMFlag::doubleAtPut(flag, &double_v, origin) == JVMFlag::SUCCESS;
   } else {
     return false;
   }
 }
 
-static bool set_string_flag(const char* name, const char* value, JVMFlag::Flags origin) {
-  if (JVMFlag::ccstrAtPut(name, &value, origin) != JVMFlag::SUCCESS) return false;
+static bool set_string_flag(JVMFlag* flag, const char* value, JVMFlag::Flags origin) {
+  if (JVMFlag::ccstrAtPut(flag, &value, origin) != JVMFlag::SUCCESS) return false;
   // Contract:  JVMFlag always returns a pointer that needs freeing.
   FREE_C_HEAP_ARRAY(char, value);
   return true;
 }
 
-static bool append_to_string_flag(const char* name, const char* new_value, JVMFlag::Flags origin) {
+static bool append_to_string_flag(JVMFlag* flag, const char* new_value, JVMFlag::Flags origin) {
   const char* old_value = "";
-  if (JVMFlag::ccstrAt(name, &old_value) != JVMFlag::SUCCESS) return false;
+  if (JVMFlag::ccstrAt(flag, &old_value) != JVMFlag::SUCCESS) return false;
   size_t old_len = old_value != NULL ? strlen(old_value) : 0;
   size_t new_len = strlen(new_value);
   const char* value;
@@ -946,7 +945,7 @@
     value = buf;
     free_this_too = buf;
   }
-  (void) JVMFlag::ccstrAtPut(name, &value, origin);
+  (void) JVMFlag::ccstrAtPut(flag, &value, origin);
   // JVMFlag always returns a pointer that needs freeing.
   FREE_C_HEAP_ARRAY(char, value);
   if (free_this_too != NULL) {
@@ -1041,7 +1040,8 @@
     if (real_name == NULL) {
       return false;
     }
-    return set_bool_flag(real_name, false, origin);
+    JVMFlag* flag = JVMFlag::find_flag(real_name);
+    return set_bool_flag(flag, false, origin);
   }
   if (sscanf(arg, "+%" XSTR(BUFLEN) NAME_RANGE "%c", name, &dummy) == 1) {
     AliasedLoggingFlag alf = catch_logging_aliases(name, true);
@@ -1053,13 +1053,13 @@
     if (real_name == NULL) {
       return false;
     }
-    return set_bool_flag(real_name, true, origin);
+    JVMFlag* flag = JVMFlag::find_flag(real_name);
+    return set_bool_flag(flag, true, origin);
   }
 
   char punct;
   if (sscanf(arg, "%" XSTR(BUFLEN) NAME_RANGE "%c", name, &punct) == 2 && punct == '=') {
     const char* value = strchr(arg, '=') + 1;
-    JVMFlag* flag;
 
     // this scanf pattern matches both strings (handled here) and numbers (handled later))
     AliasedLoggingFlag alf = catch_logging_aliases(name, true);
@@ -1071,15 +1071,15 @@
     if (real_name == NULL) {
       return false;
     }
-    flag = JVMFlag::find_flag(real_name);
+    JVMFlag* flag = JVMFlag::find_flag(real_name);
     if (flag != NULL && flag->is_ccstr()) {
       if (flag->ccstr_accumulates()) {
-        return append_to_string_flag(real_name, value, origin);
+        return append_to_string_flag(flag, value, origin);
       } else {
         if (value[0] == '\0') {
           value = NULL;
         }
-        return set_string_flag(real_name, value, origin);
+        return set_string_flag(flag, value, origin);
       }
     } else {
       warn_if_deprecated = false; // if arg is deprecated, we've already done warning...
@@ -1096,7 +1096,8 @@
     if (real_name == NULL) {
       return false;
     }
-    return set_string_flag(real_name, value, origin);
+    JVMFlag* flag = JVMFlag::find_flag(real_name);
+    return set_string_flag(flag, value, origin);
   }
 
 #define SIGNED_FP_NUMBER_RANGE "[-0123456789.eE+]"
@@ -1111,7 +1112,8 @@
       if (real_name == NULL) {
         return false;
       }
-      return set_fp_numeric_flag(real_name, value, origin);
+      JVMFlag* flag = JVMFlag::find_flag(real_name);
+      return set_fp_numeric_flag(flag, value, origin);
     }
   }
 
@@ -1121,7 +1123,8 @@
     if (real_name == NULL) {
       return false;
     }
-    return set_numeric_flag(real_name, value, origin);
+    JVMFlag* flag = JVMFlag::find_flag(real_name);
+    return set_numeric_flag(flag, value, origin);
   }
 
   return false;
@@ -1277,7 +1280,7 @@
 
   // For locked flags, report a custom error message if available.
   // Otherwise, report the standard unrecognized VM option.
-  JVMFlag* found_flag = JVMFlag::find_flag((const char*)argname, arg_len, true, true);
+  const JVMFlag* found_flag = JVMFlag::find_declared_flag((const char*)argname, arg_len);
   if (found_flag != NULL) {
     char locked_message_buf[BUFLEN];
     JVMFlag::MsgType msg_type = found_flag->get_locked_message(locked_message_buf, BUFLEN);
--- a/src/hotspot/share/runtime/basicLock.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/basicLock.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,7 +25,7 @@
 #ifndef SHARE_RUNTIME_BASICLOCK_HPP
 #define SHARE_RUNTIME_BASICLOCK_HPP
 
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.hpp"
 
--- a/src/hotspot/share/runtime/biasedLocking.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/biasedLocking.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -29,7 +29,7 @@
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/klass.inline.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/basicLock.hpp"
@@ -157,7 +157,7 @@
 
 // After the call, *biased_locker will be set to obj->mark()->biased_locker() if biased_locker != NULL,
 // AND it is a living thread. Otherwise it will not be updated, (i.e. the caller is responsible for initialization).
-BiasedLocking::Condition BiasedLocking::single_revoke_at_safepoint(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
+void BiasedLocking::single_revoke_at_safepoint(oop obj, bool is_bulk, JavaThread* requesting_thread, JavaThread** biased_locker) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
   assert(Thread::current()->is_VM_thread(), "must be VMThread");
 
@@ -173,11 +173,10 @@
                               obj->klass()->external_name(),
                               (intptr_t) requesting_thread);
     }
-    return NOT_BIASED;
+    return;
   }
 
   uint age = mark.age();
-  markWord   biased_prototype = markWord::biased_locking_prototype().set_age(age);
   markWord unbiased_prototype = markWord::prototype().set_age(age);
 
   // Log at "info" level if not bulk, else "trace" level
@@ -185,23 +184,21 @@
     ResourceMark rm;
     log_info(biasedlocking)("Revoking bias of object " INTPTR_FORMAT ", mark "
                             INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT
-                            ", allow rebias %d, requesting thread " INTPTR_FORMAT,
+                            ", requesting thread " INTPTR_FORMAT,
                             p2i((void *)obj),
                             mark.value(),
                             obj->klass()->external_name(),
                             obj->klass()->prototype_header().value(),
-                            (allow_rebias ? 1 : 0),
                             (intptr_t) requesting_thread);
   } else {
     ResourceMark rm;
     log_trace(biasedlocking)("Revoking bias of object " INTPTR_FORMAT " , mark "
                              INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT
-                             " , allow rebias %d , requesting thread " INTPTR_FORMAT,
+                             " , requesting thread " INTPTR_FORMAT,
                              p2i((void *)obj),
                              mark.value(),
                              obj->klass()->external_name(),
                              obj->klass()->prototype_header().value(),
-                             (allow_rebias ? 1 : 0),
                              (intptr_t) requesting_thread);
   }
 
@@ -210,16 +207,15 @@
     // Object is anonymously biased. We can get here if, for
     // example, we revoke the bias due to an identity hash code
     // being computed for an object.
-    if (!allow_rebias) {
-      obj->set_mark(unbiased_prototype);
-    }
+    obj->set_mark(unbiased_prototype);
+
     // Log at "info" level if not bulk, else "trace" level
     if (!is_bulk) {
       log_info(biasedlocking)("  Revoked bias of anonymously-biased object");
     } else {
       log_trace(biasedlocking)("  Revoked bias of anonymously-biased object");
     }
-    return BIAS_REVOKED;
+    return;
   }
 
   // Handle case where the thread toward which the object was biased has exited
@@ -231,11 +227,7 @@
     thread_is_alive = tlh.includes(biased_thread);
   }
   if (!thread_is_alive) {
-    if (allow_rebias) {
-      obj->set_mark(biased_prototype);
-    } else {
-      obj->set_mark(unbiased_prototype);
-    }
+    obj->set_mark(unbiased_prototype);
     // Log at "info" level if not bulk, else "trace" level
     if (!is_bulk) {
       log_info(biasedlocking)("  Revoked bias of object biased toward dead thread ("
@@ -244,7 +236,7 @@
       log_trace(biasedlocking)("  Revoked bias of object biased toward dead thread ("
                                PTR_FORMAT ")", p2i(biased_thread));
     }
-    return BIAS_REVOKED;
+    return;
   }
 
   // Log at "info" level if not bulk, else "trace" level
@@ -301,20 +293,14 @@
     } else {
       log_trace(biasedlocking)("  Revoked bias of currently-unlocked object");
     }
-    if (allow_rebias) {
-      obj->set_mark(biased_prototype);
-    } else {
-      // Store the unlocked value into the object's header.
-      obj->set_mark(unbiased_prototype);
-    }
+    // Store the unlocked value into the object's header.
+    obj->set_mark(unbiased_prototype);
   }
 
   // If requested, return information on which thread held the bias
   if (biased_locker != NULL) {
     *biased_locker = biased_thread;
   }
-
-  return BIAS_REVOKED;
 }
 
 
@@ -379,10 +365,7 @@
 }
 
 
-BiasedLocking::Condition BiasedLocking::bulk_revoke_or_rebias_at_safepoint(oop o,
-                                                                   bool bulk_rebias,
-                                                                   bool attempt_rebias_of_object,
-                                                                   JavaThread* requesting_thread) {
+void BiasedLocking::bulk_revoke_at_safepoint(oop o, bool bulk_rebias, JavaThread* requesting_thread) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be done at safepoint");
   assert(Thread::current()->is_VM_thread(), "must be VMThread");
 
@@ -437,7 +420,7 @@
 
       // At this point we're done. All we have to do is potentially
       // adjust the header of the given object to revoke its bias.
-      single_revoke_at_safepoint(o, attempt_rebias_of_object && klass->prototype_header().has_bias_pattern(), true, requesting_thread, NULL);
+      single_revoke_at_safepoint(o, true, requesting_thread, NULL);
     } else {
       if (log_is_enabled(Info, biasedlocking)) {
         ResourceMark rm;
@@ -459,36 +442,20 @@
           oop owner = mon_info->owner();
           markWord mark = owner->mark();
           if ((owner->klass() == k_o) && mark.has_bias_pattern()) {
-            single_revoke_at_safepoint(owner, false, true, requesting_thread, NULL);
+            single_revoke_at_safepoint(owner, true, requesting_thread, NULL);
           }
         }
       }
 
       // Must force the bias of the passed object to be forcibly revoked
       // as well to ensure guarantees to callers
-      single_revoke_at_safepoint(o, false, true, requesting_thread, NULL);
+      single_revoke_at_safepoint(o, true, requesting_thread, NULL);
     }
   } // ThreadsListHandle is destroyed here.
 
   log_info(biasedlocking)("* Ending bulk revocation");
 
-  BiasedLocking::Condition status_code = BIAS_REVOKED;
-
-  if (attempt_rebias_of_object &&
-      o->mark().has_bias_pattern() &&
-      klass->prototype_header().has_bias_pattern()) {
-    markWord new_mark = markWord::encode(requesting_thread, o->mark().age(),
-                                         klass->prototype_header().bias_epoch());
-    o->set_mark(new_mark);
-    status_code = BIAS_REVOKED_AND_REBIASED;
-    log_info(biasedlocking)("  Rebiased object toward thread " INTPTR_FORMAT, (intptr_t) requesting_thread);
-  }
-
-  assert(!o->mark().has_bias_pattern() ||
-         (attempt_rebias_of_object && (o->mark().biased_locker() == requesting_thread)),
-         "bug in bulk bias revocation");
-
-  return status_code;
+  assert(!o->mark().has_bias_pattern(), "bug in bulk bias revocation");
 }
 
 
@@ -509,25 +476,20 @@
   Handle* _obj;
   JavaThread* _requesting_thread;
   bool _bulk_rebias;
-  bool _attempt_rebias_of_object;
-  BiasedLocking::Condition _status_code;
   uint64_t _safepoint_id;
 
 public:
   VM_BulkRevokeBias(Handle* obj, JavaThread* requesting_thread,
-                    bool bulk_rebias,
-                    bool attempt_rebias_of_object)
+                    bool bulk_rebias)
     : _obj(obj)
     , _requesting_thread(requesting_thread)
     , _bulk_rebias(bulk_rebias)
-    , _attempt_rebias_of_object(attempt_rebias_of_object)
-    , _status_code(BiasedLocking::NOT_BIASED)
     , _safepoint_id(0) {}
 
   virtual VMOp_Type type() const { return VMOp_BulkRevokeBias; }
 
   virtual void doit() {
-    _status_code = BiasedLocking::bulk_revoke_or_rebias_at_safepoint((*_obj)(), _bulk_rebias, _attempt_rebias_of_object, _requesting_thread);
+    BiasedLocking::bulk_revoke_at_safepoint((*_obj)(), _bulk_rebias, _requesting_thread);
     _safepoint_id = SafepointSynchronize::safepoint_id();
     clean_up_cached_monitor_info();
   }
@@ -536,10 +498,6 @@
     return _bulk_rebias;
   }
 
-  BiasedLocking::Condition status_code() const {
-    return _status_code;
-  }
-
   uint64_t safepoint_id() const {
     return _safepoint_id;
   }
@@ -769,7 +727,7 @@
 }
 
 
-BiasedLocking::Condition BiasedLocking::revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS) {
+void BiasedLocking::revoke(Handle obj, TRAPS) {
   assert(!SafepointSynchronize::is_at_safepoint(), "must not be called while at safepoint");
 
   while (true) {
@@ -778,7 +736,12 @@
     // update the heuristics because doing so may cause unwanted bulk
     // revocations (which are expensive) to occur.
     markWord mark = obj->mark();
-    if (mark.is_biased_anonymously() && !attempt_rebias) {
+
+    if (!mark.has_bias_pattern()) {
+      return;
+    }
+
+    if (mark.is_biased_anonymously()) {
       // We are probably trying to revoke the bias of this object due to
       // an identity hash code computation. Try to revoke the bias
       // without a safepoint. This is possible if we can successfully
@@ -789,10 +752,10 @@
       markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
       markWord res_mark = obj->cas_set_mark(unbiased_prototype, mark);
       if (res_mark == biased_value) {
-        return BIAS_REVOKED;
+        return;
       }
       mark = res_mark;  // Refresh mark with the latest value.
-    } else if (mark.has_bias_pattern()) {
+    } else {
       Klass* k = obj->klass();
       markWord prototype_header = k->prototype_header();
       if (!prototype_header.has_bias_pattern()) {
@@ -804,31 +767,20 @@
         // with it.
         obj->cas_set_mark(prototype_header.set_age(mark.age()), mark);
         assert(!obj->mark().has_bias_pattern(), "even if we raced, should still be revoked");
-        return BIAS_REVOKED;
+        return;
       } else if (prototype_header.bias_epoch() != mark.bias_epoch()) {
         // The epoch of this biasing has expired indicating that the
-        // object is effectively unbiased. Depending on whether we need
-        // to rebias or revoke the bias of this object we can do it
-        // efficiently enough with a CAS that we shouldn't update the
+        // object is effectively unbiased. We can revoke the bias of this
+        // object efficiently enough with a CAS that we shouldn't update the
         // heuristics. This is normally done in the assembly code but we
         // can reach this point due to various points in the runtime
         // needing to revoke biases.
         markWord res_mark;
-        if (attempt_rebias) {
-          assert(THREAD->is_Java_thread(), "");
-          markWord biased_value       = mark;
-          markWord rebiased_prototype = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
-          res_mark = obj->cas_set_mark(rebiased_prototype, mark);
-          if (res_mark == biased_value) {
-            return BIAS_REVOKED_AND_REBIASED;
-          }
-        } else {
-          markWord biased_value       = mark;
-          markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
-          res_mark = obj->cas_set_mark(unbiased_prototype, mark);
-          if (res_mark == biased_value) {
-            return BIAS_REVOKED;
-          }
+        markWord biased_value       = mark;
+        markWord unbiased_prototype = markWord::prototype().set_age(mark.age());
+        res_mark = obj->cas_set_mark(unbiased_prototype, mark);
+        if (res_mark == biased_value) {
+          return;
         }
         mark = res_mark;  // Refresh mark with the latest value.
       }
@@ -836,7 +788,7 @@
 
     HeuristicsResult heuristics = update_heuristics(obj());
     if (heuristics == HR_NOT_BIASED) {
-      return NOT_BIASED;
+      return;
     } else if (heuristics == HR_SINGLE_REVOKE) {
       JavaThread *blt = mark.biased_locker();
       assert(blt != NULL, "invariant");
@@ -855,11 +807,11 @@
         if (event.should_commit()) {
           post_self_revocation_event(&event, obj->klass());
         }
-        return BIAS_REVOKED;
+        return;
       } else {
         BiasedLocking::Condition cond = single_revoke_with_handshake(obj, (JavaThread*)THREAD, blt);
         if (cond != NOT_REVOKED) {
-          return cond;
+          return;
         }
       }
     } else {
@@ -867,13 +819,12 @@
          (heuristics == HR_BULK_REBIAS), "?");
       EventBiasedLockClassRevocation event;
       VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*)THREAD,
-                                    (heuristics == HR_BULK_REBIAS),
-                                    attempt_rebias);
+                                    (heuristics == HR_BULK_REBIAS));
       VMThread::execute(&bulk_revoke);
       if (event.should_commit()) {
         post_class_revocation_event(&event, obj->klass(), &bulk_revoke);
       }
-      return bulk_revoke.status_code();
+      return;
     }
   }
 }
@@ -901,13 +852,13 @@
   HeuristicsResult heuristics = update_heuristics(obj);
   if (heuristics == HR_SINGLE_REVOKE) {
     JavaThread* biased_locker = NULL;
-    single_revoke_at_safepoint(obj, false, false, NULL, &biased_locker);
+    single_revoke_at_safepoint(obj, false, NULL, &biased_locker);
     if (biased_locker) {
       clean_up_cached_monitor_info(biased_locker);
     }
   } else if ((heuristics == HR_BULK_REBIAS) ||
              (heuristics == HR_BULK_REVOKE)) {
-    bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
+    bulk_revoke_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), NULL);
     clean_up_cached_monitor_info();
   }
 }
@@ -920,10 +871,10 @@
     oop obj = (objs->at(i))();
     HeuristicsResult heuristics = update_heuristics(obj);
     if (heuristics == HR_SINGLE_REVOKE) {
-      single_revoke_at_safepoint(obj, false, false, NULL, NULL);
+      single_revoke_at_safepoint(obj, false, NULL, NULL);
     } else if ((heuristics == HR_BULK_REBIAS) ||
                (heuristics == HR_BULK_REVOKE)) {
-      bulk_revoke_or_rebias_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), false, NULL);
+      bulk_revoke_at_safepoint(obj, (heuristics == HR_BULK_REBIAS), NULL);
     }
   }
   clean_up_cached_monitor_info();
--- a/src/hotspot/share/runtime/biasedLocking.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/biasedLocking.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -168,13 +168,12 @@
   enum Condition {
     NOT_BIASED = 1,
     BIAS_REVOKED = 2,
-    BIAS_REVOKED_AND_REBIASED = 3,
-    NOT_REVOKED = 4
+    NOT_REVOKED = 3
   };
 
 private:
-  static Condition single_revoke_at_safepoint(oop obj, bool allow_rebias, bool is_bulk, JavaThread* requester, JavaThread** biaser);
-  static Condition bulk_revoke_or_rebias_at_safepoint(oop o, bool bulk_rebias, bool attempt_rebias, JavaThread* requester);
+  static void single_revoke_at_safepoint(oop obj, bool is_bulk, JavaThread* requester, JavaThread** biaser);
+  static void bulk_revoke_at_safepoint(oop o, bool bulk_rebias, JavaThread* requester);
   static Condition single_revoke_with_handshake(Handle obj, JavaThread *requester, JavaThread *biaser);
   static void walk_stack_and_revoke(oop obj, JavaThread* biased_locker);
 
@@ -189,12 +188,13 @@
   static bool enabled();
 
   // This should be called by JavaThreads to revoke the bias of an object
-  static Condition revoke_and_rebias(Handle obj, bool attempt_rebias, TRAPS);
+  static void revoke(Handle obj, TRAPS);
+
+  static void revoke_at_safepoint(Handle obj);
 
-  // These do not allow rebiasing; they are used by deoptimization to
-  // ensure that monitors on the stack can be migrated
+  // These are used by deoptimization to ensure that monitors on the stack
+  // can be migrated
   static void revoke(GrowableArray<Handle>* objs, JavaThread *biaser);
-  static void revoke_at_safepoint(Handle obj);
   static void revoke_at_safepoint(GrowableArray<Handle>* objs);
 
   static void print_counters() { _counters.print(); }
--- a/src/hotspot/share/runtime/deoptimization.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1264,7 +1264,7 @@
           obj->set_mark(unbiased_prototype);
         }
         BasicLock* lock = mon_info->lock();
-        ObjectSynchronizer::slow_enter(obj, lock, thread);
+        ObjectSynchronizer::enter(obj, lock, thread);
         assert(mon_info->owner()->is_locked(), "object must be locked now");
       }
     }
@@ -1374,7 +1374,7 @@
       for (int j = 0; j < monitors->number_of_monitors(); j++) {
         BasicObjectLock* src = monitors->at(j);
         if (src->obj() != NULL) {
-          ObjectSynchronizer::fast_exit(src->obj(), src->lock(), thread);
+          ObjectSynchronizer::exit(src->obj(), src->lock(), thread);
         }
       }
       array->element(i)->free_monitors(thread);
--- a/src/hotspot/share/runtime/flags/jvmFlag.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/flags/jvmFlag.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -604,7 +604,7 @@
       st->cr();
       return;
     }
-    JVMFlagRangeList::print(st, _name, func);
+    JVMFlagRangeList::print(st, this, func);
 
     fill_to_pos(st, col5_pos);
     print_kind(st, col5_width);
@@ -957,103 +957,82 @@
 }
 
 // Returns the address of the index'th element
-static JVMFlag* address_of_flag(JVMFlagsEnum flag) {
+JVMFlag* JVMFlagEx::flag_from_enum(JVMFlagsEnum flag) {
   assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index");
   return &JVMFlag::flags[flag];
 }
 
 bool JVMFlagEx::is_default(JVMFlagsEnum flag) {
-  assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index");
-  JVMFlag* f = &JVMFlag::flags[flag];
-  return f->is_default();
+  return flag_from_enum(flag)->is_default();
 }
 
 bool JVMFlagEx::is_ergo(JVMFlagsEnum flag) {
-  assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index");
-  JVMFlag* f = &JVMFlag::flags[flag];
-  return f->is_ergonomic();
+  return flag_from_enum(flag)->is_ergonomic();
 }
 
 bool JVMFlagEx::is_cmdline(JVMFlagsEnum flag) {
-  assert((size_t)flag < JVMFlag::numFlags, "bad command line flag index");
-  JVMFlag* f = &JVMFlag::flags[flag];
-  return f->is_command_line();
-}
-
-bool JVMFlag::wasSetOnCmdline(const char* name, bool* value) {
-  JVMFlag* result = JVMFlag::find_flag((char*)name, strlen(name));
-  if (result == NULL) return false;
-  *value = result->is_command_line();
-  return true;
+  return flag_from_enum(flag)->is_command_line();
 }
 
 void JVMFlagEx::setOnCmdLine(JVMFlagsEnum flag) {
-  JVMFlag* faddr = address_of_flag(flag);
+  JVMFlag* faddr = flag_from_enum(flag);
   assert(faddr != NULL, "Unknown flag");
   faddr->set_command_line();
 }
 
 template<class E, class T>
-static void trace_flag_changed(const char* name, const T old_value, const T new_value, const JVMFlag::Flags origin) {
+static void trace_flag_changed(const JVMFlag* flag, const T old_value, const T new_value, const JVMFlag::Flags origin) {
   E e;
-  e.set_name(name);
+  e.set_name(flag->_name);
   e.set_oldValue(old_value);
   e.set_newValue(new_value);
   e.set_origin(origin);
   e.commit();
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_bool(const char* name, bool new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_bool(const JVMFlag* flag, bool new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name);
+  JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
   if (constraint != NULL) {
     status = constraint->apply_bool(new_value, verbose);
   }
   return status;
 }
 
-JVMFlag::Error JVMFlag::boolAt(const char* name, size_t len, bool* value, bool allow_locked, bool return_flag) {
-  JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return JVMFlag::INVALID_FLAG;
-  if (!result->is_bool()) return JVMFlag::WRONG_FORMAT;
-  *value = result->get_bool();
+JVMFlag::Error JVMFlag::boolAt(const JVMFlag* flag, bool* value) {
+  if (flag == NULL) return JVMFlag::INVALID_FLAG;
+  if (!flag->is_bool()) return JVMFlag::WRONG_FORMAT;
+  *value = flag->get_bool();
   return JVMFlag::SUCCESS;
 }
 
 JVMFlag::Error JVMFlag::boolAtPut(JVMFlag* flag, bool* value, JVMFlag::Flags origin) {
-  const char* name;
   if (flag == NULL) return JVMFlag::INVALID_FLAG;
   if (!flag->is_bool()) return JVMFlag::WRONG_FORMAT;
-  name = flag->_name;
-  JVMFlag::Error check = apply_constraint_and_check_range_bool(name, *value, !JVMFlagConstraintList::validated_after_ergo());
+  JVMFlag::Error check = apply_constraint_and_check_range_bool(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
   if (check != JVMFlag::SUCCESS) return check;
   bool old_value = flag->get_bool();
-  trace_flag_changed<EventBooleanFlagChanged, bool>(name, old_value, *value, origin);
+  trace_flag_changed<EventBooleanFlagChanged, bool>(flag, old_value, *value, origin);
   check = flag->set_bool(*value);
   *value = old_value;
   flag->set_origin(origin);
   return check;
 }
 
-JVMFlag::Error JVMFlag::boolAtPut(const char* name, size_t len, bool* value, JVMFlag::Flags origin) {
-  JVMFlag* result = JVMFlag::find_flag(name, len);
-  return boolAtPut(result, value, origin);
-}
-
 JVMFlag::Error JVMFlagEx::boolAtPut(JVMFlagsEnum flag, bool value, JVMFlag::Flags origin) {
-  JVMFlag* faddr = address_of_flag(flag);
+  JVMFlag* faddr = flag_from_enum(flag);
   guarantee(faddr != NULL && faddr->is_bool(), "wrong flag type");
   return JVMFlag::boolAtPut(faddr, &value, origin);
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_int(const char* name, int new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_int(const JVMFlag* flag, int new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(name);
+  JVMFlagRange* range = JVMFlagRangeList::find(flag);
   if (range != NULL) {
     status = range->check_int(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name);
+    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
     if (constraint != NULL) {
       status = constraint->apply_int(new_value, verbose);
     }
@@ -1061,48 +1040,40 @@
   return status;
 }
 
-JVMFlag::Error JVMFlag::intAt(const char* name, size_t len, int* value, bool allow_locked, bool return_flag) {
-  JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return JVMFlag::INVALID_FLAG;
-  if (!result->is_int()) return JVMFlag::WRONG_FORMAT;
-  *value = result->get_int();
+JVMFlag::Error JVMFlag::intAt(const JVMFlag* flag, int* value) {
+  if (flag == NULL) return JVMFlag::INVALID_FLAG;
+  if (!flag->is_int()) return JVMFlag::WRONG_FORMAT;
+  *value = flag->get_int();
   return JVMFlag::SUCCESS;
 }
 
 JVMFlag::Error JVMFlag::intAtPut(JVMFlag* flag, int* value, JVMFlag::Flags origin) {
-  const char* name;
   if (flag == NULL) return JVMFlag::INVALID_FLAG;
   if (!flag->is_int()) return JVMFlag::WRONG_FORMAT;
-  name = flag->_name;
-  JVMFlag::Error check = apply_constraint_and_check_range_int(name, *value, !JVMFlagConstraintList::validated_after_ergo());
+  JVMFlag::Error check = apply_constraint_and_check_range_int(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
   if (check != JVMFlag::SUCCESS) return check;
   int old_value = flag->get_int();
-  trace_flag_changed<EventIntFlagChanged, s4>(name, old_value, *value, origin);
+  trace_flag_changed<EventIntFlagChanged, s4>(flag, old_value, *value, origin);
   check = flag->set_int(*value);
   *value = old_value;
   flag->set_origin(origin);
   return check;
 }
 
-JVMFlag::Error JVMFlag::intAtPut(const char* name, size_t len, int* value, JVMFlag::Flags origin) {
-  JVMFlag* result = JVMFlag::find_flag(name, len);
-  return intAtPut(result, value, origin);
-}
-
 JVMFlag::Error JVMFlagEx::intAtPut(JVMFlagsEnum flag, int value, JVMFlag::Flags origin) {
-  JVMFlag* faddr = address_of_flag(flag);
+  JVMFlag* faddr = flag_from_enum(flag);
   guarantee(faddr != NULL && faddr->is_int(), "wrong flag type");
   return JVMFlag::intAtPut(faddr, &value, origin);
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_uint(const char* name, uint new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_uint(const JVMFlag* flag, uint new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(name);
+  JVMFlagRange* range = JVMFlagRangeList::find(flag);
   if (range != NULL) {
     status = range->check_uint(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name);
+    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
     if (constraint != NULL) {
       status = constraint->apply_uint(new_value, verbose);
     }
@@ -1110,56 +1081,47 @@
   return status;
 }
 
-JVMFlag::Error JVMFlag::uintAt(const char* name, size_t len, uint* value, bool allow_locked, bool return_flag) {
-  JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return JVMFlag::INVALID_FLAG;
-  if (!result->is_uint()) return JVMFlag::WRONG_FORMAT;
-  *value = result->get_uint();
+JVMFlag::Error JVMFlag::uintAt(const JVMFlag* flag, uint* value) {
+  if (flag == NULL) return JVMFlag::INVALID_FLAG;
+  if (!flag->is_uint()) return JVMFlag::WRONG_FORMAT;
+  *value = flag->get_uint();
   return JVMFlag::SUCCESS;
 }
 
 JVMFlag::Error JVMFlag::uintAtPut(JVMFlag* flag, uint* value, JVMFlag::Flags origin) {
-  const char* name;
   if (flag == NULL) return JVMFlag::INVALID_FLAG;
   if (!flag->is_uint()) return JVMFlag::WRONG_FORMAT;
-  name = flag->_name;
-  JVMFlag::Error check = apply_constraint_and_check_range_uint(name, *value, !JVMFlagConstraintList::validated_after_ergo());
+  JVMFlag::Error check = apply_constraint_and_check_range_uint(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
   if (check != JVMFlag::SUCCESS) return check;
   uint old_value = flag->get_uint();
-  trace_flag_changed<EventUnsignedIntFlagChanged, u4>(name, old_value, *value, origin);
+  trace_flag_changed<EventUnsignedIntFlagChanged, u4>(flag, old_value, *value, origin);
   check = flag->set_uint(*value);
   *value = old_value;
   flag->set_origin(origin);
   return check;
 }
 
-JVMFlag::Error JVMFlag::uintAtPut(const char* name, size_t len, uint* value, JVMFlag::Flags origin) {
-  JVMFlag* result = JVMFlag::find_flag(name, len);
-  return uintAtPut(result, value, origin);
-}
-
 JVMFlag::Error JVMFlagEx::uintAtPut(JVMFlagsEnum flag, uint value, JVMFlag::Flags origin) {
-  JVMFlag* faddr = address_of_flag(flag);
+  JVMFlag* faddr = flag_from_enum(flag);
   guarantee(faddr != NULL && faddr->is_uint(), "wrong flag type");
   return JVMFlag::uintAtPut(faddr, &value, origin);
 }
 
-JVMFlag::Error JVMFlag::intxAt(const char* name, size_t len, intx* value, bool allow_locked, bool return_flag) {
-  JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return JVMFlag::INVALID_FLAG;
-  if (!result->is_intx()) return JVMFlag::WRONG_FORMAT;
-  *value = result->get_intx();
+JVMFlag::Error JVMFlag::intxAt(const JVMFlag* flag, intx* value) {
+  if (flag == NULL) return JVMFlag::INVALID_FLAG;
+  if (!flag->is_intx()) return JVMFlag::WRONG_FORMAT;
+  *value = flag->get_intx();
   return JVMFlag::SUCCESS;
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_intx(const char* name, intx new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_intx(const JVMFlag* flag, intx new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(name);
+  JVMFlagRange* range = JVMFlagRangeList::find(flag);
   if (range != NULL) {
     status = range->check_intx(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name);
+    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
     if (constraint != NULL) {
       status = constraint->apply_intx(new_value, verbose);
     }
@@ -1168,47 +1130,39 @@
 }
 
 JVMFlag::Error JVMFlag::intxAtPut(JVMFlag* flag, intx* value, JVMFlag::Flags origin) {
-  const char* name;
   if (flag == NULL) return JVMFlag::INVALID_FLAG;
   if (!flag->is_intx()) return JVMFlag::WRONG_FORMAT;
-  name = flag->_name;
-  JVMFlag::Error check = apply_constraint_and_check_range_intx(name, *value, !JVMFlagConstraintList::validated_after_ergo());
+  JVMFlag::Error check = apply_constraint_and_check_range_intx(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
   if (check != JVMFlag::SUCCESS) return check;
   intx old_value = flag->get_intx();
-  trace_flag_changed<EventLongFlagChanged, intx>(name, old_value, *value, origin);
+  trace_flag_changed<EventLongFlagChanged, intx>(flag, old_value, *value, origin);
   check = flag->set_intx(*value);
   *value = old_value;
   flag->set_origin(origin);
   return check;
 }
 
-JVMFlag::Error JVMFlag::intxAtPut(const char* name, size_t len, intx* value, JVMFlag::Flags origin) {
-  JVMFlag* result = JVMFlag::find_flag(name, len);
-  return intxAtPut(result, value, origin);
-}
-
 JVMFlag::Error JVMFlagEx::intxAtPut(JVMFlagsEnum flag, intx value, JVMFlag::Flags origin) {
-  JVMFlag* faddr = address_of_flag(flag);
+  JVMFlag* faddr = flag_from_enum(flag);
   guarantee(faddr != NULL && faddr->is_intx(), "wrong flag type");
   return JVMFlag::intxAtPut(faddr, &value, origin);
 }
 
-JVMFlag::Error JVMFlag::uintxAt(const char* name, size_t len, uintx* value, bool allow_locked, bool return_flag) {
-  JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return JVMFlag::INVALID_FLAG;
-  if (!result->is_uintx()) return JVMFlag::WRONG_FORMAT;
-  *value = result->get_uintx();
+JVMFlag::Error JVMFlag::uintxAt(const JVMFlag* flag, uintx* value) {
+  if (flag == NULL) return JVMFlag::INVALID_FLAG;
+  if (!flag->is_uintx()) return JVMFlag::WRONG_FORMAT;
+  *value = flag->get_uintx();
   return JVMFlag::SUCCESS;
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_uintx(const char* name, uintx new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_uintx(const JVMFlag* flag, uintx new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(name);
+  JVMFlagRange* range = JVMFlagRangeList::find(flag);
   if (range != NULL) {
     status = range->check_uintx(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name);
+    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
     if (constraint != NULL) {
       status = constraint->apply_uintx(new_value, verbose);
     }
@@ -1217,47 +1171,39 @@
 }
 
 JVMFlag::Error JVMFlag::uintxAtPut(JVMFlag* flag, uintx* value, JVMFlag::Flags origin) {
-  const char* name;
   if (flag == NULL) return JVMFlag::INVALID_FLAG;
   if (!flag->is_uintx()) return JVMFlag::WRONG_FORMAT;
-  name = flag->_name;
-  JVMFlag::Error check = apply_constraint_and_check_range_uintx(name, *value, !JVMFlagConstraintList::validated_after_ergo());
+  JVMFlag::Error check = apply_constraint_and_check_range_uintx(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
   if (check != JVMFlag::SUCCESS) return check;
   uintx old_value = flag->get_uintx();
-  trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
+  trace_flag_changed<EventUnsignedLongFlagChanged, u8>(flag, old_value, *value, origin);
   check = flag->set_uintx(*value);
   *value = old_value;
   flag->set_origin(origin);
   return check;
 }
 
-JVMFlag::Error JVMFlag::uintxAtPut(const char* name, size_t len, uintx* value, JVMFlag::Flags origin) {
-  JVMFlag* result = JVMFlag::find_flag(name, len);
-  return uintxAtPut(result, value, origin);
-}
-
 JVMFlag::Error JVMFlagEx::uintxAtPut(JVMFlagsEnum flag, uintx value, JVMFlag::Flags origin) {
-  JVMFlag* faddr = address_of_flag(flag);
+  JVMFlag* faddr = flag_from_enum(flag);
   guarantee(faddr != NULL && faddr->is_uintx(), "wrong flag type");
   return JVMFlag::uintxAtPut(faddr, &value, origin);
 }
 
-JVMFlag::Error JVMFlag::uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked, bool return_flag) {
-  JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return JVMFlag::INVALID_FLAG;
-  if (!result->is_uint64_t()) return JVMFlag::WRONG_FORMAT;
-  *value = result->get_uint64_t();
+JVMFlag::Error JVMFlag::uint64_tAt(const JVMFlag* flag, uint64_t* value) {
+  if (flag == NULL) return JVMFlag::INVALID_FLAG;
+  if (!flag->is_uint64_t()) return JVMFlag::WRONG_FORMAT;
+  *value = flag->get_uint64_t();
   return JVMFlag::SUCCESS;
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_uint64_t(const char* name, uint64_t new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_uint64_t(const JVMFlag* flag, uint64_t new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(name);
+  JVMFlagRange* range = JVMFlagRangeList::find(flag);
   if (range != NULL) {
     status = range->check_uint64_t(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name);
+    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
     if (constraint != NULL) {
       status = constraint->apply_uint64_t(new_value, verbose);
     }
@@ -1266,47 +1212,39 @@
 }
 
 JVMFlag::Error JVMFlag::uint64_tAtPut(JVMFlag* flag, uint64_t* value, JVMFlag::Flags origin) {
-  const char* name;
   if (flag == NULL) return JVMFlag::INVALID_FLAG;
   if (!flag->is_uint64_t()) return JVMFlag::WRONG_FORMAT;
-  name = flag->_name;
-  JVMFlag::Error check = apply_constraint_and_check_range_uint64_t(name, *value, !JVMFlagConstraintList::validated_after_ergo());
+  JVMFlag::Error check = apply_constraint_and_check_range_uint64_t(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
   if (check != JVMFlag::SUCCESS) return check;
   uint64_t old_value = flag->get_uint64_t();
-  trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
+  trace_flag_changed<EventUnsignedLongFlagChanged, u8>(flag, old_value, *value, origin);
   check = flag->set_uint64_t(*value);
   *value = old_value;
   flag->set_origin(origin);
   return check;
 }
 
-JVMFlag::Error JVMFlag::uint64_tAtPut(const char* name, size_t len, uint64_t* value, JVMFlag::Flags origin) {
-  JVMFlag* result = JVMFlag::find_flag(name, len);
-  return uint64_tAtPut(result, value, origin);
-}
-
 JVMFlag::Error JVMFlagEx::uint64_tAtPut(JVMFlagsEnum flag, uint64_t value, JVMFlag::Flags origin) {
-  JVMFlag* faddr = address_of_flag(flag);
+  JVMFlag* faddr = flag_from_enum(flag);
   guarantee(faddr != NULL && faddr->is_uint64_t(), "wrong flag type");
   return JVMFlag::uint64_tAtPut(faddr, &value, origin);
 }
 
-JVMFlag::Error JVMFlag::size_tAt(const char* name, size_t len, size_t* value, bool allow_locked, bool return_flag) {
-  JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return JVMFlag::INVALID_FLAG;
-  if (!result->is_size_t()) return JVMFlag::WRONG_FORMAT;
-  *value = result->get_size_t();
+JVMFlag::Error JVMFlag::size_tAt(const JVMFlag* flag, size_t* value) {
+  if (flag == NULL) return JVMFlag::INVALID_FLAG;
+  if (!flag->is_size_t()) return JVMFlag::WRONG_FORMAT;
+  *value = flag->get_size_t();
   return JVMFlag::SUCCESS;
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_size_t(const char* name, size_t new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_size_t(const JVMFlag* flag, size_t new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(name);
+  JVMFlagRange* range = JVMFlagRangeList::find(flag);
   if (range != NULL) {
     status = range->check_size_t(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name);
+    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
     if (constraint != NULL) {
       status = constraint->apply_size_t(new_value, verbose);
     }
@@ -1316,47 +1254,39 @@
 
 
 JVMFlag::Error JVMFlag::size_tAtPut(JVMFlag* flag, size_t* value, JVMFlag::Flags origin) {
-  const char* name;
   if (flag == NULL) return JVMFlag::INVALID_FLAG;
   if (!flag->is_size_t()) return JVMFlag::WRONG_FORMAT;
-  name = flag->_name;
-  JVMFlag::Error check = apply_constraint_and_check_range_size_t(name, *value, !JVMFlagConstraintList::validated_after_ergo());
+  JVMFlag::Error check = apply_constraint_and_check_range_size_t(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
   if (check != JVMFlag::SUCCESS) return check;
   size_t old_value = flag->get_size_t();
-  trace_flag_changed<EventUnsignedLongFlagChanged, u8>(name, old_value, *value, origin);
+  trace_flag_changed<EventUnsignedLongFlagChanged, u8>(flag, old_value, *value, origin);
   check = flag->set_size_t(*value);
   *value = old_value;
   flag->set_origin(origin);
   return check;
 }
 
-JVMFlag::Error JVMFlag::size_tAtPut(const char* name, size_t len, size_t* value, JVMFlag::Flags origin) {
-  JVMFlag* result = JVMFlag::find_flag(name, len);
-  return size_tAtPut(result, value, origin);
-}
-
 JVMFlag::Error JVMFlagEx::size_tAtPut(JVMFlagsEnum flag, size_t value, JVMFlag::Flags origin) {
-  JVMFlag* faddr = address_of_flag(flag);
+  JVMFlag* faddr = flag_from_enum(flag);
   guarantee(faddr != NULL && faddr->is_size_t(), "wrong flag type");
   return JVMFlag::size_tAtPut(faddr, &value, origin);
 }
 
-JVMFlag::Error JVMFlag::doubleAt(const char* name, size_t len, double* value, bool allow_locked, bool return_flag) {
-  JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return JVMFlag::INVALID_FLAG;
-  if (!result->is_double()) return JVMFlag::WRONG_FORMAT;
-  *value = result->get_double();
+JVMFlag::Error JVMFlag::doubleAt(const JVMFlag* flag, double* value) {
+  if (flag == NULL) return JVMFlag::INVALID_FLAG;
+  if (!flag->is_double()) return JVMFlag::WRONG_FORMAT;
+  *value = flag->get_double();
   return JVMFlag::SUCCESS;
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_double(const char* name, double new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_double(const JVMFlag* flag, double new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(name);
+  JVMFlagRange* range = JVMFlagRangeList::find(flag);
   if (range != NULL) {
     status = range->check_double(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(name);
+    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
     if (constraint != NULL) {
       status = constraint->apply_double(new_value, verbose);
     }
@@ -1365,64 +1295,55 @@
 }
 
 JVMFlag::Error JVMFlag::doubleAtPut(JVMFlag* flag, double* value, JVMFlag::Flags origin) {
-  const char* name;
   if (flag == NULL) return JVMFlag::INVALID_FLAG;
   if (!flag->is_double()) return JVMFlag::WRONG_FORMAT;
-  name = flag->_name;
-  JVMFlag::Error check = apply_constraint_and_check_range_double(name, *value, !JVMFlagConstraintList::validated_after_ergo());
+  JVMFlag::Error check = apply_constraint_and_check_range_double(flag, *value, !JVMFlagConstraintList::validated_after_ergo());
   if (check != JVMFlag::SUCCESS) return check;
   double old_value = flag->get_double();
-  trace_flag_changed<EventDoubleFlagChanged, double>(name, old_value, *value, origin);
+  trace_flag_changed<EventDoubleFlagChanged, double>(flag, old_value, *value, origin);
   check = flag->set_double(*value);
   *value = old_value;
   flag->set_origin(origin);
   return check;
 }
 
-JVMFlag::Error JVMFlag::doubleAtPut(const char* name, size_t len, double* value, JVMFlag::Flags origin) {
-  JVMFlag* result = JVMFlag::find_flag(name, len);
-  return doubleAtPut(result, value, origin);
-}
-
 JVMFlag::Error JVMFlagEx::doubleAtPut(JVMFlagsEnum flag, double value, JVMFlag::Flags origin) {
-  JVMFlag* faddr = address_of_flag(flag);
+  JVMFlag* faddr = flag_from_enum(flag);
   guarantee(faddr != NULL && faddr->is_double(), "wrong flag type");
   return JVMFlag::doubleAtPut(faddr, &value, origin);
 }
 
-JVMFlag::Error JVMFlag::ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked, bool return_flag) {
-  JVMFlag* result = JVMFlag::find_flag(name, len, allow_locked, return_flag);
-  if (result == NULL) return JVMFlag::INVALID_FLAG;
-  if (!result->is_ccstr()) return JVMFlag::WRONG_FORMAT;
-  *value = result->get_ccstr();
+JVMFlag::Error JVMFlag::ccstrAt(const JVMFlag* flag, ccstr* value) {
+  if (flag == NULL) return JVMFlag::INVALID_FLAG;
+  if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT;
+  *value = flag->get_ccstr();
   return JVMFlag::SUCCESS;
 }
 
-JVMFlag::Error JVMFlag::ccstrAtPut(const char* name, size_t len, ccstr* value, JVMFlag::Flags origin) {
-  JVMFlag* result = JVMFlag::find_flag(name, len);
-  if (result == NULL) return JVMFlag::INVALID_FLAG;
-  if (!result->is_ccstr()) return JVMFlag::WRONG_FORMAT;
-  ccstr old_value = result->get_ccstr();
-  trace_flag_changed<EventStringFlagChanged, const char*>(name, old_value, *value, origin);
+JVMFlag::Error JVMFlag::ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlag::Flags origin) {
+  if (flag == NULL) return JVMFlag::INVALID_FLAG;
+  if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT;
+  ccstr old_value = flag->get_ccstr();
+  trace_flag_changed<EventStringFlagChanged, const char*>(flag, old_value, *value, origin);
   char* new_value = NULL;
   if (*value != NULL) {
     new_value = os::strdup_check_oom(*value);
   }
-  JVMFlag::Error check = result->set_ccstr(new_value);
-  if (result->is_default() && old_value != NULL) {
+  JVMFlag::Error check = flag->set_ccstr(new_value);
+  if (flag->is_default() && old_value != NULL) {
     // Prior value is NOT heap allocated, but was a literal constant.
     old_value = os::strdup_check_oom(old_value);
   }
   *value = old_value;
-  result->set_origin(origin);
+  flag->set_origin(origin);
   return check;
 }
 
 JVMFlag::Error JVMFlagEx::ccstrAtPut(JVMFlagsEnum flag, ccstr value, JVMFlag::Flags origin) {
-  JVMFlag* faddr = address_of_flag(flag);
+  JVMFlag* faddr = flag_from_enum(flag);
   guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
   ccstr old_value = faddr->get_ccstr();
-  trace_flag_changed<EventStringFlagChanged, const char*>(faddr->_name, old_value, value, origin);
+  trace_flag_changed<EventStringFlagChanged, const char*>(faddr, old_value, value, origin);
   char* new_value = os::strdup_check_oom(value);
   JVMFlag::Error check = faddr->set_ccstr(new_value);
   if (!faddr->is_default() && old_value != NULL) {
--- a/src/hotspot/share/runtime/flags/jvmFlag.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/flags/jvmFlag.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -118,8 +118,20 @@
   // number of flags
   static size_t numFlags;
 
-  static JVMFlag* find_flag(const char* name) { return find_flag(name, strlen(name), true, true); };
-  static JVMFlag* find_flag(const char* name, size_t length, bool allow_locked = false, bool return_flag = false);
+private:
+  static JVMFlag* find_flag(const char* name, size_t length, bool allow_locked, bool return_flag);
+
+public:
+  static JVMFlag* find_flag(const char* name) {
+    return find_flag(name, strlen(name), false, false);
+  }
+  static const JVMFlag* find_declared_flag(const char* name, size_t length) {
+    return find_flag(name, length, true, true);
+  }
+  static const JVMFlag* find_declared_flag(const char* name) {
+    return find_declared_flag(name, strlen(name));
+  }
+
   static JVMFlag* fuzzy_match(const char* name, size_t length, bool allow_locked = false);
 
   static const char* get_int_default_range_str();
@@ -213,63 +225,35 @@
   static const char* flag_error_str(JVMFlag::Error error);
 
 public:
-  static JVMFlag::Error boolAt(const char* name, size_t len, bool* value, bool allow_locked = false, bool return_flag = false);
-  static JVMFlag::Error boolAt(const char* name, bool* value, bool allow_locked = false, bool return_flag = false)      { return boolAt(name, strlen(name), value, allow_locked, return_flag); }
+  static JVMFlag::Error boolAt(const JVMFlag* flag, bool* value);
   static JVMFlag::Error boolAtPut(JVMFlag* flag, bool* value, JVMFlag::Flags origin);
-  static JVMFlag::Error boolAtPut(const char* name, size_t len, bool* value, JVMFlag::Flags origin);
-  static JVMFlag::Error boolAtPut(const char* name, bool* value, JVMFlag::Flags origin)   { return boolAtPut(name, strlen(name), value, origin); }
 
-  static JVMFlag::Error intAt(const char* name, size_t len, int* value, bool allow_locked = false, bool return_flag = false);
-  static JVMFlag::Error intAt(const char* name, int* value, bool allow_locked = false, bool return_flag = false)      { return intAt(name, strlen(name), value, allow_locked, return_flag); }
+  static JVMFlag::Error intAt(const JVMFlag* flag, int* value);
   static JVMFlag::Error intAtPut(JVMFlag* flag, int* value, JVMFlag::Flags origin);
-  static JVMFlag::Error intAtPut(const char* name, size_t len, int* value, JVMFlag::Flags origin);
-  static JVMFlag::Error intAtPut(const char* name, int* value, JVMFlag::Flags origin)   { return intAtPut(name, strlen(name), value, origin); }
 
-  static JVMFlag::Error uintAt(const char* name, size_t len, uint* value, bool allow_locked = false, bool return_flag = false);
-  static JVMFlag::Error uintAt(const char* name, uint* value, bool allow_locked = false, bool return_flag = false)      { return uintAt(name, strlen(name), value, allow_locked, return_flag); }
+  static JVMFlag::Error uintAt(const JVMFlag* flag, uint* value);
   static JVMFlag::Error uintAtPut(JVMFlag* flag, uint* value, JVMFlag::Flags origin);
-  static JVMFlag::Error uintAtPut(const char* name, size_t len, uint* value, JVMFlag::Flags origin);
-  static JVMFlag::Error uintAtPut(const char* name, uint* value, JVMFlag::Flags origin)   { return uintAtPut(name, strlen(name), value, origin); }
 
-  static JVMFlag::Error intxAt(const char* name, size_t len, intx* value, bool allow_locked = false, bool return_flag = false);
-  static JVMFlag::Error intxAt(const char* name, intx* value, bool allow_locked = false, bool return_flag = false)      { return intxAt(name, strlen(name), value, allow_locked, return_flag); }
+  static JVMFlag::Error intxAt(const JVMFlag* flag, intx* value);
   static JVMFlag::Error intxAtPut(JVMFlag* flag, intx* value, JVMFlag::Flags origin);
-  static JVMFlag::Error intxAtPut(const char* name, size_t len, intx* value, JVMFlag::Flags origin);
-  static JVMFlag::Error intxAtPut(const char* name, intx* value, JVMFlag::Flags origin)   { return intxAtPut(name, strlen(name), value, origin); }
 
-  static JVMFlag::Error uintxAt(const char* name, size_t len, uintx* value, bool allow_locked = false, bool return_flag = false);
-  static JVMFlag::Error uintxAt(const char* name, uintx* value, bool allow_locked = false, bool return_flag = false)    { return uintxAt(name, strlen(name), value, allow_locked, return_flag); }
+  static JVMFlag::Error uintxAt(const JVMFlag* flag, uintx* value);
   static JVMFlag::Error uintxAtPut(JVMFlag* flag, uintx* value, JVMFlag::Flags origin);
-  static JVMFlag::Error uintxAtPut(const char* name, size_t len, uintx* value, JVMFlag::Flags origin);
-  static JVMFlag::Error uintxAtPut(const char* name, uintx* value, JVMFlag::Flags origin) { return uintxAtPut(name, strlen(name), value, origin); }
 
-  static JVMFlag::Error size_tAt(const char* name, size_t len, size_t* value, bool allow_locked = false, bool return_flag = false);
-  static JVMFlag::Error size_tAt(const char* name, size_t* value, bool allow_locked = false, bool return_flag = false)    { return size_tAt(name, strlen(name), value, allow_locked, return_flag); }
+  static JVMFlag::Error size_tAt(const JVMFlag* flag, size_t* value);
   static JVMFlag::Error size_tAtPut(JVMFlag* flag, size_t* value, JVMFlag::Flags origin);
-  static JVMFlag::Error size_tAtPut(const char* name, size_t len, size_t* value, JVMFlag::Flags origin);
-  static JVMFlag::Error size_tAtPut(const char* name, size_t* value, JVMFlag::Flags origin) { return size_tAtPut(name, strlen(name), value, origin); }
 
-  static JVMFlag::Error uint64_tAt(const char* name, size_t len, uint64_t* value, bool allow_locked = false, bool return_flag = false);
-  static JVMFlag::Error uint64_tAt(const char* name, uint64_t* value, bool allow_locked = false, bool return_flag = false) { return uint64_tAt(name, strlen(name), value, allow_locked, return_flag); }
+  static JVMFlag::Error uint64_tAt(const JVMFlag* flag, uint64_t* value);
   static JVMFlag::Error uint64_tAtPut(JVMFlag* flag, uint64_t* value, JVMFlag::Flags origin);
-  static JVMFlag::Error uint64_tAtPut(const char* name, size_t len, uint64_t* value, JVMFlag::Flags origin);
-  static JVMFlag::Error uint64_tAtPut(const char* name, uint64_t* value, JVMFlag::Flags origin) { return uint64_tAtPut(name, strlen(name), value, origin); }
 
-  static JVMFlag::Error doubleAt(const char* name, size_t len, double* value, bool allow_locked = false, bool return_flag = false);
-  static JVMFlag::Error doubleAt(const char* name, double* value, bool allow_locked = false, bool return_flag = false)    { return doubleAt(name, strlen(name), value, allow_locked, return_flag); }
+  static JVMFlag::Error doubleAt(const JVMFlag* flag, double* value);
   static JVMFlag::Error doubleAtPut(JVMFlag* flag, double* value, JVMFlag::Flags origin);
-  static JVMFlag::Error doubleAtPut(const char* name, size_t len, double* value, JVMFlag::Flags origin);
-  static JVMFlag::Error doubleAtPut(const char* name, double* value, JVMFlag::Flags origin) { return doubleAtPut(name, strlen(name), value, origin); }
 
-  static JVMFlag::Error ccstrAt(const char* name, size_t len, ccstr* value, bool allow_locked = false, bool return_flag = false);
-  static JVMFlag::Error ccstrAt(const char* name, ccstr* value, bool allow_locked = false, bool return_flag = false)    { return ccstrAt(name, strlen(name), value, allow_locked, return_flag); }
+  static JVMFlag::Error ccstrAt(const JVMFlag* flag, ccstr* value);
   // Contract:  JVMFlag will make private copy of the incoming value.
   // Outgoing value is always malloc-ed, and caller MUST call free.
-  static JVMFlag::Error ccstrAtPut(const char* name, size_t len, ccstr* value, JVMFlag::Flags origin);
-  static JVMFlag::Error ccstrAtPut(const char* name, ccstr* value, JVMFlag::Flags origin) { return ccstrAtPut(name, strlen(name), value, origin); }
+  static JVMFlag::Error ccstrAtPut(JVMFlag* flag, ccstr* value, JVMFlag::Flags origin);
 
-  // Returns false if name is not a command line flag.
-  static bool wasSetOnCmdline(const char* name, bool* value);
   static void printSetFlags(outputStream* out);
 
   // printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -32,22 +32,20 @@
 #include "runtime/flags/jvmFlagConstraintsCompiler.hpp"
 #include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
 #include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/os.hpp"
 #include "utilities/macros.hpp"
 
 class JVMFlagConstraint_bool : public JVMFlagConstraint {
   JVMFlagConstraintFunc_bool _constraint;
-  const bool* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagConstraint_bool(const char* name, const bool* ptr,
-                                 JVMFlagConstraintFunc_bool func,
-                                 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {}
+  JVMFlagConstraint_bool(const JVMFlag* flag,
+                         JVMFlagConstraintFunc_bool func,
+                         ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
 
   JVMFlag::Error apply(bool verbose) {
-    bool value = *_ptr;
-    return _constraint(value, verbose);
+    return _constraint(_flag->get_bool(), verbose);
   }
 
   JVMFlag::Error apply_bool(bool value, bool verbose) {
@@ -57,17 +55,14 @@
 
 class JVMFlagConstraint_int : public JVMFlagConstraint {
   JVMFlagConstraintFunc_int _constraint;
-  const int* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagConstraint_int(const char* name, const int* ptr,
-                                JVMFlagConstraintFunc_int func,
-                                ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {}
+  JVMFlagConstraint_int(const JVMFlag* flag,
+                        JVMFlagConstraintFunc_int func,
+                        ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
 
   JVMFlag::Error apply(bool verbose) {
-    int value = *_ptr;
-    return _constraint(value, verbose);
+    return _constraint(_flag->get_int(), verbose);
   }
 
   JVMFlag::Error apply_int(int value, bool verbose) {
@@ -77,17 +72,14 @@
 
 class JVMFlagConstraint_intx : public JVMFlagConstraint {
   JVMFlagConstraintFunc_intx _constraint;
-  const intx* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagConstraint_intx(const char* name, const intx* ptr,
-                                 JVMFlagConstraintFunc_intx func,
-                                 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {}
+  JVMFlagConstraint_intx(const JVMFlag* flag,
+                         JVMFlagConstraintFunc_intx func,
+                         ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
 
   JVMFlag::Error apply(bool verbose) {
-    intx value = *_ptr;
-    return _constraint(value, verbose);
+    return _constraint(_flag->get_intx(), verbose);
   }
 
   JVMFlag::Error apply_intx(intx value, bool verbose) {
@@ -97,17 +89,14 @@
 
 class JVMFlagConstraint_uint : public JVMFlagConstraint {
   JVMFlagConstraintFunc_uint _constraint;
-  const uint* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagConstraint_uint(const char* name, const uint* ptr,
-                                 JVMFlagConstraintFunc_uint func,
-                                 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {}
+  JVMFlagConstraint_uint(const JVMFlag* flag,
+                         JVMFlagConstraintFunc_uint func,
+                         ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
 
   JVMFlag::Error apply(bool verbose) {
-    uint value = *_ptr;
-    return _constraint(value, verbose);
+    return _constraint(_flag->get_uint(), verbose);
   }
 
   JVMFlag::Error apply_uint(uint value, bool verbose) {
@@ -117,17 +106,14 @@
 
 class JVMFlagConstraint_uintx : public JVMFlagConstraint {
   JVMFlagConstraintFunc_uintx _constraint;
-  const uintx* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagConstraint_uintx(const char* name, const uintx* ptr,
-                                  JVMFlagConstraintFunc_uintx func,
-                                 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {}
+  JVMFlagConstraint_uintx(const JVMFlag* flag,
+                          JVMFlagConstraintFunc_uintx func,
+                          ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
 
   JVMFlag::Error apply(bool verbose) {
-    uintx value = *_ptr;
-    return _constraint(value, verbose);
+    return _constraint(_flag->get_uintx(), verbose);
   }
 
   JVMFlag::Error apply_uintx(uintx value, bool verbose) {
@@ -137,17 +123,14 @@
 
 class JVMFlagConstraint_uint64_t : public JVMFlagConstraint {
   JVMFlagConstraintFunc_uint64_t _constraint;
-  const uint64_t* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagConstraint_uint64_t(const char* name, const uint64_t* ptr,
-                                     JVMFlagConstraintFunc_uint64_t func,
-                                 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {}
+  JVMFlagConstraint_uint64_t(const JVMFlag* flag,
+                             JVMFlagConstraintFunc_uint64_t func,
+                             ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
 
   JVMFlag::Error apply(bool verbose) {
-    uint64_t value = *_ptr;
-    return _constraint(value, verbose);
+    return _constraint(_flag->get_uint64_t(), verbose);
   }
 
   JVMFlag::Error apply_uint64_t(uint64_t value, bool verbose) {
@@ -157,16 +140,14 @@
 
 class JVMFlagConstraint_size_t : public JVMFlagConstraint {
   JVMFlagConstraintFunc_size_t _constraint;
-  const size_t* _ptr;
+
 public:
-  // the "name" argument must be a string literal
-  JVMFlagConstraint_size_t(const char* name, const size_t* ptr,
-                                   JVMFlagConstraintFunc_size_t func,
-                                 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {}
+  JVMFlagConstraint_size_t(const JVMFlag* flag,
+                           JVMFlagConstraintFunc_size_t func,
+                           ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
 
   JVMFlag::Error apply(bool verbose) {
-    size_t value = *_ptr;
-    return _constraint(value, verbose);
+    return _constraint(_flag->get_size_t(), verbose);
   }
 
   JVMFlag::Error apply_size_t(size_t value, bool verbose) {
@@ -176,17 +157,14 @@
 
 class JVMFlagConstraint_double : public JVMFlagConstraint {
   JVMFlagConstraintFunc_double _constraint;
-  const double* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagConstraint_double(const char* name, const double* ptr,
-                                   JVMFlagConstraintFunc_double func,
-                                 ConstraintType type) : JVMFlagConstraint(name, type), _constraint(func), _ptr(ptr) {}
+  JVMFlagConstraint_double(const JVMFlag* flag,
+                           JVMFlagConstraintFunc_double func,
+                           ConstraintType type) : JVMFlagConstraint(flag, type), _constraint(func) {}
 
   JVMFlag::Error apply(bool verbose) {
-    double value = *_ptr;
-    return _constraint(value, verbose);
+    return _constraint(_flag->get_double(), verbose);
   }
 
   JVMFlag::Error apply_double(double value, bool verbose) {
@@ -195,49 +173,49 @@
 };
 
 // No constraint emitting
-void emit_constraint_no(...)                                                      { /* NOP */ }
+void emit_constraint_no(...)                            { /* NOP */ }
 
 // No constraint emitting if function argument is NOT provided
-void emit_constraint_bool(const char* /*name*/, const bool* /*value*/)            { /* NOP */ }
-void emit_constraint_ccstr(const char* /*name*/, const ccstr* /*value*/)          { /* NOP */ }
-void emit_constraint_ccstrlist(const char* /*name*/, const ccstrlist* /*value*/)  { /* NOP */ }
-void emit_constraint_int(const char* /*name*/, const int* /*value*/)              { /* NOP */ }
-void emit_constraint_intx(const char* /*name*/, const intx* /*value*/)            { /* NOP */ }
-void emit_constraint_uint(const char* /*name*/, const uint* /*value*/)            { /* NOP */ }
-void emit_constraint_uintx(const char* /*name*/, const uintx* /*value*/)          { /* NOP */ }
-void emit_constraint_uint64_t(const char* /*name*/, const uint64_t* /*value*/)    { /* NOP */ }
-void emit_constraint_size_t(const char* /*name*/, const size_t* /*value*/)        { /* NOP */ }
-void emit_constraint_double(const char* /*name*/, const double* /*value*/)        { /* NOP */ }
+void emit_constraint_bool(const JVMFlag* /*flag*/)      { /* NOP */ }
+void emit_constraint_ccstr(const JVMFlag* /*flag*/)     { /* NOP */ }
+void emit_constraint_ccstrlist(const JVMFlag* /*flag*/) { /* NOP */ }
+void emit_constraint_int(const JVMFlag* /*flag*/)       { /* NOP */ }
+void emit_constraint_intx(const JVMFlag* /*flag*/)      { /* NOP */ }
+void emit_constraint_uint(const JVMFlag* /*flag*/)      { /* NOP */ }
+void emit_constraint_uintx(const JVMFlag* /*flag*/)     { /* NOP */ }
+void emit_constraint_uint64_t(const JVMFlag* /*flag*/)  { /* NOP */ }
+void emit_constraint_size_t(const JVMFlag* /*flag*/)    { /* NOP */ }
+void emit_constraint_double(const JVMFlag* /*flag*/)    { /* NOP */ }
 
 // JVMFlagConstraint emitting code functions if function argument is provided
-void emit_constraint_bool(const char* name, const bool* ptr, JVMFlagConstraintFunc_bool func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_bool(name, ptr, func, type));
+void emit_constraint_bool(const JVMFlag* flag, JVMFlagConstraintFunc_bool func, JVMFlagConstraint::ConstraintType type) {
+  JVMFlagConstraintList::add(new JVMFlagConstraint_bool(flag, func, type));
 }
-void emit_constraint_int(const char* name, const int* ptr, JVMFlagConstraintFunc_int func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_int(name, ptr, func, type));
+void emit_constraint_int(const JVMFlag* flag, JVMFlagConstraintFunc_int func, JVMFlagConstraint::ConstraintType type) {
+  JVMFlagConstraintList::add(new JVMFlagConstraint_int(flag, func, type));
 }
-void emit_constraint_intx(const char* name, const intx* ptr, JVMFlagConstraintFunc_intx func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_intx(name, ptr, func, type));
+void emit_constraint_intx(const JVMFlag* flag, JVMFlagConstraintFunc_intx func, JVMFlagConstraint::ConstraintType type) {
+  JVMFlagConstraintList::add(new JVMFlagConstraint_intx(flag, func, type));
 }
-void emit_constraint_uint(const char* name, const uint* ptr, JVMFlagConstraintFunc_uint func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_uint(name, ptr, func, type));
+void emit_constraint_uint(const JVMFlag* flag, JVMFlagConstraintFunc_uint func, JVMFlagConstraint::ConstraintType type) {
+  JVMFlagConstraintList::add(new JVMFlagConstraint_uint(flag, func, type));
 }
-void emit_constraint_uintx(const char* name, const uintx* ptr, JVMFlagConstraintFunc_uintx func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_uintx(name, ptr, func, type));
+void emit_constraint_uintx(const JVMFlag* flag, JVMFlagConstraintFunc_uintx func, JVMFlagConstraint::ConstraintType type) {
+  JVMFlagConstraintList::add(new JVMFlagConstraint_uintx(flag, func, type));
 }
-void emit_constraint_uint64_t(const char* name, const uint64_t* ptr, JVMFlagConstraintFunc_uint64_t func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_uint64_t(name, ptr, func, type));
+void emit_constraint_uint64_t(const JVMFlag* flag, JVMFlagConstraintFunc_uint64_t func, JVMFlagConstraint::ConstraintType type) {
+  JVMFlagConstraintList::add(new JVMFlagConstraint_uint64_t(flag, func, type));
 }
-void emit_constraint_size_t(const char* name, const size_t* ptr, JVMFlagConstraintFunc_size_t func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_size_t(name, ptr, func, type));
+void emit_constraint_size_t(const JVMFlag* flag, JVMFlagConstraintFunc_size_t func, JVMFlagConstraint::ConstraintType type) {
+  JVMFlagConstraintList::add(new JVMFlagConstraint_size_t(flag, func, type));
 }
-void emit_constraint_double(const char* name, const double* ptr, JVMFlagConstraintFunc_double func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_double(name, ptr, func, type));
+void emit_constraint_double(const JVMFlag* flag, JVMFlagConstraintFunc_double func, JVMFlagConstraint::ConstraintType type) {
+  JVMFlagConstraintList::add(new JVMFlagConstraint_double(flag, func, type));
 }
 
 // Generate code to call emit_constraint_xxx function
 #define EMIT_CONSTRAINT_START       (void)(0
-#define EMIT_CONSTRAINT(type, name) ); emit_constraint_##type(#name, &name
+#define EMIT_CONSTRAINT(type, name) ); emit_constraint_##type(JVMFlagEx::flag_from_enum(FLAG_MEMBER_ENUM(name))
 #define EMIT_CONSTRAINT_NO          ); emit_constraint_no(0
 #define EMIT_CONSTRAINT_PRODUCT_FLAG(type, name, value, doc)      EMIT_CONSTRAINT(type, name)
 #define EMIT_CONSTRAINT_DIAGNOSTIC_FLAG(type, name, value, doc)   EMIT_CONSTRAINT(type, name)
@@ -296,11 +274,11 @@
   EMIT_CONSTRAINT_END
 }
 
-JVMFlagConstraint* JVMFlagConstraintList::find(const char* name) {
+JVMFlagConstraint* JVMFlagConstraintList::find(const JVMFlag* flag) {
   JVMFlagConstraint* found = NULL;
   for (int i=0; i<length(); i++) {
     JVMFlagConstraint* constraint = at(i);
-    if (strcmp(constraint->name(), name) == 0) {
+    if (constraint->flag() == flag) {
       found = constraint;
       break;
     }
@@ -308,11 +286,11 @@
   return found;
 }
 
-// Find constraints by name and return only if found constraint's type is equal or lower than current validating type.
-JVMFlagConstraint* JVMFlagConstraintList::find_if_needs_check(const char* name) {
+// Find constraints and return only if found constraint's type is equal or lower than current validating type.
+JVMFlagConstraint* JVMFlagConstraintList::find_if_needs_check(const JVMFlag* flag) {
   JVMFlagConstraint* found = NULL;
-  JVMFlagConstraint* constraint = find(name);
-  if (constraint && (constraint->type() <= _validating_type)) {
+  JVMFlagConstraint* constraint = find(flag);
+  if (constraint != NULL && (constraint->type() <= _validating_type)) {
     found = constraint;
   }
   return found;
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -60,15 +60,17 @@
     AfterMemoryInit = 2
   };
 
+protected:
+  const JVMFlag* const _flag;
+
 private:
-  const char* _name;
   ConstraintType _validate_type;
 
 public:
   // the "name" argument must be a string literal
-  JVMFlagConstraint(const char* name, ConstraintType type) { _name=name; _validate_type=type; };
-  ~JVMFlagConstraint() {};
-  const char* name() const { return _name; }
+  JVMFlagConstraint(const JVMFlag* flag, ConstraintType type) : _flag(flag), _validate_type(type) {}
+  ~JVMFlagConstraint() {}
+  const JVMFlag* flag() const { return _flag; }
   ConstraintType type() const { return _validate_type; }
   virtual JVMFlag::Error apply(bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
   virtual JVMFlag::Error apply_bool(bool value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
@@ -90,8 +92,8 @@
   static void init();
   static int length() { return (_constraints != NULL) ? _constraints->length() : 0; }
   static JVMFlagConstraint* at(int i) { return (_constraints != NULL) ? _constraints->at(i) : NULL; }
-  static JVMFlagConstraint* find(const char* name);
-  static JVMFlagConstraint* find_if_needs_check(const char* name);
+  static JVMFlagConstraint* find(const JVMFlag* flag);
+  static JVMFlagConstraint* find_if_needs_check(const JVMFlag* flag);
   static void add(JVMFlagConstraint* constraint) { _constraints->append(constraint); }
   // True if 'AfterErgo' or later constraint functions are validated.
   static bool validated_after_ergo() { return _validating_type >= JVMFlagConstraint::AfterErgo; };
--- a/src/hotspot/share/runtime/flags/jvmFlagRangeList.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/flags/jvmFlagRangeList.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,12 +27,13 @@
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
 #include "gc/shared/referenceProcessor.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/flags/jvmFlag.hpp"
 #include "runtime/flags/jvmFlagConstraintList.hpp"
 #include "runtime/flags/jvmFlagRangeList.hpp"
 #include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/os.hpp"
 #include "runtime/task.hpp"
 #include "utilities/macros.hpp"
@@ -40,15 +41,13 @@
 class JVMFlagRange_int : public JVMFlagRange {
   int _min;
   int _max;
-  const int* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagRange_int(const char* name, const int* ptr, int min, int max)
-    : JVMFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
+  JVMFlagRange_int(const JVMFlag* flag, int min, int max)
+    : JVMFlagRange(flag), _min(min), _max(max) {}
 
   JVMFlag::Error check(bool verbose = true) {
-    return check_int(*_ptr, verbose);
+    return check_int(_flag->get_int(), verbose);
   }
 
   JVMFlag::Error check_int(int value, bool verbose = true) {
@@ -71,14 +70,13 @@
 class JVMFlagRange_intx : public JVMFlagRange {
   intx _min;
   intx _max;
-  const intx* _ptr;
+
 public:
-  // the "name" argument must be a string literal
-  JVMFlagRange_intx(const char* name, const intx* ptr, intx min, intx max)
-    : JVMFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
+  JVMFlagRange_intx(const JVMFlag* flag, intx min, intx max)
+    : JVMFlagRange(flag), _min(min), _max(max) {}
 
   JVMFlag::Error check(bool verbose = true) {
-    return check_intx(*_ptr, verbose);
+    return check_intx(_flag->get_intx(), verbose);
   }
 
   JVMFlag::Error check_intx(intx value, bool verbose = true) {
@@ -101,15 +99,13 @@
 class JVMFlagRange_uint : public JVMFlagRange {
   uint _min;
   uint _max;
-  const uint* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagRange_uint(const char* name, const uint* ptr, uint min, uint max)
-    : JVMFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
+  JVMFlagRange_uint(const JVMFlag* flag, uint min, uint max)
+    : JVMFlagRange(flag), _min(min), _max(max) {}
 
   JVMFlag::Error check(bool verbose = true) {
-    return check_uint(*_ptr, verbose);
+    return check_uint(_flag->get_uint(), verbose);
   }
 
   JVMFlag::Error check_uint(uint value, bool verbose = true) {
@@ -132,15 +128,13 @@
 class JVMFlagRange_uintx : public JVMFlagRange {
   uintx _min;
   uintx _max;
-  const uintx* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagRange_uintx(const char* name, const uintx* ptr, uintx min, uintx max)
-    : JVMFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
+  JVMFlagRange_uintx(const JVMFlag* flag, uintx min, uintx max)
+    : JVMFlagRange(flag), _min(min), _max(max) {}
 
   JVMFlag::Error check(bool verbose = true) {
-    return check_uintx(*_ptr, verbose);
+    return check_uintx(_flag->get_uintx(), verbose);
   }
 
   JVMFlag::Error check_uintx(uintx value, bool verbose = true) {
@@ -163,15 +157,13 @@
 class JVMFlagRange_uint64_t : public JVMFlagRange {
   uint64_t _min;
   uint64_t _max;
-  const uint64_t* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagRange_uint64_t(const char* name, const uint64_t* ptr, uint64_t min, uint64_t max)
-    : JVMFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
+  JVMFlagRange_uint64_t(const JVMFlag* flag, uint64_t min, uint64_t max)
+    : JVMFlagRange(flag), _min(min), _max(max) {}
 
   JVMFlag::Error check(bool verbose = true) {
-    return check_uint64_t(*_ptr, verbose);
+    return check_uint64_t(_flag->get_uintx(), verbose);
   }
 
   JVMFlag::Error check_uint64_t(uint64_t value, bool verbose = true) {
@@ -194,15 +186,13 @@
 class JVMFlagRange_size_t : public JVMFlagRange {
   size_t _min;
   size_t _max;
-  const size_t* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagRange_size_t(const char* name, const size_t* ptr, size_t min, size_t max)
-    : JVMFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
+  JVMFlagRange_size_t(const JVMFlag* flag, size_t min, size_t max)
+    : JVMFlagRange(flag), _min(min), _max(max) {}
 
   JVMFlag::Error check(bool verbose = true) {
-    return check_size_t(*_ptr, verbose);
+    return check_size_t(_flag->get_size_t(), verbose);
   }
 
   JVMFlag::Error check_size_t(size_t value, bool verbose = true) {
@@ -225,15 +215,13 @@
 class JVMFlagRange_double : public JVMFlagRange {
   double _min;
   double _max;
-  const double* _ptr;
 
 public:
-  // the "name" argument must be a string literal
-  JVMFlagRange_double(const char* name, const double* ptr, double min, double max)
-    : JVMFlagRange(name), _min(min), _max(max), _ptr(ptr) {}
+  JVMFlagRange_double(const JVMFlag* flag, double min, double max)
+    : JVMFlagRange(flag), _min(min), _max(max) {}
 
   JVMFlag::Error check(bool verbose = true) {
-    return check_double(*_ptr, verbose);
+    return check_double(_flag->get_double(), verbose);
   }
 
   JVMFlag::Error check_double(double value, bool verbose = true) {
@@ -257,43 +245,43 @@
 void emit_range_no(...)                         { /* NOP */ }
 
 // No constraint emitting if function argument is NOT provided
-void emit_range_bool(const char* /*name*/, const bool* /*value*/)            { /* NOP */ }
-void emit_range_ccstr(const char* /*name*/, const ccstr* /*value*/)          { /* NOP */ }
-void emit_range_ccstrlist(const char* /*name*/, const ccstrlist* /*value*/)  { /* NOP */ }
-void emit_range_int(const char* /*name*/, const int* /*value*/)              { /* NOP */ }
-void emit_range_intx(const char* /*name*/, const intx* /*value*/)            { /* NOP */ }
-void emit_range_uint(const char* /*name*/, const uint* /*value*/)            { /* NOP */ }
-void emit_range_uintx(const char* /*name*/, const uintx* /*value*/)          { /* NOP */ }
-void emit_range_uint64_t(const char* /*name*/, const uint64_t* /*value*/)    { /* NOP */ }
-void emit_range_size_t(const char* /*name*/, const size_t* /*value*/)        { /* NOP */ }
-void emit_range_double(const char* /*name*/, const double* /*value*/)        { /* NOP */ }
+void emit_range_bool(const JVMFlag* /*flag*/)      { /* NOP */ }
+void emit_range_ccstr(const JVMFlag* /*flag*/)     { /* NOP */ }
+void emit_range_ccstrlist(const JVMFlag* /*flag*/) { /* NOP */ }
+void emit_range_int(const JVMFlag* /*flag*/)       { /* NOP */ }
+void emit_range_intx(const JVMFlag* /*flag*/)      { /* NOP */ }
+void emit_range_uint(const JVMFlag* /*flag*/)      { /* NOP */ }
+void emit_range_uintx(const JVMFlag* /*flag*/)     { /* NOP */ }
+void emit_range_uint64_t(const JVMFlag* /*flag*/)  { /* NOP */ }
+void emit_range_size_t(const JVMFlag* /*flag*/)    { /* NOP */ }
+void emit_range_double(const JVMFlag* /*flag*/)    { /* NOP */ }
 
 // JVMFlagRange emitting code functions if range arguments are provided
-void emit_range_int(const char* name, const int* ptr, int min, int max)       {
-  JVMFlagRangeList::add(new JVMFlagRange_int(name, ptr, min, max));
+void emit_range_int(const JVMFlag* flag, int min, int max)       {
+  JVMFlagRangeList::add(new JVMFlagRange_int(flag, min, max));
 }
-void emit_range_intx(const char* name, const intx* ptr, intx min, intx max) {
-  JVMFlagRangeList::add(new JVMFlagRange_intx(name, ptr, min, max));
+void emit_range_intx(const JVMFlag* flag, intx min, intx max) {
+  JVMFlagRangeList::add(new JVMFlagRange_intx(flag, min, max));
 }
-void emit_range_uint(const char* name, const uint* ptr, uint min, uint max) {
-  JVMFlagRangeList::add(new JVMFlagRange_uint(name, ptr, min, max));
+void emit_range_uint(const JVMFlag* flag, uint min, uint max) {
+  JVMFlagRangeList::add(new JVMFlagRange_uint(flag, min, max));
 }
-void emit_range_uintx(const char* name, const uintx* ptr, uintx min, uintx max) {
-  JVMFlagRangeList::add(new JVMFlagRange_uintx(name, ptr, min, max));
+void emit_range_uintx(const JVMFlag* flag, uintx min, uintx max) {
+  JVMFlagRangeList::add(new JVMFlagRange_uintx(flag, min, max));
 }
-void emit_range_uint64_t(const char* name, const uint64_t* ptr, uint64_t min, uint64_t max) {
-  JVMFlagRangeList::add(new JVMFlagRange_uint64_t(name, ptr, min, max));
+void emit_range_uint64_t(const JVMFlag* flag, uint64_t min, uint64_t max) {
+  JVMFlagRangeList::add(new JVMFlagRange_uint64_t(flag, min, max));
 }
-void emit_range_size_t(const char* name, const size_t* ptr, size_t min, size_t max) {
-  JVMFlagRangeList::add(new JVMFlagRange_size_t(name, ptr, min, max));
+void emit_range_size_t(const JVMFlag* flag, size_t min, size_t max) {
+  JVMFlagRangeList::add(new JVMFlagRange_size_t(flag, min, max));
 }
-void emit_range_double(const char* name, const double* ptr, double min, double max) {
-  JVMFlagRangeList::add(new JVMFlagRange_double(name, ptr, min, max));
+void emit_range_double(const JVMFlag* flag, double min, double max) {
+  JVMFlagRangeList::add(new JVMFlagRange_double(flag, min, max));
 }
 
 // Generate code to call emit_range_xxx function
 #define EMIT_RANGE_START       (void)(0
-#define EMIT_RANGE(type, name) ); emit_range_##type(#name, &name
+#define EMIT_RANGE(type, name) ); emit_range_##type(JVMFlagEx::flag_from_enum(FLAG_MEMBER_ENUM(name))
 #define EMIT_RANGE_NO          ); emit_range_no(0
 #define EMIT_RANGE_PRODUCT_FLAG(type, name, value, doc)      EMIT_RANGE(type, name)
 #define EMIT_RANGE_DIAGNOSTIC_FLAG(type, name, value, doc)   EMIT_RANGE(type, name)
@@ -351,11 +339,11 @@
   EMIT_RANGE_END
 }
 
-JVMFlagRange* JVMFlagRangeList::find(const char* name) {
+JVMFlagRange* JVMFlagRangeList::find(const JVMFlag* flag) {
   JVMFlagRange* found = NULL;
   for (int i=0; i<length(); i++) {
     JVMFlagRange* range = at(i);
-    if (strcmp(range->name(), name) == 0) {
+    if (range->flag() == flag) {
       found = range;
       break;
     }
@@ -363,12 +351,12 @@
   return found;
 }
 
-void JVMFlagRangeList::print(outputStream* st, const char* name, RangeStrFunc default_range_str_func) {
-  JVMFlagRange* range = JVMFlagRangeList::find(name);
+void JVMFlagRangeList::print(outputStream* st, const JVMFlag* flag, RangeStrFunc default_range_str_func) {
+  JVMFlagRange* range = JVMFlagRangeList::find(flag);
   if (range != NULL) {
     range->print(st);
   } else {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find(name);
+    JVMFlagConstraint* constraint = JVMFlagConstraintList::find(flag);
     if (constraint != NULL) {
       assert(default_range_str_func!=NULL, "default_range_str_func must be provided");
       st->print("%s", default_range_str_func());
--- a/src/hotspot/share/runtime/flags/jvmFlagRangeList.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/flags/jvmFlagRangeList.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -39,13 +39,14 @@
  */
 
 class JVMFlagRange : public CHeapObj<mtArguments> {
-private:
-  const char* _name;
+protected:
+  const JVMFlag* const _flag;
 public:
   // the "name" argument must be a string literal
-  JVMFlagRange(const char* name) { _name=name; }
+  JVMFlagRange(const JVMFlag* flag) : _flag(flag) {}
   ~JVMFlagRange() {}
-  const char* name() { return _name; }
+  const JVMFlag* flag() const { return _flag; }
+  const char* name() const { return _flag->_name; }
   virtual JVMFlag::Error check(bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
   virtual JVMFlag::Error check_int(int value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
   virtual JVMFlag::Error check_intx(intx value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; }
@@ -63,9 +64,9 @@
   static void init();
   static int length() { return (_ranges != NULL) ? _ranges->length() : 0; }
   static JVMFlagRange* at(int i) { return (_ranges != NULL) ? _ranges->at(i) : NULL; }
-  static JVMFlagRange* find(const char* name);
+  static JVMFlagRange* find(const JVMFlag* flag);
   static void add(JVMFlagRange* range) { _ranges->append(range); }
-  static void print(outputStream* st, const char* name, RangeStrFunc default_range_str_func);
+  static void print(outputStream* st, const JVMFlag* flag, RangeStrFunc default_range_str_func);
   // Check the final values of all flags for ranges.
   static bool check_ranges();
 };
--- a/src/hotspot/share/runtime/frame.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/frame.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -33,7 +33,7 @@
 #include "interpreter/oopMapCache.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/methodData.hpp"
 #include "oops/oop.inline.hpp"
--- a/src/hotspot/share/runtime/globals.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/globals.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -2437,11 +2437,14 @@
   diagnostic(bool, ShowRegistersOnAssert, true,                             \
           "On internal errors, include registers in error report.")         \
                                                                             \
-  experimental(bool, UseSwitchProfiling, true,                              \
+  diagnostic(bool, UseSwitchProfiling, true,                                \
           "leverage profiling for table/lookup switch")                     \
                                                                             \
+  develop(bool, TraceMemoryWriteback, false,                                \
+          "Trace memory writeback operations")                              \
+                                                                            \
   JFR_ONLY(product(bool, FlightRecorder, false,                             \
-          "(Deprecated) Enable Flight Recorder"))                                        \
+          "(Deprecated) Enable Flight Recorder"))                           \
                                                                             \
   JFR_ONLY(product(ccstr, FlightRecorderOptions, NULL,                      \
           "Flight Recorder options"))                                       \
--- a/src/hotspot/share/runtime/globals_extension.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/globals_extension.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -91,6 +91,8 @@
   static bool is_cmdline(JVMFlagsEnum flag);
 
   static void setOnCmdLine(JVMFlagsEnum flag);
+
+  static JVMFlag* flag_from_enum(JVMFlagsEnum flag);
 };
 
 // Construct set functions for all flags
--- a/src/hotspot/share/runtime/init.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/init.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -50,6 +50,7 @@
 void check_ThreadShadow();
 void eventlog_init();
 void mutex_init();
+void oopstorage_init();
 void chunkpool_init();
 void perfMemory_init();
 void SuspendibleThreadSet_init();
@@ -98,6 +99,7 @@
   basic_types_init();
   eventlog_init();
   mutex_init();
+  oopstorage_init();
   chunkpool_init();
   perfMemory_init();
   SuspendibleThreadSet_init();
--- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -254,30 +254,30 @@
 };
 
 // Unlike ThreadBlockInVM, this class is designed to avoid certain deadlock scenarios while making
-// transitions inside class Monitor in cases where we need to block for a safepoint or handshake. It
-// receives an extra argument compared to ThreadBlockInVM, the address of a pointer to the monitor we
-// are trying to acquire. This will be used to access and release the monitor if needed to avoid
+// transitions inside class Mutex in cases where we need to block for a safepoint or handshake. It
+// receives an extra argument compared to ThreadBlockInVM, the address of a pointer to the mutex we
+// are trying to acquire. This will be used to access and release the mutex if needed to avoid
 // said deadlocks.
 // It works like ThreadBlockInVM but differs from it in two ways:
 // - When transitioning in (constructor), it checks for safepoints without blocking, i.e., calls
 //   back if needed to allow a pending safepoint to continue but does not block in it.
 // - When transitioning back (destructor), if there is a pending safepoint or handshake it releases
-//   the monitor that is only partially acquired.
+//   the mutex that is only partially acquired.
 class ThreadBlockInVMWithDeadlockCheck : public ThreadStateTransition {
  private:
-  Monitor** _in_flight_monitor_adr;
+  Mutex** _in_flight_mutex_addr;
 
-  void release_monitor() {
-    assert(_in_flight_monitor_adr != NULL, "_in_flight_monitor_adr should have been set on constructor");
-    Monitor* in_flight_monitor = *_in_flight_monitor_adr;
-    if (in_flight_monitor != NULL) {
-      in_flight_monitor->release_for_safepoint();
-      *_in_flight_monitor_adr = NULL;
+  void release_mutex() {
+    assert(_in_flight_mutex_addr != NULL, "_in_flight_mutex_addr should have been set on constructor");
+    Mutex* in_flight_mutex = *_in_flight_mutex_addr;
+    if (in_flight_mutex != NULL) {
+      in_flight_mutex->release_for_safepoint();
+      *_in_flight_mutex_addr = NULL;
     }
   }
  public:
-  ThreadBlockInVMWithDeadlockCheck(JavaThread* thread, Monitor** in_flight_monitor_adr)
-  : ThreadStateTransition(thread), _in_flight_monitor_adr(in_flight_monitor_adr) {
+  ThreadBlockInVMWithDeadlockCheck(JavaThread* thread, Mutex** in_flight_mutex_addr)
+  : ThreadStateTransition(thread), _in_flight_mutex_addr(in_flight_mutex_addr) {
     // Once we are blocked vm expects stack to be walkable
     thread->frame_anchor()->make_walkable(thread);
 
@@ -293,7 +293,7 @@
     _thread->set_thread_state_fence((JavaThreadState)(_thread_blocked_trans));
 
     if (SafepointMechanism::should_block(_thread)) {
-      release_monitor();
+      release_mutex();
       SafepointMechanism::block_if_requested(_thread);
     }
 
--- a/src/hotspot/share/runtime/jniHandles.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/jniHandles.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "gc/shared/oopStorage.inline.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "logging/log.hpp"
 #include "memory/iterator.hpp"
 #include "memory/universe.hpp"
@@ -36,17 +37,21 @@
 #include "utilities/align.hpp"
 #include "utilities/debug.hpp"
 
+static OopStorage* global_handles() {
+  return OopStorageSet::jni_global();
+}
+
+static OopStorage* weak_global_handles() {
+  return OopStorageSet::jni_weak();
+}
+
+// Serviceability agent support.
 OopStorage* JNIHandles::_global_handles = NULL;
 OopStorage* JNIHandles::_weak_global_handles = NULL;
 
-OopStorage* JNIHandles::global_handles() {
-  assert(_global_handles != NULL, "Uninitialized JNI global handles");
-  return _global_handles;
-}
-
-OopStorage* JNIHandles::weak_global_handles() {
-  assert(_weak_global_handles != NULL, "Uninitialized JNI weak global handles");
-  return _weak_global_handles;
+void jni_handles_init() {
+  JNIHandles::_global_handles = global_handles();
+  JNIHandles::_weak_global_handles = weak_global_handles();
 }
 
 
@@ -197,16 +202,6 @@
 }
 
 
-void JNIHandles::initialize() {
-  _global_handles = new OopStorage("JNI Global",
-                                   JNIGlobalAlloc_lock,
-                                   JNIGlobalActive_lock);
-  _weak_global_handles = new OopStorage("JNI Weak",
-                                        JNIWeakAlloc_lock,
-                                        JNIWeakActive_lock);
-}
-
-
 inline bool is_storage_handle(const OopStorage* storage, const oop* ptr) {
   return storage->allocation_status(ptr) == OopStorage::ALLOCATED_ENTRY;
 }
@@ -332,11 +327,6 @@
 }
 
 
-void jni_handles_init() {
-  JNIHandles::initialize();
-}
-
-
 int             JNIHandleBlock::_blocks_allocated     = 0;
 JNIHandleBlock* JNIHandleBlock::_block_free_list      = NULL;
 #ifndef PRODUCT
--- a/src/hotspot/share/runtime/jniHandles.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/jniHandles.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -37,8 +37,10 @@
 class JNIHandles : AllStatic {
   friend class VMStructs;
  private:
+  // These are used by the serviceability agent.
   static OopStorage* _global_handles;
   static OopStorage* _weak_global_handles;
+  friend void jni_handles_init();
 
   inline static bool is_jweak(jobject handle);
   inline static oop* jobject_ptr(jobject handle); // NOT jweak!
@@ -122,9 +124,6 @@
   static void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* f);
   // Traversal of weak global handles.
   static void weak_oops_do(OopClosure* f);
-
-  static OopStorage* global_handles();
-  static OopStorage* weak_global_handles();
 };
 
 
--- a/src/hotspot/share/runtime/mutex.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/mutex.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -33,27 +33,27 @@
 #include "utilities/macros.hpp"
 
 #ifdef ASSERT
-void Monitor::check_safepoint_state(Thread* thread, bool do_safepoint_check) {
+void Mutex::check_safepoint_state(Thread* thread, bool do_safepoint_check) {
   // If the JavaThread checks for safepoint, verify that the lock wasn't created with safepoint_check_never.
-  SafepointCheckRequired not_allowed = do_safepoint_check ?  Monitor::_safepoint_check_never :
-                                                             Monitor::_safepoint_check_always;
+  SafepointCheckRequired not_allowed = do_safepoint_check ?  Mutex::_safepoint_check_never :
+                                                             Mutex::_safepoint_check_always;
   assert(!thread->is_active_Java_thread() || _safepoint_check_required != not_allowed,
          "This lock should %s have a safepoint check for Java threads: %s",
          _safepoint_check_required ? "always" : "never", name());
 
   // If defined with safepoint_check_never, a NonJavaThread should never ask to safepoint check either.
-  assert(thread->is_Java_thread() || !do_safepoint_check || _safepoint_check_required != Monitor::_safepoint_check_never,
+  assert(thread->is_Java_thread() || !do_safepoint_check || _safepoint_check_required != Mutex::_safepoint_check_never,
          "NonJavaThread should not check for safepoint");
 }
 #endif // ASSERT
 
-void Monitor::lock(Thread * self) {
+void Mutex::lock(Thread * self) {
   check_safepoint_state(self, true);
 
   DEBUG_ONLY(check_prelock_state(self, true));
   assert(_owner != self, "invariant");
 
-  Monitor* in_flight_monitor = NULL;
+  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()) {
@@ -62,18 +62,18 @@
   #ifdef ASSERT
     check_block_state(self);
     if (retry_cnt++ > 3) {
-      log_trace(vmmonitor)("JavaThread " INTPTR_FORMAT " on %d attempt trying to acquire vmmonitor %s", p2i(self), retry_cnt, _name);
+      log_trace(vmmutex)("JavaThread " INTPTR_FORMAT " on %d attempt trying to acquire vmmutex %s", p2i(self), retry_cnt, _name);
     }
   #endif // ASSERT
 
     // Is it a JavaThread participating in the safepoint protocol.
     if (is_active_Java_thread) {
       assert(rank() > Mutex::special, "Potential deadlock with special or lesser rank mutex");
-      { ThreadBlockInVMWithDeadlockCheck tbivmdc((JavaThread *) self, &in_flight_monitor);
-        in_flight_monitor = this;  // save for ~ThreadBlockInVMWithDeadlockCheck
+      { ThreadBlockInVMWithDeadlockCheck tbivmdc((JavaThread *) self, &in_flight_mutex);
+        in_flight_mutex = this;  // save for ~ThreadBlockInVMWithDeadlockCheck
         _lock.lock();
       }
-      if (in_flight_monitor != NULL) {
+      if (in_flight_mutex != NULL) {
         // Not unlocked by ~ThreadBlockInVMWithDeadlockCheck
         break;
       }
@@ -87,7 +87,7 @@
   set_owner(self);
 }
 
-void Monitor::lock() {
+void Mutex::lock() {
   this->lock(Thread::current());
 }
 
@@ -97,7 +97,7 @@
 // safepoint-safe and so will prevent a safepoint from being reached. If used
 // in the wrong way this can lead to a deadlock with the safepoint code.
 
-void Monitor::lock_without_safepoint_check(Thread * self) {
+void Mutex::lock_without_safepoint_check(Thread * self) {
   check_safepoint_state(self, false);
   assert(_owner != self, "invariant");
   _lock.lock();
@@ -105,14 +105,14 @@
   set_owner(self);
 }
 
-void Monitor::lock_without_safepoint_check() {
+void Mutex::lock_without_safepoint_check() {
   lock_without_safepoint_check(Thread::current());
 }
 
 
 // Returns true if thread succeeds in grabbing the lock, otherwise false.
 
-bool Monitor::try_lock() {
+bool Mutex::try_lock() {
   Thread * const self = Thread::current();
   DEBUG_ONLY(check_prelock_state(self, false);)
 
@@ -124,12 +124,12 @@
   return false;
 }
 
-void Monitor::release_for_safepoint() {
+void Mutex::release_for_safepoint() {
   assert_owner(NULL);
   _lock.unlock();
 }
 
-void Monitor::unlock() {
+void Mutex::unlock() {
   assert_owner(Thread::current());
   set_owner(NULL);
   _lock.unlock();
@@ -147,7 +147,7 @@
 
 #ifdef ASSERT
 void Monitor::assert_wait_lock_state(Thread* self) {
-  Monitor* least = get_least_ranked_lock_besides_this(self->owned_locks());
+  Mutex* least = get_least_ranked_lock_besides_this(self->owned_locks());
   assert(least != this, "Specification of get_least_... call above");
   if (least != NULL && least->rank() <= special) {
     ::tty->print("Attempting to wait on monitor %s/%d while holding"
@@ -194,10 +194,10 @@
   // abdicating the lock in wait
   set_owner(NULL);
   JavaThread *jt = (JavaThread *)self;
-  Monitor* in_flight_monitor = NULL;
+  Mutex* in_flight_mutex = NULL;
 
   {
-    ThreadBlockInVMWithDeadlockCheck tbivmdc(jt, &in_flight_monitor);
+    ThreadBlockInVMWithDeadlockCheck tbivmdc(jt, &in_flight_mutex);
     OSThreadWaitState osts(self->osthread(), false /* not Object.wait() */);
     if (as_suspend_equivalent) {
       jt->set_suspend_equivalent();
@@ -206,7 +206,7 @@
     }
 
     wait_status = _lock.wait(timeout);
-    in_flight_monitor = this;  // save for ~ThreadBlockInVMWithDeadlockCheck
+    in_flight_mutex = this;  // save for ~ThreadBlockInVMWithDeadlockCheck
 
     // were we externally suspended while we were waiting?
     if (as_suspend_equivalent && jt->handle_special_suspend_equivalent_condition()) {
@@ -220,7 +220,7 @@
     }
   }
 
-  if (in_flight_monitor != NULL) {
+  if (in_flight_mutex != NULL) {
     // Not unlocked by ~ThreadBlockInVMWithDeadlockCheck
     assert_owner(NULL);
     // Conceptually reestablish ownership of the lock.
@@ -232,7 +232,7 @@
   return wait_status != 0;          // return true IFF timeout
 }
 
-Monitor::~Monitor() {
+Mutex::~Mutex() {
   assert_owner(NULL);
 }
 
@@ -241,34 +241,34 @@
   return (strcmp(name, "Threads_lock") == 0 || strcmp(name, "Heap_lock") == 0 || strcmp(name, "SR_lock") == 0);
 }
 
-Monitor::Monitor(int Rank, const char * name, bool allow_vm_block,
-                 SafepointCheckRequired safepoint_check_required) : _owner(NULL) {
+Mutex::Mutex(int Rank, const char * name, bool allow_vm_block,
+             SafepointCheckRequired safepoint_check_required) : _owner(NULL) {
   assert(os::mutex_init_done(), "Too early!");
   if (name == NULL) {
     strcpy(_name, "UNKNOWN");
   } else {
-    strncpy(_name, name, MONITOR_NAME_LEN - 1);
-    _name[MONITOR_NAME_LEN - 1] = '\0';
+    strncpy(_name, name, MUTEX_NAME_LEN - 1);
+    _name[MUTEX_NAME_LEN - 1] = '\0';
   }
 #ifdef ASSERT
   _allow_vm_block  = allow_vm_block;
   _rank            = Rank;
   _safepoint_check_required = safepoint_check_required;
 
-  assert(_safepoint_check_required != Monitor::_safepoint_check_sometimes || is_sometimes_ok(name),
+  assert(_safepoint_check_required != Mutex::_safepoint_check_sometimes || is_sometimes_ok(name),
          "Lock has _safepoint_check_sometimes %s", name);
 #endif
 }
 
-Mutex::Mutex(int Rank, const char * name, bool allow_vm_block,
+Monitor::Monitor(int Rank, const char * name, bool allow_vm_block,
              SafepointCheckRequired safepoint_check_required) :
-  Monitor(Rank, name, allow_vm_block, safepoint_check_required) {}
+  Mutex(Rank, name, allow_vm_block, safepoint_check_required) {}
 
-bool Monitor::owned_by_self() const {
+bool Mutex::owned_by_self() const {
   return _owner == Thread::current();
 }
 
-void Monitor::print_on_error(outputStream* st) const {
+void Mutex::print_on_error(outputStream* st) const {
   st->print("[" PTR_FORMAT, p2i(this));
   st->print("] %s", _name);
   st->print(" - owner thread: " PTR_FORMAT, p2i(_owner));
@@ -278,7 +278,7 @@
 // Non-product code
 
 #ifndef PRODUCT
-void Monitor::print_on(outputStream* st) const {
+void Mutex::print_on(outputStream* st) const {
   st->print_cr("Mutex: [" PTR_FORMAT "] %s - owner: " PTR_FORMAT,
                p2i(this), _name, p2i(_owner));
 }
@@ -287,7 +287,7 @@
 #ifndef PRODUCT
 #ifdef ASSERT
 
-void Monitor::assert_owner(Thread * expected) {
+void Mutex::assert_owner(Thread * expected) {
   const char* msg = "invalid owner";
   if (expected == NULL) {
     msg = "should be un-owned";
@@ -300,8 +300,8 @@
          msg, p2i(_owner), p2i(expected));
 }
 
-Monitor * Monitor::get_least_ranked_lock(Monitor * locks) {
-  Monitor *res, *tmp;
+Mutex* Mutex::get_least_ranked_lock(Mutex* locks) {
+  Mutex *res, *tmp;
   for (res = tmp = locks; tmp != NULL; tmp = tmp->next()) {
     if (tmp->rank() < res->rank()) {
       res = tmp;
@@ -320,8 +320,8 @@
   return res;
 }
 
-Monitor* Monitor::get_least_ranked_lock_besides_this(Monitor* locks) {
-  Monitor *res, *tmp;
+Mutex* Mutex::get_least_ranked_lock_besides_this(Mutex* locks) {
+  Mutex *res, *tmp;
   for (res = NULL, tmp = locks; tmp != NULL; tmp = tmp->next()) {
     if (tmp != this && (res == NULL || tmp->rank() < res->rank())) {
       res = tmp;
@@ -341,7 +341,7 @@
 }
 
 
-bool Monitor::contains(Monitor* locks, Monitor * lock) {
+bool Mutex::contains(Mutex* locks, Mutex* lock) {
   for (; locks != NULL; locks = locks->next()) {
     if (locks == lock) {
       return true;
@@ -356,7 +356,7 @@
 // might indicate exposure to deadlock.
 // Rather like an EventListener for _owner (:>).
 
-void Monitor::set_owner_implementation(Thread *new_owner) {
+void Mutex::set_owner_implementation(Thread *new_owner) {
   // This function is solely responsible for maintaining
   // and checking the invariant that threads and locks
   // are in a 1/N relation, with some some locks unowned.
@@ -377,7 +377,7 @@
     // link "this" into the owned locks list
 
 #ifdef ASSERT  // Thread::_owned_locks is under the same ifdef
-    Monitor* locks = get_least_ranked_lock(new_owner->owned_locks());
+    Mutex* locks = get_least_ranked_lock(new_owner->owned_locks());
     // Mutex::set_owner_implementation is a friend of Thread
 
     assert(this->rank() >= 0, "bad lock rank");
@@ -415,11 +415,11 @@
     _owner = NULL; // set the owner
 
 #ifdef ASSERT
-    Monitor *locks = old_owner->owned_locks();
+    Mutex* locks = old_owner->owned_locks();
 
     // remove "this" from the owned locks list
 
-    Monitor *prev = NULL;
+    Mutex* prev = NULL;
     bool found = false;
     for (; locks != NULL; prev = locks, locks = locks->next()) {
       if (locks == this) {
@@ -440,7 +440,7 @@
 
 
 // Factored out common sanity checks for locking mutex'es. Used by lock() and try_lock()
-void Monitor::check_prelock_state(Thread *thread, bool safepoint_check) {
+void Mutex::check_prelock_state(Thread *thread, bool safepoint_check) {
   if (safepoint_check) {
     assert((!thread->is_active_Java_thread() || ((JavaThread *)thread)->thread_state() == _thread_in_vm)
            || rank() == Mutex::special, "wrong thread state for using locks");
@@ -454,13 +454,13 @@
          "locking not allowed when crash protection is set");
 }
 
-void Monitor::check_block_state(Thread *thread) {
+void Mutex::check_block_state(Thread *thread) {
   if (!_allow_vm_block && thread->is_VM_thread()) {
     warning("VM thread blocked on lock");
     print();
     BREAKPOINT;
   }
-  assert(_owner != thread, "deadlock: blocking on monitor owned by current thread");
+  assert(_owner != thread, "deadlock: blocking on mutex owned by current thread");
 }
 
 #endif // PRODUCT
--- a/src/hotspot/share/runtime/mutex.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/mutex.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -32,12 +32,12 @@
 // variable that supports lock ownership tracking, lock ranking for deadlock
 // detection and coordinates with the safepoint protocol.
 
-// The default length of monitor name was originally chosen to be 64 to avoid
-// false sharing. Now, PaddedMonitor is available for this purpose.
-// TODO: Check if _name[MONITOR_NAME_LEN] should better get replaced by const char*.
-static const int MONITOR_NAME_LEN = 64;
+// The default length of mutex name was originally chosen to be 64 to avoid
+// false sharing. Now, PaddedMutex and PaddedMonitor are available for this purpose.
+// TODO: Check if _name[MUTEX_NAME_LEN] should better get replaced by const char*.
+static const int MUTEX_NAME_LEN = 64;
 
-class Monitor : public CHeapObj<mtSynchronizer> {
+class Mutex : public CHeapObj<mtSynchronizer> {
 
  public:
   // A special lock: Is a lock where you are guaranteed not to block while you are
@@ -78,17 +78,17 @@
  protected:                              // Monitor-Mutex metadata
   Thread * volatile _owner;              // The owner of the lock
   os::PlatformMonitor _lock;             // Native monitor implementation
-  char _name[MONITOR_NAME_LEN];          // Name of mutex/monitor
+  char _name[MUTEX_NAME_LEN];            // Name of mutex/monitor
 
   // Debugging fields for naming, deadlock detection, etc. (some only used in debug mode)
 #ifndef PRODUCT
   bool      _allow_vm_block;
   DEBUG_ONLY(int _rank;)                 // rank (to avoid/detect potential deadlocks)
-  DEBUG_ONLY(Monitor * _next;)           // Used by a Thread to link up owned locks
+  DEBUG_ONLY(Mutex* _next;)              // Used by a Thread to link up owned locks
   DEBUG_ONLY(Thread* _last_owner;)       // the last thread to own the lock
-  DEBUG_ONLY(static bool contains(Monitor * locks, Monitor * lock);)
-  DEBUG_ONLY(static Monitor * get_least_ranked_lock(Monitor * locks);)
-  DEBUG_ONLY(Monitor * get_least_ranked_lock_besides_this(Monitor * locks);)
+  DEBUG_ONLY(static bool contains(Mutex* locks, Mutex* lock);)
+  DEBUG_ONLY(static Mutex* get_least_ranked_lock(Mutex* locks);)
+  DEBUG_ONLY(Mutex* get_least_ranked_lock_besides_this(Mutex* locks);)
 #endif
 
   void set_owner_implementation(Thread* owner)                        PRODUCT_RETURN;
@@ -96,7 +96,6 @@
   void check_block_state       (Thread* thread)                       PRODUCT_RETURN;
   void check_safepoint_state   (Thread* thread, bool safepoint_check) NOT_DEBUG_RETURN;
   void assert_owner            (Thread* expected)                     NOT_DEBUG_RETURN;
-  void assert_wait_lock_state  (Thread* self)                         NOT_DEBUG_RETURN;
 
  public:
   enum {
@@ -130,32 +129,21 @@
   };
 
   enum SafepointCheckRequired {
-    _safepoint_check_never,       // Monitors with this value will cause errors
+    _safepoint_check_never,       // Mutexes with this value will cause errors
                                   // when acquired by a JavaThread with a safepoint check.
     _safepoint_check_sometimes,   // A couple of special locks are acquired by JavaThreads sometimes
                                   // with and sometimes without safepoint checks. These
                                   // locks will not produce errors when locked.
-    _safepoint_check_always       // Monitors with this value will cause errors
+    _safepoint_check_always       // Mutexes with this value will cause errors
                                   // when acquired by a JavaThread without a safepoint check.
   };
 
   NOT_PRODUCT(SafepointCheckRequired _safepoint_check_required;)
 
  public:
-  Monitor(int rank, const char *name, bool allow_vm_block = false,
-          SafepointCheckRequired safepoint_check_required = _safepoint_check_always);
-  ~Monitor();
-
-  // Wait until monitor is notified (or times out).
-  // Defaults are to make safepoint checks, wait time is forever (i.e.,
-  // zero), and not a suspend-equivalent condition. Returns true if wait
-  // times out; otherwise returns false.
-  bool wait(long timeout = 0,
-            bool as_suspend_equivalent = !_as_suspend_equivalent_flag);
-  bool wait_without_safepoint_check(long timeout = 0);
-  void notify();
-  void notify_all();
-
+  Mutex(int rank, const char *name, bool allow_vm_block = false,
+        SafepointCheckRequired safepoint_check_required = _safepoint_check_always);
+  ~Mutex();
 
   void lock(); // prints out warning if VM thread blocks
   void lock(Thread *thread); // overloaded with current thread
@@ -186,19 +174,49 @@
     DEBUG_ONLY(int    rank() const          { return _rank; })
     bool   allow_vm_block()                 { return _allow_vm_block; }
 
-    DEBUG_ONLY(Monitor *next()  const         { return _next; })
-    DEBUG_ONLY(void   set_next(Monitor *next) { _next = next; })
+    DEBUG_ONLY(Mutex *next()  const         { return _next; })
+    DEBUG_ONLY(void   set_next(Mutex *next) { _next = next; })
   #endif
 
   void set_owner(Thread* owner) {
   #ifndef PRODUCT
     set_owner_implementation(owner);
-    DEBUG_ONLY(void verify_Monitor(Thread* thr);)
+    DEBUG_ONLY(void verify_mutex(Thread* thr);)
   #else
     _owner = owner;
   #endif
   }
+};
 
+class Monitor : public Mutex {
+  void assert_wait_lock_state  (Thread* self)                         NOT_DEBUG_RETURN;
+ public:
+   Monitor(int rank, const char *name, bool allow_vm_block = false,
+         SafepointCheckRequired safepoint_check_required = _safepoint_check_always);
+   // default destructor
+
+  // Wait until monitor is notified (or times out).
+  // Defaults are to make safepoint checks, wait time is forever (i.e.,
+  // zero), and not a suspend-equivalent condition. Returns true if wait
+  // times out; otherwise returns false.
+  bool wait(long timeout = 0,
+            bool as_suspend_equivalent = !_as_suspend_equivalent_flag);
+  bool wait_without_safepoint_check(long timeout = 0);
+  void notify();
+  void notify_all();
+};
+
+
+class PaddedMutex : public Mutex {
+  enum {
+    CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Mutex),
+    PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
+  };
+  char _padding[PADDING_LEN];
+public:
+  PaddedMutex(int rank, const char *name, bool allow_vm_block = false,
+              SafepointCheckRequired safepoint_check_required = _safepoint_check_always) :
+    Mutex(rank, name, allow_vm_block, safepoint_check_required) {};
 };
 
 class PaddedMonitor : public Monitor {
@@ -213,49 +231,4 @@
     Monitor(rank, name, allow_vm_block, safepoint_check_required) {};
 };
 
-// Normally we'd expect Monitor to extend Mutex in the sense that a monitor
-// constructed from pthreads primitives might extend a mutex by adding
-// a condvar and some extra metadata.  In fact this was the case until J2SE7.
-//
-// Currently, however, the base object is a monitor.  Monitor contains all the
-// logic for wait(), notify(), etc.   Mutex extends monitor and restricts the
-// visibility of wait(), notify(), and notify_all().
-//
-// Another viable alternative would have been to have Monitor extend Mutex and
-// implement all the normal mutex and wait()-notify() logic in Mutex base class.
-// The wait()-notify() facility would be exposed via special protected member functions
-// (e.g., _Wait() and _Notify()) in Mutex.  Monitor would extend Mutex and expose wait()
-// as a call to _Wait().  That is, the public wait() would be a wrapper for the protected
-// _Wait().
-//
-// An even better alternative is to simply eliminate Mutex:: and use Monitor:: instead.
-// After all, monitors are sufficient for Java-level synchronization.   At one point in time
-// there may have been some benefit to having distinct mutexes and monitors, but that time
-// has passed.
-//
-
-class Mutex : public Monitor {      // degenerate Monitor
- public:
-   Mutex(int rank, const char *name, bool allow_vm_block = false,
-         SafepointCheckRequired safepoint_check_required = _safepoint_check_always);
-   // default destructor
- private:
-   void notify();
-   void notify_all();
-   bool wait(long timeout, bool as_suspend_equivalent);
-   bool wait_without_safepoint_check(long timeout);
-};
-
-class PaddedMutex : public Mutex {
-  enum {
-    CACHE_LINE_PADDING = (int)DEFAULT_CACHE_LINE_SIZE - (int)sizeof(Mutex),
-    PADDING_LEN = CACHE_LINE_PADDING > 0 ? CACHE_LINE_PADDING : 1
-  };
-  char _padding[PADDING_LEN];
-public:
-  PaddedMutex(int rank, const char *name, bool allow_vm_block = false,
-              SafepointCheckRequired safepoint_check_required = _safepoint_check_always) :
-    Mutex(rank, name, allow_vm_block, safepoint_check_required) {};
-};
-
 #endif // SHARE_RUNTIME_MUTEX_HPP
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -46,19 +46,7 @@
 Mutex*   CompiledIC_lock              = NULL;
 Mutex*   InlineCacheBuffer_lock       = NULL;
 Mutex*   VMStatistic_lock             = NULL;
-Mutex*   JNIGlobalAlloc_lock          = NULL;
-Mutex*   JNIGlobalActive_lock         = NULL;
-Mutex*   JNIWeakAlloc_lock            = NULL;
-Mutex*   JNIWeakActive_lock           = NULL;
-Mutex*   StringTableWeakAlloc_lock    = NULL;
-Mutex*   StringTableWeakActive_lock   = NULL;
 Mutex*   JNIHandleBlockFreeList_lock  = NULL;
-Mutex*   VMGlobalAlloc_lock           = NULL;
-Mutex*   VMGlobalActive_lock          = NULL;
-Mutex*   VMWeakAlloc_lock             = NULL;
-Mutex*   VMWeakActive_lock            = NULL;
-Mutex*   ResolvedMethodTableWeakAlloc_lock  = NULL;
-Mutex*   ResolvedMethodTableWeakActive_lock = NULL;
 Mutex*   JmethodIdCreation_lock       = NULL;
 Mutex*   JfieldIdCreation_lock        = NULL;
 Monitor* JNICritical_lock             = NULL;
@@ -142,7 +130,7 @@
 #ifndef SUPPORTS_NATIVE_CX8
 Mutex*   UnsafeJlong_lock             = NULL;
 #endif
-Monitor* CodeHeapStateAnalytics_lock  = NULL;
+Mutex*   CodeHeapStateAnalytics_lock  = NULL;
 
 Mutex*   MetaspaceExpand_lock         = NULL;
 Mutex*   ClassLoaderDataGraph_lock    = NULL;
@@ -165,11 +153,11 @@
 
 
 #define MAX_NUM_MUTEX 128
-static Monitor * _mutex_array[MAX_NUM_MUTEX];
+static Mutex* _mutex_array[MAX_NUM_MUTEX];
 static int _num_mutex;
 
 #ifdef ASSERT
-void assert_locked_or_safepoint(const Monitor * lock) {
+void assert_locked_or_safepoint(const Mutex* lock) {
   // check if this thread owns the lock (common case)
   if (IgnoreLockingAssertions) return;
   assert(lock != NULL, "Need non-NULL lock");
@@ -183,7 +171,7 @@
 }
 
 // a weaker assertion than the above
-void assert_locked_or_safepoint_weak(const Monitor * lock) {
+void assert_locked_or_safepoint_weak(const Mutex* lock) {
   if (IgnoreLockingAssertions) return;
   assert(lock != NULL, "Need non-NULL lock");
   if (lock->is_locked()) return;
@@ -193,7 +181,7 @@
 }
 
 // a stronger assertion than the above
-void assert_lock_strong(const Monitor * lock) {
+void assert_lock_strong(const Mutex* lock) {
   if (IgnoreLockingAssertions) return;
   assert(lock != NULL, "Need non-NULL lock");
   if (lock->owned_by_self()) return;
@@ -214,18 +202,6 @@
   def(CGC_lock                     , PaddedMonitor, special,     true,  Monitor::_safepoint_check_never);      // coordinate between fore- and background GC
   def(STS_lock                     , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);
 
-  def(VMGlobalAlloc_lock           , PaddedMutex  , oopstorage,  true,  Monitor::_safepoint_check_never);
-  def(VMGlobalActive_lock          , PaddedMutex  , oopstorage-1,true,  Monitor::_safepoint_check_never);
-
-  def(VMWeakAlloc_lock             , PaddedMutex  , oopstorage,  true,  Monitor::_safepoint_check_never);
-  def(VMWeakActive_lock            , PaddedMutex  , oopstorage-1,true,  Monitor::_safepoint_check_never);
-
-  def(StringTableWeakAlloc_lock    , PaddedMutex  , oopstorage,  true,  Monitor::_safepoint_check_never);
-  def(StringTableWeakActive_lock   , PaddedMutex  , oopstorage-1,true,  Monitor::_safepoint_check_never);
-
-  def(ResolvedMethodTableWeakAlloc_lock    , PaddedMutex  , oopstorage,   true,  Monitor::_safepoint_check_never);
-  def(ResolvedMethodTableWeakActive_lock   , PaddedMutex  , oopstorage-1, true,  Monitor::_safepoint_check_never);
-
   def(FullGCCount_lock             , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);      // in support of ExplicitGCInvokesConcurrent
   if (UseG1GC) {
     def(DirtyCardQ_CBL_mon         , PaddedMonitor, access,      true,  Monitor::_safepoint_check_never);
@@ -249,7 +225,7 @@
   }
   def(ParGCRareEvent_lock          , PaddedMutex  , leaf     ,   true,  Monitor::_safepoint_check_always);
   def(CGCPhaseManager_lock         , PaddedMonitor, leaf,        false, Monitor::_safepoint_check_always);
-  def(CodeCache_lock               , PaddedMutex  , special,     true,  Monitor::_safepoint_check_never);
+  def(CodeCache_lock               , PaddedMonitor, special,     true,  Monitor::_safepoint_check_never);
   def(RawMonitor_lock              , PaddedMutex  , special,     true,  Monitor::_safepoint_check_never);
   def(OopMapCacheAlloc_lock        , PaddedMutex  , leaf,        true,  Monitor::_safepoint_check_always); // used for oop_map_cache allocation.
 
@@ -296,10 +272,6 @@
   def(InitCompleted_lock           , PaddedMonitor, leaf,        true,  Monitor::_safepoint_check_never);
   def(VtableStubs_lock             , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_never);
   def(Notify_lock                  , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_always);
-  def(JNIGlobalAlloc_lock          , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_never);
-  def(JNIGlobalActive_lock         , PaddedMutex  , nonleaf-1,   true,  Monitor::_safepoint_check_never);
-  def(JNIWeakAlloc_lock            , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_never);
-  def(JNIWeakActive_lock           , PaddedMutex  , nonleaf-1,   true,  Monitor::_safepoint_check_never);
   def(JNICritical_lock             , PaddedMonitor, nonleaf,     true,  Monitor::_safepoint_check_always); // used for JNI critical regions
   def(AdapterHandlerLibrary_lock   , PaddedMutex  , nonleaf,     true,  Monitor::_safepoint_check_always);
 
@@ -362,7 +334,7 @@
 #endif // INCLUDE_CDS
 }
 
-GCMutexLocker::GCMutexLocker(Monitor * mutex) {
+GCMutexLocker::GCMutexLocker(Mutex* mutex) {
   if (SafepointSynchronize::is_at_safepoint()) {
     _locked = false;
   } else {
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -39,19 +39,7 @@
 extern Mutex*   CompiledIC_lock;                 // a lock used to guard compiled IC patching and access
 extern Mutex*   InlineCacheBuffer_lock;          // a lock used to guard the InlineCacheBuffer
 extern Mutex*   VMStatistic_lock;                // a lock used to guard statistics count increment
-extern Mutex*   JNIGlobalAlloc_lock;             // JNI global storage allocate list lock
-extern Mutex*   JNIGlobalActive_lock;            // JNI global storage active list lock
-extern Mutex*   JNIWeakAlloc_lock;               // JNI weak storage allocate list lock
-extern Mutex*   JNIWeakActive_lock;              // JNI weak storage active list lock
-extern Mutex*   StringTableWeakAlloc_lock;       // StringTable weak storage allocate list lock
-extern Mutex*   StringTableWeakActive_lock;      // STringTable weak storage active list lock
 extern Mutex*   JNIHandleBlockFreeList_lock;     // a lock on the JNI handle block free list
-extern Mutex*   VMGlobalAlloc_lock;              // VM Global Handles storage allocate list lock
-extern Mutex*   VMGlobalActive_lock;             // VM Global Handles storage active list lock
-extern Mutex*   VMWeakAlloc_lock;                // VM Weak Handles storage allocate list lock
-extern Mutex*   VMWeakActive_lock;               // VM Weak Handles storage active list lock
-extern Mutex*   ResolvedMethodTableWeakAlloc_lock;  // ResolvedMethodTable weak storage allocate list
-extern Mutex*   ResolvedMethodTableWeakActive_lock; // ResolvedMethodTable weak storage active list
 extern Mutex*   JmethodIdCreation_lock;          // a lock on creating JNI method identifiers
 extern Mutex*   JfieldIdCreation_lock;           // a lock on creating JNI static field identifiers
 extern Monitor* JNICritical_lock;                // a lock used while entering and exiting JNI critical regions, allows GC to sometimes get in
@@ -154,7 +142,7 @@
 extern Mutex*   ClassLoaderDataGraph_lock;       // protects CLDG list, needed for concurrent unloading
 
 
-extern Monitor* CodeHeapStateAnalytics_lock;     // lock print functions against concurrent analyze functions.
+extern Mutex*   CodeHeapStateAnalytics_lock;     // lock print functions against concurrent analyze functions.
                                                  // Only used locally in PrintCodeCacheLayout processing.
 
 #if INCLUDE_JVMCI
@@ -183,9 +171,9 @@
 
 // for debugging: check that we're already owning this lock (or are at a safepoint)
 #ifdef ASSERT
-void assert_locked_or_safepoint(const Monitor * lock);
-void assert_locked_or_safepoint_weak(const Monitor * lock);
-void assert_lock_strong(const Monitor * lock);
+void assert_locked_or_safepoint(const Mutex* lock);
+void assert_locked_or_safepoint_weak(const Mutex* lock);
+void assert_lock_strong(const Mutex* lock);
 #else
 #define assert_locked_or_safepoint(lock)
 #define assert_locked_or_safepoint_weak(lock)
@@ -194,10 +182,10 @@
 
 class MutexLocker: public StackObj {
  protected:
-  Monitor* _mutex;
+  Mutex* _mutex;
  private:
  public:
-  MutexLocker(Monitor* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
+  MutexLocker(Mutex* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
     _mutex(mutex) {
     bool no_safepoint_check = flag == Mutex::_no_safepoint_check_flag;
     if (_mutex != NULL) {
@@ -211,7 +199,7 @@
     }
   }
 
-  MutexLocker(Monitor* mutex, Thread* thread, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
+  MutexLocker(Mutex* mutex, Thread* thread, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
     _mutex(mutex) {
     bool no_safepoint_check = flag == Mutex::_no_safepoint_check_flag;
     if (_mutex != NULL) {
@@ -239,35 +227,36 @@
 
 class MonitorLocker: public MutexLocker {
   Mutex::SafepointCheckFlag _flag;
+  Monitor* _monitor;
  public:
   MonitorLocker(Monitor* monitor, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
-    MutexLocker(monitor, flag), _flag(flag) {
+    MutexLocker(monitor, flag), _flag(flag), _monitor(monitor) {
     // Superclass constructor did locking
-    assert(_mutex != NULL, "NULL monitor not allowed");
+    assert(_monitor != NULL, "NULL monitor not allowed");
   }
 
   MonitorLocker(Monitor* monitor, Thread* thread, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
-    MutexLocker(monitor, thread, flag), _flag(flag)  {
+    MutexLocker(monitor, thread, flag), _flag(flag), _monitor(monitor)  {
     // Superclass constructor did locking
-    assert(_mutex != NULL, "NULL monitor not allowed");
+    assert(_monitor != NULL, "NULL monitor not allowed");
   }
 
   bool wait(long timeout = 0,
             bool as_suspend_equivalent = !Mutex::_as_suspend_equivalent_flag) {
     if (_flag == Mutex::_safepoint_check_flag) {
-      return _mutex->wait(timeout, as_suspend_equivalent);
+      return _monitor->wait(timeout, as_suspend_equivalent);
     } else {
-      return _mutex->wait_without_safepoint_check(timeout);
+      return _monitor->wait_without_safepoint_check(timeout);
     }
     return false;
   }
 
   void notify_all() {
-    _mutex->notify_all();
+    _monitor->notify_all();
   }
 
   void notify() {
-    _mutex->notify();
+    _monitor->notify();
   }
 };
 
@@ -280,10 +269,10 @@
 
 class GCMutexLocker: public StackObj {
 private:
-  Monitor* _mutex;
+  Mutex* _mutex;
   bool _locked;
 public:
-  GCMutexLocker(Monitor* mutex);
+  GCMutexLocker(Mutex* mutex);
   ~GCMutexLocker() { if (_locked) _mutex->unlock(); }
 };
 
@@ -292,11 +281,11 @@
 
 class MutexUnlocker: StackObj {
  private:
-  Monitor* _mutex;
+  Mutex* _mutex;
   bool _no_safepoint_check;
 
  public:
-  MutexUnlocker(Monitor* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
+  MutexUnlocker(Mutex* mutex, Mutex::SafepointCheckFlag flag = Mutex::_safepoint_check_flag) :
     _mutex(mutex),
     _no_safepoint_check(flag) {
     _mutex->unlock();
--- a/src/hotspot/share/runtime/objectMonitor.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/objectMonitor.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -28,7 +28,7 @@
 #include "jfr/support/jfrThreadId.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
--- a/src/hotspot/share/runtime/objectMonitor.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/objectMonitor.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,7 +27,7 @@
 
 #include "memory/allocation.hpp"
 #include "memory/padded.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/os.hpp"
 #include "runtime/park.hpp"
 #include "runtime/perfData.hpp"
@@ -44,8 +44,8 @@
  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;
+  ObjectWaiter* volatile _next;
+  ObjectWaiter* volatile _prev;
   Thread*       _thread;
   jlong         _notifier_tid;
   ParkEvent *   _event;
@@ -75,7 +75,7 @@
 // ObjectMonitor Layout Overview/Highlights/Restrictions:
 //
 // - The _header field must be at offset 0 because the displaced header
-//   from markWord is stored there. We do not want markOop.hpp to include
+//   from markWord is stored there. We do not want markWord.hpp to include
 //   ObjectMonitor.hpp to avoid exposing ObjectMonitor everywhere. This
 //   means that ObjectMonitor cannot inherit from any other class nor can
 //   it use any virtual member functions. This restriction is critical to
@@ -142,25 +142,35 @@
   friend class VMStructs;
   JVMCI_ONLY(friend class JVMCIVMStructs;)
 
-  volatile markWord  _header;       // displaced object header word - mark
-  void*     volatile _object;       // backward object pointer - strong root
+  // The sync code expects the header field to be at offset zero (0).
+  // Enforced by the assert() in header_addr().
+  volatile markWord _header;        // displaced object header word - mark
+  void* volatile _object;           // backward object pointer - strong root
  public:
-  ObjectMonitor*     FreeNext;      // Free list linkage
+  ObjectMonitor* _next_om;          // Next ObjectMonitor* linkage
  private:
+  // Separate _header and _owner on different cache lines since both can
+  // have busy multi-threaded access. _header and _object are set at
+  // initial inflation and _object doesn't change until deflation so
+  // _object is a good choice to share the cache line with _header.
+  // _next_om shares _header's cache line for pre-monitor list historical
+  // reasons. _next_om only changes if the next ObjectMonitor is deflated.
   DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE,
-                        sizeof(volatile markWord) + sizeof(void * volatile) +
+                        sizeof(volatile markWord) + sizeof(void* volatile) +
                         sizeof(ObjectMonitor *));
  protected:                         // protected for JvmtiRawMonitor
-  void *  volatile _owner;          // pointer to owning thread OR BasicLock
+  void* volatile _owner;            // pointer to owning thread OR BasicLock
+ private:
   volatile jlong _previous_owner_tid;  // thread id of the previous owner of the monitor
-  volatile intptr_t  _recursions;   // recursion count, 0 for first entry
-  ObjectWaiter * volatile _EntryList; // Threads blocked on entry or reentry.
+ 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;
+  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;
 
   volatile int _Spinner;            // for exit->spinner handoff optimization
   volatile int _SpinDuration;
@@ -169,7 +179,7 @@
                                     // along with other fields to determine if an ObjectMonitor can be
                                     // deflated. See ObjectSynchronizer::deflate_monitor().
  protected:
-  ObjectWaiter * volatile _WaitSet; // LL of threads wait()ing on the monitor
+  ObjectWaiter* volatile _WaitSet;  // LL of threads wait()ing on the monitor
   volatile jint  _waiters;          // number of waiting threads
  private:
   volatile int _WaitSetLock;        // protects Wait Queue - simple spinlock
@@ -202,7 +212,7 @@
   void* operator new (size_t size) throw();
   void* operator new[] (size_t size) throw();
   void operator delete(void* p);
-  void operator delete[] (void *p);
+  void operator delete[] (void* p);
 
   // TODO-FIXME: the "offset" routines should return a type of off_t instead of int ...
   // ByteSize would also be an appropriate type.
@@ -256,7 +266,7 @@
  protected:
   // We don't typically expect or want the ctors or dtors to run.
   // normal ObjectMonitors are type-stable and immortal.
-  ObjectMonitor() { ::memset((void *)this, 0, sizeof(*this)); }
+  ObjectMonitor() { ::memset((void*)this, 0, sizeof(*this)); }
 
   ~ObjectMonitor() {
     // TODO: Add asserts ...
@@ -305,18 +315,18 @@
   void      reenter(intptr_t recursions, TRAPS);
 
  private:
-  void      AddWaiter(ObjectWaiter * waiter);
-  void      INotify(Thread * Self);
-  ObjectWaiter * DequeueWaiter();
-  void      DequeueSpecificWaiter(ObjectWaiter * waiter);
+  void      AddWaiter(ObjectWaiter* waiter);
+  void      INotify(Thread* self);
+  ObjectWaiter* DequeueWaiter();
+  void      DequeueSpecificWaiter(ObjectWaiter* waiter);
   void      EnterI(TRAPS);
-  void      ReenterI(Thread * Self, ObjectWaiter * SelfNode);
-  void      UnlinkAfterAcquire(Thread * Self, ObjectWaiter * SelfNode);
-  int       TryLock(Thread * Self);
-  int       NotRunnable(Thread * Self, Thread * Owner);
-  int       TrySpin(Thread * Self);
-  void      ExitEpilog(Thread * Self, ObjectWaiter * Wakee);
-  bool      ExitSuspendEquivalent(JavaThread * Self);
+  void      ReenterI(Thread* self, ObjectWaiter* self_node);
+  void      UnlinkAfterAcquire(Thread* self, ObjectWaiter* self_node);
+  int       TryLock(Thread* self);
+  int       NotRunnable(Thread* self, Thread * Owner);
+  int       TrySpin(Thread* self);
+  void      ExitEpilog(Thread* self, ObjectWaiter* Wakee);
+  bool      ExitSuspendEquivalent(JavaThread* self);
 };
 
 #endif // SHARE_RUNTIME_OBJECTMONITOR_HPP
--- a/src/hotspot/share/runtime/os.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/os.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -279,6 +279,19 @@
   return false;
 }
 
+// Frees all memory allocated on the heap for the
+// supplied array of arrays of chars (a), where n
+// is the number of elements in the array.
+static void free_array_of_char_arrays(char** a, size_t n) {
+      while (n > 0) {
+          n--;
+          if (a[n] != NULL) {
+            FREE_C_HEAP_ARRAY(char, a[n]);
+          }
+      }
+      FREE_C_HEAP_ARRAY(char*, a);
+}
+
 bool os::dll_locate_lib(char *buffer, size_t buflen,
                         const char* pname, const char* fname) {
   bool retval = false;
@@ -299,10 +312,10 @@
       }
     } else if (strchr(pname, *os::path_separator()) != NULL) {
       // A list of paths. Search for the path that contains the library.
-      int n;
-      char** pelements = split_path(pname, &n);
+      size_t n;
+      char** pelements = split_path(pname, &n, fullfnamelen);
       if (pelements != NULL) {
-        for (int i = 0; i < n; i++) {
+        for (size_t i = 0; i < n; i++) {
           char* path = pelements[i];
           // Really shouldn't be NULL, but check can't hurt.
           size_t plen = (path == NULL) ? 0 : strlen(path);
@@ -314,12 +327,7 @@
           if (retval) break;
         }
         // Release the storage allocated by split_path.
-        for (int i = 0; i < n; i++) {
-          if (pelements[i] != NULL) {
-            FREE_C_HEAP_ARRAY(char, pelements[i]);
-          }
-        }
-        FREE_C_HEAP_ARRAY(char*, pelements);
+        free_array_of_char_arrays(pelements, n);
       }
     } else {
       // A definite path.
@@ -1074,37 +1082,10 @@
   }
 
   // Check if addr points into Java heap.
-  if (Universe::heap()->is_in(addr)) {
-    oop o = oopDesc::oop_or_null(addr);
-    if (o != NULL) {
-      if ((HeapWord*)o == (HeapWord*)addr) {
-        st->print(INTPTR_FORMAT " is an oop: ", p2i(addr));
-      } else {
-        st->print(INTPTR_FORMAT " is pointing into object: " , p2i(addr));
-      }
-      ResourceMark rm;
-      o->print_on(st);
-      return;
-    }
-  } else if (Universe::heap()->is_in_reserved(addr)) {
-    st->print_cr(INTPTR_FORMAT " is an unallocated location in the heap", p2i(addr));
+  if (Universe::heap()->print_location(st, addr)) {
     return;
   }
 
-  // Compressed oop needs to be decoded first.
-#ifdef _LP64
-  if (UseCompressedOops && ((uintptr_t)addr &~ (uintptr_t)max_juint) == 0) {
-    narrowOop narrow_oop = (narrowOop)(uintptr_t)addr;
-    oop o = CompressedOops::decode_raw(narrow_oop);
-
-    if (oopDesc::is_valid(o)) {
-      st->print(UINT32_FORMAT " is a compressed pointer to object: ", narrow_oop);
-      o->print_on(st);
-      return;
-    }
-  }
-#endif
-
   bool accessible = is_readable_pointer(addr);
 
   // Check if addr is a JNI handle.
@@ -1335,17 +1316,22 @@
   return false;
 }
 
-/*
- * Splits a path, based on its separator, the number of
- * elements is returned back in n.
- * It is the callers responsibility to:
- *   a> check the value of n, and n may be 0.
- *   b> ignore any empty path elements
- *   c> free up the data.
- */
-char** os::split_path(const char* path, int* n) {
-  *n = 0;
-  if (path == NULL || strlen(path) == 0) {
+// Splits a path, based on its separator, the number of
+// elements is returned back in "elements".
+// file_name_length is used as a modifier for each path's
+// length when compared to JVM_MAXPATHLEN. So if you know
+// each returned path will have something appended when
+// in use, you can pass the length of that in
+// file_name_length, to ensure we detect if any path
+// exceeds the maximum path length once prepended onto
+// the sub-path/file name.
+// It is the callers responsibility to:
+//   a> check the value of "elements", which may be 0.
+//   b> ignore any empty path elements
+//   c> free up the data.
+char** os::split_path(const char* path, size_t* elements, size_t file_name_length) {
+  *elements = (size_t)0;
+  if (path == NULL || strlen(path) == 0 || file_name_length == (size_t)NULL) {
     return NULL;
   }
   const char psepchar = *os::path_separator();
@@ -1354,7 +1340,7 @@
     return NULL;
   }
   strcpy(inpath, path);
-  int count = 1;
+  size_t count = 1;
   char* p = strchr(inpath, psepchar);
   // Get a count of elements to allocate memory
   while (p != NULL) {
@@ -1363,20 +1349,23 @@
     p = strchr(p, psepchar);
   }
   char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count, mtInternal);
-  if (opath == NULL) {
-    return NULL;
-  }
 
   // do the actual splitting
   p = inpath;
-  for (int i = 0 ; i < count ; i++) {
+  for (size_t i = 0 ; i < count ; i++) {
     size_t len = strcspn(p, os::path_separator());
-    if (len > JVM_MAXPATHLEN) {
-      return NULL;
+    if (len + file_name_length > JVM_MAXPATHLEN) {
+      // release allocated storage before exiting the vm
+      free_array_of_char_arrays(opath, i++);
+      vm_exit_during_initialization("The VM tried to use a path that exceeds the maximum path length for "
+                                    "this system. Review path-containing parameters and properties, such as "
+                                    "sun.boot.library.path, to identify potential sources for this path.");
     }
     // allocate the string and add terminator storage
-    char* s  = (char*)NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
+    char* s  = (char*)NEW_C_HEAP_ARRAY_RETURN_NULL(char, len + 1, mtInternal);
     if (s == NULL) {
+      // release allocated storage before returning null
+      free_array_of_char_arrays(opath, i++);
       return NULL;
     }
     strncpy(s, p, len);
@@ -1385,7 +1374,7 @@
     p += len + 1;
   }
   FREE_C_HEAP_ARRAY(char, inpath);
-  *n = count;
+  *elements = count;
   return opath;
 }
 
--- a/src/hotspot/share/runtime/os.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/os.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -821,7 +821,10 @@
   // Amount beyond the callee frame size that we bang the stack.
   static int extra_bang_size_in_bytes();
 
-  static char** split_path(const char* path, int* n);
+  static char** split_path(const char* path, size_t* elements, size_t file_name_length);
+
+  // support for mapping non-volatile memory using MAP_SYNC
+  static bool supports_map_sync();
 
   // Extensions
 #include "runtime/os_ext.hpp"
--- a/src/hotspot/share/runtime/perfMemory.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/perfMemory.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -25,6 +25,7 @@
 #ifndef SHARE_RUNTIME_PERFMEMORY_HPP
 #define SHARE_RUNTIME_PERFMEMORY_HPP
 
+#include "runtime/globals.hpp"
 #include "utilities/exceptions.hpp"
 
 /*
--- a/src/hotspot/share/runtime/serviceThread.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/serviceThread.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,6 +27,8 @@
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "gc/shared/oopStorage.hpp"
+#include "gc/shared/oopStorageSet.hpp"
 #include "memory/universe.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
@@ -83,22 +85,14 @@
   }
 }
 
-static void cleanup_oopstorages(OopStorage* const* storages, size_t size) {
-  for (size_t i = 0; i < size; ++i) {
-    storages[i]->delete_empty_blocks();
+static void cleanup_oopstorages() {
+  OopStorageSet::Iterator it = OopStorageSet::all_iterator();
+  for ( ; !it.is_end(); ++it) {
+    it->delete_empty_blocks();
   }
 }
 
 void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) {
-  OopStorage* const oopstorages[] = {
-    JNIHandles::global_handles(),
-    JNIHandles::weak_global_handles(),
-    StringTable::weak_storage(),
-    SystemDictionary::vm_global_oop_storage(),
-    SystemDictionary::vm_weak_oop_storage()
-  };
-  const size_t oopstorage_count = ARRAY_SIZE(oopstorages);
-
   while (true) {
     bool sensors_changed = false;
     bool has_jvmti_events = false;
@@ -134,8 +128,8 @@
               (symboltable_work = SymbolTable::has_work()) |
               (resolved_method_table_work = ResolvedMethodTable::has_work()) |
               (protection_domain_table_work = SystemDictionary::pd_cache_table()->has_work()) |
-              (oopstorage_work = OopStorage::has_cleanup_work_and_reset()))
-             == 0) {
+              (oopstorage_work = OopStorage::has_cleanup_work_and_reset())
+             ) == 0) {
         // Wait until notified that there is some work to do.
         ml.wait();
       }
@@ -178,7 +172,7 @@
     }
 
     if (oopstorage_work) {
-      cleanup_oopstorages(oopstorages, oopstorage_count);
+      cleanup_oopstorages();
     }
   }
 }
--- a/src/hotspot/share/runtime/sharedRuntime.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -2091,12 +2091,7 @@
     Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
   }
   Handle h_obj(THREAD, obj);
-  if (UseBiasedLocking) {
-    // Retry fast entry if bias is revoked to avoid unnecessary inflation
-    ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
-  } else {
-    ObjectSynchronizer::slow_enter(h_obj, lock, CHECK);
-  }
+  ObjectSynchronizer::enter(h_obj, lock, CHECK);
   assert(!HAS_PENDING_EXCEPTION, "Should have no exception here");
   JRT_BLOCK_END
 JRT_END
@@ -2127,7 +2122,7 @@
   {
     // Exit must be non-blocking, and therefore no exceptions can be thrown.
     EXCEPTION_MARK;
-    ObjectSynchronizer::slow_exit(obj, lock, THREAD);
+    ObjectSynchronizer::exit(obj, lock, THREAD);
   }
 
 #ifdef MIGHT_HAVE_PENDING
--- a/src/hotspot/share/runtime/stubRoutines.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/stubRoutines.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -113,6 +113,9 @@
 
 address StubRoutines::_zero_aligned_words = CAST_FROM_FN_PTR(address, Copy::zero_to_words);
 
+address StubRoutines::_data_cache_writeback              = NULL;
+address StubRoutines::_data_cache_writeback_sync         = NULL;
+
 address StubRoutines::_checkcast_arraycopy               = NULL;
 address StubRoutines::_checkcast_arraycopy_uninit        = NULL;
 address StubRoutines::_unsafe_arraycopy                  = NULL;
--- a/src/hotspot/share/runtime/stubRoutines.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/stubRoutines.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -191,6 +191,10 @@
   static address _arrayof_jlong_disjoint_arraycopy;
   static address _arrayof_oop_disjoint_arraycopy, _arrayof_oop_disjoint_arraycopy_uninit;
 
+  // cache line writeback
+  static address _data_cache_writeback;
+  static address _data_cache_writeback_sync;
+
   // these are recommended but optional:
   static address _checkcast_arraycopy, _checkcast_arraycopy_uninit;
   static address _unsafe_arraycopy;
@@ -357,6 +361,14 @@
   static address arrayof_oop_disjoint_arraycopy(bool dest_uninitialized = false) {
     return dest_uninitialized ? _arrayof_oop_disjoint_arraycopy_uninit : _arrayof_oop_disjoint_arraycopy;
   }
+  static address data_cache_writeback()              { return _data_cache_writeback; }
+  static address data_cache_writeback_sync()         { return _data_cache_writeback_sync; }
+
+  typedef void (*DataCacheWritebackStub)(void *);
+  static DataCacheWritebackStub DataCacheWriteback_stub()         { return CAST_TO_FN_PTR(DataCacheWritebackStub,  _data_cache_writeback); }
+  typedef void (*DataCacheWritebackSyncStub)(bool);
+  static DataCacheWritebackSyncStub DataCacheWritebackSync_stub() { return CAST_TO_FN_PTR(DataCacheWritebackSyncStub,  _data_cache_writeback_sync); }
+
   static address checkcast_arraycopy(bool dest_uninitialized = false) {
     return dest_uninitialized ? _checkcast_arraycopy_uninit : _checkcast_arraycopy;
   }
--- a/src/hotspot/share/runtime/sweeper.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/sweeper.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -699,22 +699,9 @@
       // Code cache state change is tracked in make_zombie()
       cm->make_zombie();
       SWEEP(cm);
-      // The nmethod may have been locked by JVMTI after being made zombie (see
-      // JvmtiDeferredEvent::compiled_method_unload_event()). If so, we cannot
-      // flush the osr nmethod directly but have to wait for a later sweeper cycle.
-      if (cm->is_osr_method() && !cm->is_locked_by_vm()) {
-        // No inline caches will ever point to osr methods, so we can just remove it.
-        // Make sure that we unregistered the nmethod with the heap and flushed all
-        // dependencies before removing the nmethod (done in make_zombie()).
-        assert(cm->is_zombie(), "nmethod must be unregistered");
-        cm->flush();
-        assert(result == None, "sanity");
-        result = Flushed;
-      } else {
-        assert(result == None, "sanity");
-        result = MadeZombie;
-        assert(cm->is_zombie(), "nmethod must be zombie");
-      }
+      assert(result == None, "sanity");
+      result = MadeZombie;
+      assert(cm->is_zombie(), "nmethod must be zombie");
     } else {
       // Still alive, clean up its inline caches
       cm->cleanup_inline_caches(false);
@@ -722,20 +709,12 @@
     }
   } else if (cm->is_unloaded()) {
     // Code is unloaded, so there are no activations on the stack.
-    // Convert the nmethod to zombie or flush it directly in the OSR case.
-    if (cm->is_osr_method()) {
-      SWEEP(cm);
-      // No inline caches will ever point to osr methods, so we can just remove it
-      cm->flush();
-      assert(result == None, "sanity");
-      result = Flushed;
-    } else {
-      // Code cache state change is tracked in make_zombie()
-      cm->make_zombie();
-      SWEEP(cm);
-      assert(result == None, "sanity");
-      result = MadeZombie;
-    }
+    // Convert the nmethod to zombie.
+    // Code cache state change is tracked in make_zombie()
+    cm->make_zombie();
+    SWEEP(cm);
+    assert(result == None, "sanity");
+    result = MadeZombie;
   } else {
     if (cm->is_nmethod()) {
       possibly_flush((nmethod*)cm);
--- a/src/hotspot/share/runtime/synchronizer.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/synchronizer.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -32,7 +32,7 @@
 #include "memory/padded.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/biasedLocking.hpp"
@@ -117,18 +117,18 @@
 static volatile intptr_t gInflationLocks[NINFLATIONLOCKS];
 
 // global list of blocks of monitors
-PaddedEnd<ObjectMonitor> * volatile ObjectSynchronizer::gBlockList = NULL;
-// global monitor free list
-ObjectMonitor * volatile ObjectSynchronizer::gFreeList  = NULL;
-// global monitor in-use list, for moribund threads,
-// monitors they inflated need to be scanned for deflation
-ObjectMonitor * volatile ObjectSynchronizer::gOmInUseList  = NULL;
-// count of entries in gOmInUseList
-int ObjectSynchronizer::gOmInUseCount = 0;
+PaddedObjectMonitor* volatile ObjectSynchronizer::g_block_list = NULL;
+// Global ObjectMonitor free list. Newly allocated and deflated
+// ObjectMonitors are prepended here.
+ObjectMonitor* volatile ObjectSynchronizer::g_free_list = NULL;
+// Global ObjectMonitor in-use list. When a JavaThread is exiting,
+// ObjectMonitors on its per-thread in-use list are prepended here.
+ObjectMonitor* volatile ObjectSynchronizer::g_om_in_use_list = NULL;
+int ObjectSynchronizer::g_om_in_use_count = 0;  // # on g_om_in_use_list
 
-static volatile intptr_t gListLock = 0;      // protects global monitor lists
-static volatile int gMonitorFreeCount  = 0;  // # on gFreeList
-static volatile int gMonitorPopulation = 0;  // # Extant -- in circulation
+static volatile intptr_t gListLock = 0;   // protects global monitor lists
+static volatile int g_om_free_count = 0;  // # on g_free_list
+static volatile int g_om_population = 0;  // # Extant -- in circulation
 
 #define CHAINMARKER (cast_to_oop<intptr_t>(-1))
 
@@ -155,7 +155,7 @@
 // the monitorexit operation.  In that case the JIT could fuse the operations
 // into a single notifyAndExit() runtime primitive.
 
-bool ObjectSynchronizer::quick_notify(oopDesc * obj, Thread * self, bool all) {
+bool ObjectSynchronizer::quick_notify(oopDesc* obj, Thread* self, bool all) {
   assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
   assert(self->is_Java_thread(), "invariant");
   assert(((JavaThread *) self)->thread_state() == _thread_in_Java, "invariant");
@@ -170,7 +170,7 @@
   }
 
   if (mark.has_monitor()) {
-    ObjectMonitor * const mon = mark.monitor();
+    ObjectMonitor* const mon = mark.monitor();
     assert(oopDesc::equals((oop) mon->object(), obj), "invariant");
     if (mon->owner() != self) return false;  // slow-path for IMS exception
 
@@ -183,12 +183,12 @@
       } else {
         DTRACE_MONITOR_PROBE(notify, mon, obj, self);
       }
-      int tally = 0;
+      int free_count = 0;
       do {
         mon->INotify(self);
-        ++tally;
+        ++free_count;
       } while (mon->first_waiter() != NULL && all);
-      OM_PERFDATA_OP(Notifications, inc(tally));
+      OM_PERFDATA_OP(Notifications, inc(free_count));
     }
     return true;
   }
@@ -204,26 +204,26 @@
 // Note that we can't safely call AsyncPrintJavaStack() from within
 // quick_enter() as our thread state remains _in_Java.
 
-bool ObjectSynchronizer::quick_enter(oop obj, Thread * Self,
+bool ObjectSynchronizer::quick_enter(oop obj, Thread* self,
                                      BasicLock * lock) {
   assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
-  assert(Self->is_Java_thread(), "invariant");
-  assert(((JavaThread *) Self)->thread_state() == _thread_in_Java, "invariant");
+  assert(self->is_Java_thread(), "invariant");
+  assert(((JavaThread *) self)->thread_state() == _thread_in_Java, "invariant");
   NoSafepointVerifier nsv;
   if (obj == NULL) return false;       // Need to throw NPE
   const markWord mark = obj->mark();
 
   if (mark.has_monitor()) {
-    ObjectMonitor * const m = mark.monitor();
+    ObjectMonitor* const m = mark.monitor();
     assert(oopDesc::equals((oop) m->object(), obj), "invariant");
-    Thread * const owner = (Thread *) m->_owner;
+    Thread* const owner = (Thread *) m->_owner;
 
     // Lock contention and Transactional Lock Elision (TLE) diagnostics
     // and observability
     // Case: light contention possibly amenable to TLE
     // Case: TLE inimical operations such as nested/recursive synchronization
 
-    if (owner == Self) {
+    if (owner == self) {
       m->_recursions++;
       return true;
     }
@@ -240,7 +240,7 @@
     // and last are the inflated Java Monitor (ObjectMonitor) checks.
     lock->set_displaced_header(markWord::unused_mark());
 
-    if (owner == NULL && Atomic::replace_if_null(Self, &(m->_owner))) {
+    if (owner == NULL && Atomic::replace_if_null(self, &(m->_owner))) {
       assert(m->_recursions == 0, "invariant");
       return true;
     }
@@ -257,85 +257,20 @@
 }
 
 // -----------------------------------------------------------------------------
-//  Fast Monitor Enter/Exit
-// This the fast monitor enter. The interpreter and compiler use
-// some assembly copies of this code. Make sure update those code
-// if the following function is changed. The implementation is
-// extremely sensitive to race condition. Be careful.
+// Monitor Enter/Exit
+// The interpreter and compiler assembly code tries to lock using the fast path
+// of this algorithm. Make sure to update that code if the following function is
+// changed. The implementation is extremely sensitive to race condition. Be careful.
 
-void ObjectSynchronizer::fast_enter(Handle obj, BasicLock* lock,
-                                    bool attempt_rebias, TRAPS) {
+void ObjectSynchronizer::enter(Handle obj, BasicLock* lock, TRAPS) {
   if (UseBiasedLocking) {
     if (!SafepointSynchronize::is_at_safepoint()) {
-      BiasedLocking::Condition cond = BiasedLocking::revoke_and_rebias(obj, attempt_rebias, THREAD);
-      if (cond == BiasedLocking::BIAS_REVOKED_AND_REBIASED) {
-        return;
-      }
+      BiasedLocking::revoke(obj, THREAD);
     } else {
-      assert(!attempt_rebias, "can not rebias toward VM thread");
       BiasedLocking::revoke_at_safepoint(obj);
     }
-    assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
-  }
-
-  slow_enter(obj, lock, THREAD);
-}
-
-void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) {
-  markWord mark = object->mark();
-  // We cannot check for Biased Locking if we are racing an inflation.
-  assert(mark == markWord::INFLATING() ||
-         !mark.has_bias_pattern(), "should not see bias pattern here");
-
-  markWord dhw = lock->displaced_header();
-  if (dhw.value() == 0) {
-    // If the displaced header is NULL, then this exit matches up with
-    // a recursive enter. No real work to do here except for diagnostics.
-#ifndef PRODUCT
-    if (mark != markWord::INFLATING()) {
-      // Only do diagnostics if we are not racing an inflation. Simply
-      // exiting a recursive enter of a Java Monitor that is being
-      // inflated is safe; see the has_monitor() comment below.
-      assert(!mark.is_neutral(), "invariant");
-      assert(!mark.has_locker() ||
-             THREAD->is_lock_owned((address)mark.locker()), "invariant");
-      if (mark.has_monitor()) {
-        // The BasicLock's displaced_header is marked as a recursive
-        // enter and we have an inflated Java Monitor (ObjectMonitor).
-        // This is a special case where the Java Monitor was inflated
-        // after this thread entered the stack-lock recursively. When a
-        // Java Monitor is inflated, we cannot safely walk the Java
-        // Monitor owner's stack and update the BasicLocks because a
-        // Java Monitor can be asynchronously inflated by a thread that
-        // does not own the Java Monitor.
-        ObjectMonitor * m = mark.monitor();
-        assert(((oop)(m->object()))->mark() == mark, "invariant");
-        assert(m->is_entered(THREAD), "invariant");
-      }
-    }
-#endif
-    return;
-  }
-
-  if (mark == markWord::from_pointer(lock)) {
-    // If the object is stack-locked by the current thread, try to
-    // swing the displaced header from the BasicLock back to the mark.
-    assert(dhw.is_neutral(), "invariant");
-    if (object->cas_set_mark(dhw, mark) == mark) {
-      return;
-    }
   }
 
-  // We have to take the slow-path of possible inflation and then exit.
-  inflate(THREAD, object, inflate_cause_vm_internal)->exit(true, THREAD);
-}
-
-// -----------------------------------------------------------------------------
-// Interpreter/Compiler Slow Case
-// This routine is used to handle interpreter/compiler slow case
-// We don't need to use fast path here, because it must have been
-// failed in the interpreter/compiler code.
-void ObjectSynchronizer::slow_enter(Handle obj, BasicLock* lock, TRAPS) {
   markWord mark = obj->mark();
   assert(!mark.has_bias_pattern(), "should not see bias pattern here");
 
@@ -363,12 +298,53 @@
   inflate(THREAD, obj(), inflate_cause_monitor_enter)->enter(THREAD);
 }
 
-// This routine is used to handle interpreter/compiler slow case
-// We don't need to use fast path here, because it must have
-// failed in the interpreter/compiler code. Simply use the heavy
-// weight monitor should be ok, unless someone find otherwise.
-void ObjectSynchronizer::slow_exit(oop object, BasicLock* lock, TRAPS) {
-  fast_exit(object, lock, THREAD);
+void ObjectSynchronizer::exit(oop object, BasicLock* lock, TRAPS) {
+  markWord mark = object->mark();
+  // We cannot check for Biased Locking if we are racing an inflation.
+  assert(mark == markWord::INFLATING() ||
+         !mark.has_bias_pattern(), "should not see bias pattern here");
+
+  markWord dhw = lock->displaced_header();
+  if (dhw.value() == 0) {
+    // If the displaced header is NULL, then this exit matches up with
+    // a recursive enter. No real work to do here except for diagnostics.
+#ifndef PRODUCT
+    if (mark != markWord::INFLATING()) {
+      // Only do diagnostics if we are not racing an inflation. Simply
+      // exiting a recursive enter of a Java Monitor that is being
+      // inflated is safe; see the has_monitor() comment below.
+      assert(!mark.is_neutral(), "invariant");
+      assert(!mark.has_locker() ||
+             THREAD->is_lock_owned((address)mark.locker()), "invariant");
+      if (mark.has_monitor()) {
+        // The BasicLock's displaced_header is marked as a recursive
+        // enter and we have an inflated Java Monitor (ObjectMonitor).
+        // This is a special case where the Java Monitor was inflated
+        // after this thread entered the stack-lock recursively. When a
+        // Java Monitor is inflated, we cannot safely walk the Java
+        // Monitor owner's stack and update the BasicLocks because a
+        // Java Monitor can be asynchronously inflated by a thread that
+        // does not own the Java Monitor.
+        ObjectMonitor* m = mark.monitor();
+        assert(((oop)(m->object()))->mark() == mark, "invariant");
+        assert(m->is_entered(THREAD), "invariant");
+      }
+    }
+#endif
+    return;
+  }
+
+  if (mark == markWord::from_pointer(lock)) {
+    // If the object is stack-locked by the current thread, try to
+    // swing the displaced header from the BasicLock back to the mark.
+    assert(dhw.is_neutral(), "invariant");
+    if (object->cas_set_mark(dhw, mark) == mark) {
+      return;
+    }
+  }
+
+  // We have to take the slow-path of possible inflation and then exit.
+  inflate(THREAD, object, inflate_cause_vm_internal)->exit(true, THREAD);
 }
 
 // -----------------------------------------------------------------------------
@@ -385,7 +361,7 @@
 // NOTE: must use heavy weight monitor to handle complete_exit/reenter()
 intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
@@ -397,7 +373,7 @@
 // NOTE: must use heavy weight monitor to handle complete_exit/reenter()
 void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
@@ -411,7 +387,7 @@
 void ObjectSynchronizer::jni_enter(Handle obj, TRAPS) {
   // the current locking is from JNI instead of Java code
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
   THREAD->set_current_pending_monitor_is_from_java(false);
@@ -423,7 +399,7 @@
 void ObjectSynchronizer::jni_exit(oop obj, Thread* THREAD) {
   if (UseBiasedLocking) {
     Handle h_obj(THREAD, obj);
-    BiasedLocking::revoke_and_rebias(h_obj, false, THREAD);
+    BiasedLocking::revoke(h_obj, THREAD);
     obj = h_obj();
   }
   assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
@@ -440,20 +416,20 @@
 // -----------------------------------------------------------------------------
 // Internal VM locks on java objects
 // standard constructor, allows locking failures
-ObjectLocker::ObjectLocker(Handle obj, Thread* thread, bool doLock) {
-  _dolock = doLock;
+ObjectLocker::ObjectLocker(Handle obj, Thread* thread, bool do_lock) {
+  _dolock = do_lock;
   _thread = thread;
   _thread->check_for_valid_safepoint_state(false);
   _obj = obj;
 
   if (_dolock) {
-    ObjectSynchronizer::fast_enter(_obj, &_lock, false, _thread);
+    ObjectSynchronizer::enter(_obj, &_lock, _thread);
   }
 }
 
 ObjectLocker::~ObjectLocker() {
   if (_dolock) {
-    ObjectSynchronizer::fast_exit(_obj(), &_lock, _thread);
+    ObjectSynchronizer::exit(_obj(), &_lock, _thread);
   }
 }
 
@@ -463,7 +439,7 @@
 // NOTE: must use heavy weight monitor to handle wait()
 int ObjectSynchronizer::wait(Handle obj, jlong millis, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
   if (millis < 0) {
@@ -481,9 +457,9 @@
   return dtrace_waited_probe(monitor, obj, THREAD);
 }
 
-void ObjectSynchronizer::waitUninterruptibly(Handle obj, jlong millis, TRAPS) {
+void ObjectSynchronizer::wait_uninterruptibly(Handle obj, jlong millis, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
   if (millis < 0) {
@@ -494,7 +470,7 @@
 
 void ObjectSynchronizer::notify(Handle obj, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
@@ -508,7 +484,7 @@
 // NOTE: see comment of notify()
 void ObjectSynchronizer::notifyall(Handle obj, TRAPS) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(obj, false, THREAD);
+    BiasedLocking::revoke(obj, THREAD);
     assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
@@ -544,11 +520,11 @@
   char         _pad_prefix[DEFAULT_CACHE_LINE_SIZE];
   // These are highly shared mostly-read variables.
   // To avoid false-sharing they need to be the sole occupants of a cache line.
-  volatile int stwRandom;
-  volatile int stwCycle;
+  volatile int stw_random;
+  volatile int stw_cycle;
   DEFINE_PAD_MINUS_SIZE(1, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile int) * 2);
   // Hot RW variable -- Sequester to avoid false-sharing
-  volatile int hcSequence;
+  volatile int hc_sequence;
   DEFINE_PAD_MINUS_SIZE(2, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile int));
 };
 
@@ -556,7 +532,7 @@
 static int MonitorScavengeThreshold = 1000000;
 static volatile int ForceMonitorScavenge = 0; // Scavenge required and pending
 
-static markWord ReadStableMark(oop obj) {
+static markWord read_stable_mark(oop obj) {
   markWord mark = obj->mark();
   if (!mark.is_being_inflated()) {
     return mark;       // normal fast-path return
@@ -570,7 +546,7 @@
     }
 
     // The object is being inflated by some other thread.
-    // The caller of ReadStableMark() must wait for inflation to complete.
+    // The caller of read_stable_mark() must wait for inflation to complete.
     // Avoid live-lock
     // TODO: consider calling SafepointSynchronize::do_call_back() while
     // spinning to see if there's a safepoint pending.  If so, immediately
@@ -606,7 +582,7 @@
         Thread::muxAcquire(gInflationLocks + ix, "gInflationLock");
         while (obj->mark() == markWord::INFLATING()) {
           // Beware: NakedYield() is advisory and has almost no effect on some platforms
-          // so we periodically call Self->_ParkEvent->park(1).
+          // so we periodically call self->_ParkEvent->park(1).
           // We use a mixed spin/yield/block mechanism.
           if ((YieldThenBlock++) >= 16) {
             Thread::current()->_ParkEvent->park(1);
@@ -625,21 +601,21 @@
 // hashCode() generation :
 //
 // Possibilities:
-// * MD5Digest of {obj,stwRandom}
-// * CRC32 of {obj,stwRandom} or any linear-feedback shift register function.
+// * MD5Digest of {obj,stw_random}
+// * CRC32 of {obj,stw_random} or any linear-feedback shift register function.
 // * A DES- or AES-style SBox[] mechanism
 // * One of the Phi-based schemes, such as:
 //   2654435761 = 2^32 * Phi (golden ratio)
-//   HashCodeValue = ((uintptr_t(obj) >> 3) * 2654435761) ^ GVars.stwRandom ;
+//   HashCodeValue = ((uintptr_t(obj) >> 3) * 2654435761) ^ GVars.stw_random ;
 // * A variation of Marsaglia's shift-xor RNG scheme.
-// * (obj ^ stwRandom) is appealing, but can result
+// * (obj ^ stw_random) is appealing, but can result
 //   in undesirable regularity in the hashCode values of adjacent objects
 //   (objects allocated back-to-back, in particular).  This could potentially
 //   result in hashtable collisions and reduced hashtable efficiency.
 //   There are simple ways to "diffuse" the middle address bits over the
 //   generated hashCode values:
 
-static inline intptr_t get_next_hash(Thread * Self, oop obj) {
+static inline intptr_t get_next_hash(Thread* self, oop obj) {
   intptr_t value = 0;
   if (hashCode == 0) {
     // This form uses global Park-Miller RNG.
@@ -650,26 +626,26 @@
     // This variation has the property of being stable (idempotent)
     // between STW operations.  This can be useful in some of the 1-0
     // synchronization schemes.
-    intptr_t addrBits = cast_from_oop<intptr_t>(obj) >> 3;
-    value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom;
+    intptr_t addr_bits = cast_from_oop<intptr_t>(obj) >> 3;
+    value = addr_bits ^ (addr_bits >> 5) ^ GVars.stw_random;
   } else if (hashCode == 2) {
     value = 1;            // for sensitivity testing
   } else if (hashCode == 3) {
-    value = ++GVars.hcSequence;
+    value = ++GVars.hc_sequence;
   } else if (hashCode == 4) {
     value = cast_from_oop<intptr_t>(obj);
   } else {
     // Marsaglia's xor-shift scheme with thread-specific state
     // This is probably the best overall implementation -- we'll
     // likely make this the default in future releases.
-    unsigned t = Self->_hashStateX;
+    unsigned t = self->_hashStateX;
     t ^= (t << 11);
-    Self->_hashStateX = Self->_hashStateY;
-    Self->_hashStateY = Self->_hashStateZ;
-    Self->_hashStateZ = Self->_hashStateW;
-    unsigned v = Self->_hashStateW;
+    self->_hashStateX = self->_hashStateY;
+    self->_hashStateY = self->_hashStateZ;
+    self->_hashStateZ = self->_hashStateW;
+    unsigned v = self->_hashStateW;
     v = (v ^ (v >> 19)) ^ (t ^ (t >> 8));
-    Self->_hashStateW = v;
+    self->_hashStateW = v;
     value = v;
   }
 
@@ -679,7 +655,7 @@
   return value;
 }
 
-intptr_t ObjectSynchronizer::FastHashCode(Thread * Self, oop obj) {
+intptr_t ObjectSynchronizer::FastHashCode(Thread* self, oop obj) {
   if (UseBiasedLocking) {
     // NOTE: many places throughout the JVM do not expect a safepoint
     // to be taken here, in particular most operations on perm gen
@@ -690,12 +666,12 @@
     // thread-local storage.
     if (obj->mark().has_bias_pattern()) {
       // Handle for oop obj in case of STW safepoint
-      Handle hobj(Self, obj);
+      Handle hobj(self, obj);
       // Relaxing assertion for bug 6320749.
       assert(Universe::verify_in_progress() ||
              !SafepointSynchronize::is_at_safepoint(),
              "biases should not be seen by VM thread here");
-      BiasedLocking::revoke_and_rebias(hobj, false, JavaThread::current());
+      BiasedLocking::revoke(hobj, JavaThread::current());
       obj = hobj();
       assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now");
     }
@@ -706,14 +682,14 @@
   assert(Universe::verify_in_progress() || DumpSharedSpaces ||
          !SafepointSynchronize::is_at_safepoint(), "invariant");
   assert(Universe::verify_in_progress() || DumpSharedSpaces ||
-         Self->is_Java_thread() , "invariant");
+         self->is_Java_thread() , "invariant");
   assert(Universe::verify_in_progress() || DumpSharedSpaces ||
-         ((JavaThread *)Self)->thread_state() != _thread_blocked, "invariant");
+         ((JavaThread *)self)->thread_state() != _thread_blocked, "invariant");
 
   ObjectMonitor* monitor = NULL;
   markWord temp, test;
   intptr_t hash;
-  markWord mark = ReadStableMark(obj);
+  markWord mark = read_stable_mark(obj);
 
   // object should remain ineligible for biased locking
   assert(!mark.has_bias_pattern(), "invariant");
@@ -723,7 +699,7 @@
     if (hash != 0) {                  // if it has hash, just return it
       return hash;
     }
-    hash = get_next_hash(Self, obj);  // allocate a new hash code
+    hash = get_next_hash(self, obj);  // allocate a new hash code
     temp = mark.copy_set_hash(hash);  // merge the hash code into header
     // use (machine word version) atomic operation to install the hash
     test = obj->cas_set_mark(temp, mark);
@@ -742,7 +718,7 @@
       return hash;
     }
     // Skip to the following code to reduce code size
-  } else if (Self->is_lock_owned((address)mark.locker())) {
+  } else if (self->is_lock_owned((address)mark.locker())) {
     temp = mark.displaced_mark_helper(); // this is a lightweight monitor owned
     assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value());
     hash = temp.hash();                  // by current thread, check if the displaced
@@ -760,21 +736,22 @@
   }
 
   // Inflate the monitor to set hash code
-  monitor = inflate(Self, obj, inflate_cause_hash_code);
+  monitor = inflate(self, obj, inflate_cause_hash_code);
   // Load displaced header and check it has hash code
   mark = monitor->header();
   assert(mark.is_neutral(), "invariant: header=" INTPTR_FORMAT, mark.value());
   hash = mark.hash();
   if (hash == 0) {
-    hash = get_next_hash(Self, obj);
+    hash = get_next_hash(self, obj);
     temp = mark.copy_set_hash(hash); // merge hash code into header
     assert(temp.is_neutral(), "invariant: header=" INTPTR_FORMAT, temp.value());
     uintptr_t v = Atomic::cmpxchg(temp.value(), (volatile uintptr_t*)monitor->header_addr(), mark.value());
     test = markWord(v);
     if (test != mark) {
-      // The only update to the ObjectMonitor's header/dmw field
-      // is to merge in the hash code. If someone adds a new usage
-      // of the header/dmw field, please update this code.
+      // The only non-deflation update to the ObjectMonitor's
+      // header/dmw field is to merge in the hash code. If someone
+      // adds a new usage of the header/dmw field, please update
+      // this code.
       hash = test.hash();
       assert(test.is_neutral(), "invariant: header=" INTPTR_FORMAT, test.value());
       assert(hash != 0, "Trivial unexpected object/monitor header usage.");
@@ -794,14 +771,14 @@
 bool ObjectSynchronizer::current_thread_holds_lock(JavaThread* thread,
                                                    Handle h_obj) {
   if (UseBiasedLocking) {
-    BiasedLocking::revoke_and_rebias(h_obj, false, thread);
+    BiasedLocking::revoke(h_obj, thread);
     assert(!h_obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
 
   assert(thread == JavaThread::current(), "Can only be called on current thread");
   oop obj = h_obj();
 
-  markWord mark = ReadStableMark(obj);
+  markWord mark = read_stable_mark(obj);
 
   // Uncontended case, header points to stack
   if (mark.has_locker()) {
@@ -833,14 +810,14 @@
 
   if (UseBiasedLocking && h_obj()->mark().has_bias_pattern()) {
     // CASE: biased
-    BiasedLocking::revoke_and_rebias(h_obj, false, self);
+    BiasedLocking::revoke(h_obj, self);
     assert(!h_obj->mark().has_bias_pattern(),
            "biases should be revoked by now");
   }
 
   assert(self == JavaThread::current(), "Can only be called on current thread");
   oop obj = h_obj();
-  markWord mark = ReadStableMark(obj);
+  markWord mark = read_stable_mark(obj);
 
   // CASE: stack-locked.  Mark points to a BasicLock on the owner's stack.
   if (mark.has_locker()) {
@@ -852,7 +829,7 @@
   // The Object:ObjectMonitor relationship is stable as long as we're
   // not at a safepoint.
   if (mark.has_monitor()) {
-    void * owner = mark.monitor()->_owner;
+    void* owner = mark.monitor()->_owner;
     if (owner == NULL) return owner_none;
     return (owner == self ||
             self->is_lock_owned((address)owner)) ? owner_self : owner_other;
@@ -869,7 +846,7 @@
     if (SafepointSynchronize::is_at_safepoint()) {
       BiasedLocking::revoke_at_safepoint(h_obj);
     } else {
-      BiasedLocking::revoke_and_rebias(h_obj, false, JavaThread::current());
+      BiasedLocking::revoke(h_obj, JavaThread::current());
     }
     assert(!h_obj->mark().has_bias_pattern(), "biases should be revoked by now");
   }
@@ -877,7 +854,7 @@
   oop obj = h_obj();
   address owner = NULL;
 
-  markWord mark = ReadStableMark(obj);
+  markWord mark = read_stable_mark(obj);
 
   // Uncontended case, header points to stack
   if (mark.has_locker()) {
@@ -907,34 +884,27 @@
 // Visitors ...
 
 void ObjectSynchronizer::monitors_iterate(MonitorClosure* closure) {
-  PaddedEnd<ObjectMonitor> * block = OrderAccess::load_acquire(&gBlockList);
+  PaddedObjectMonitor* block = OrderAccess::load_acquire(&g_block_list);
   while (block != NULL) {
     assert(block->object() == CHAINMARKER, "must be a block header");
     for (int i = _BLOCKSIZE - 1; i > 0; i--) {
       ObjectMonitor* mid = (ObjectMonitor *)(block + i);
       oop object = (oop)mid->object();
       if (object != NULL) {
+        // Only process with closure if the object is set.
         closure->do_monitor(mid);
       }
     }
-    block = (PaddedEnd<ObjectMonitor> *)block->FreeNext;
+    block = (PaddedObjectMonitor*)block->_next_om;
   }
 }
 
-// Get the next block in the block list.
-static inline PaddedEnd<ObjectMonitor>* next(PaddedEnd<ObjectMonitor>* block) {
-  assert(block->object() == CHAINMARKER, "must be a block header");
-  block = (PaddedEnd<ObjectMonitor>*) block->FreeNext;
-  assert(block == NULL || block->object() == CHAINMARKER, "must be a block header");
-  return block;
-}
-
 static bool monitors_used_above_threshold() {
-  if (gMonitorPopulation == 0) {
+  if (g_om_population == 0) {
     return false;
   }
-  int monitors_used = gMonitorPopulation - gMonitorFreeCount;
-  int monitor_usage = (monitors_used * 100LL) / gMonitorPopulation;
+  int monitors_used = g_om_population - g_om_free_count;
+  int monitor_usage = (monitors_used * 100LL) / g_om_population;
   return monitor_usage > MonitorUsedDeflationThreshold;
 }
 
@@ -953,18 +923,18 @@
 
 void ObjectSynchronizer::global_used_oops_do(OopClosure* f) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
-  list_oops_do(gOmInUseList, f);
+  list_oops_do(g_om_in_use_list, f);
 }
 
 void ObjectSynchronizer::thread_local_used_oops_do(Thread* thread, OopClosure* f) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
-  list_oops_do(thread->omInUseList, f);
+  list_oops_do(thread->om_in_use_list, f);
 }
 
 void ObjectSynchronizer::list_oops_do(ObjectMonitor* list, OopClosure* f) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   ObjectMonitor* mid;
-  for (mid = list; mid != NULL; mid = mid->FreeNext) {
+  for (mid = list; mid != NULL; mid = mid->_next_om) {
     if (mid->object() != NULL) {
       f->do_oop((oop*)mid->object_addr());
     }
@@ -975,10 +945,10 @@
 // -----------------------------------------------------------------------------
 // ObjectMonitor Lifecycle
 // -----------------------
-// Inflation unlinks monitors from the global gFreeList and
+// Inflation unlinks monitors from the global g_free_list and
 // associates them with objects.  Deflation -- which occurs at
 // STW-time -- disassociates idle monitors from objects.  Such
-// scavenged monitors are returned to the gFreeList.
+// scavenged monitors are returned to the g_free_list.
 //
 // The global list is protected by gListLock.  All the critical sections
 // are short and operate in constant-time.
@@ -987,13 +957,15 @@
 //
 // Lifecycle:
 // --   unassigned and on the global free list
-// --   unassigned and on a thread's private omFreeList
+// --   unassigned and on a thread's private om_free_list
 // --   assigned to an object.  The object is inflated and the mark refers
 //      to the objectmonitor.
 
 
 // Constraining monitor pool growth via MonitorBound ...
 //
+// If MonitorBound is not set (<= 0), MonitorBound checks are disabled.
+//
 // The monitor pool is grow-only.  We scavenge at STW safepoint-time, but the
 // the rate of scavenging is driven primarily by GC.  As such,  we can find
 // an inordinate number of monitors in circulation.
@@ -1007,8 +979,14 @@
 // See also: GuaranteedSafepointInterval
 //
 // The current implementation uses asynchronous VM operations.
+//
+// If MonitorBound is set, the boundry applies to
+//     (g_om_population - g_om_free_count)
+// i.e., if there are not enough ObjectMonitors on the global free list,
+// then a safepoint deflation is induced. Picking a good MonitorBound value
+// is non-trivial.
 
-static void InduceScavenge(Thread * Self, const char * Whence) {
+static void InduceScavenge(Thread* self, const char * Whence) {
   // Induce STW safepoint to trim monitors
   // Ultimately, this results in a call to deflate_idle_monitors() in the near future.
   // More precisely, trigger an asynchronous STW safepoint as the number
@@ -1024,86 +1002,86 @@
   }
 }
 
-ObjectMonitor* ObjectSynchronizer::omAlloc(Thread * Self) {
+ObjectMonitor* ObjectSynchronizer::om_alloc(Thread* self) {
   // A large MAXPRIVATE value reduces both list lock contention
   // and list coherency traffic, but also tends to increase the
-  // number of objectMonitors in circulation as well as the STW
+  // number of ObjectMonitors in circulation as well as the STW
   // scavenge costs.  As usual, we lean toward time in space-time
   // tradeoffs.
   const int MAXPRIVATE = 1024;
   stringStream ss;
   for (;;) {
-    ObjectMonitor * m;
+    ObjectMonitor* m;
 
-    // 1: try to allocate from the thread's local omFreeList.
+    // 1: try to allocate from the thread's local om_free_list.
     // Threads will attempt to allocate first from their local list, then
     // from the global list, and only after those attempts fail will the thread
     // attempt to instantiate new monitors.   Thread-local free lists take
     // heat off the gListLock and improve allocation latency, as well as reducing
     // coherency traffic on the shared global list.
-    m = Self->omFreeList;
+    m = self->om_free_list;
     if (m != NULL) {
-      Self->omFreeList = m->FreeNext;
-      Self->omFreeCount--;
+      self->om_free_list = m->_next_om;
+      self->om_free_count--;
       guarantee(m->object() == NULL, "invariant");
-      m->FreeNext = Self->omInUseList;
-      Self->omInUseList = m;
-      Self->omInUseCount++;
+      m->_next_om = self->om_in_use_list;
+      self->om_in_use_list = m;
+      self->om_in_use_count++;
       return m;
     }
 
-    // 2: try to allocate from the global gFreeList
+    // 2: try to allocate from the global g_free_list
     // CONSIDER: use muxTry() instead of muxAcquire().
     // If the muxTry() fails then drop immediately into case 3.
     // If we're using thread-local free lists then try
     // to reprovision the caller's free list.
-    if (gFreeList != NULL) {
-      // Reprovision the thread's omFreeList.
+    if (g_free_list != NULL) {
+      // Reprovision the thread's om_free_list.
       // Use bulk transfers to reduce the allocation rate and heat
       // on various locks.
-      Thread::muxAcquire(&gListLock, "omAlloc(1)");
-      for (int i = Self->omFreeProvision; --i >= 0 && gFreeList != NULL;) {
-        gMonitorFreeCount--;
-        ObjectMonitor * take = gFreeList;
-        gFreeList = take->FreeNext;
+      Thread::muxAcquire(&gListLock, "om_alloc(1)");
+      for (int i = self->om_free_provision; --i >= 0 && g_free_list != NULL;) {
+        g_om_free_count--;
+        ObjectMonitor* take = g_free_list;
+        g_free_list = take->_next_om;
         guarantee(take->object() == NULL, "invariant");
         take->Recycle();
-        omRelease(Self, take, false);
+        om_release(self, take, false);
       }
       Thread::muxRelease(&gListLock);
-      Self->omFreeProvision += 1 + (Self->omFreeProvision/2);
-      if (Self->omFreeProvision > MAXPRIVATE) Self->omFreeProvision = MAXPRIVATE;
+      self->om_free_provision += 1 + (self->om_free_provision/2);
+      if (self->om_free_provision > MAXPRIVATE) self->om_free_provision = MAXPRIVATE;
 
       const int mx = MonitorBound;
-      if (mx > 0 && (gMonitorPopulation-gMonitorFreeCount) > mx) {
-        // We can't safely induce a STW safepoint from omAlloc() as our thread
+      if (mx > 0 && (g_om_population-g_om_free_count) > mx) {
+        // Not enough ObjectMonitors on the global free list.
+        // We can't safely induce a STW safepoint from om_alloc() as our thread
         // state may not be appropriate for such activities and callers may hold
         // naked oops, so instead we defer the action.
-        InduceScavenge(Self, "omAlloc");
+        InduceScavenge(self, "om_alloc");
       }
       continue;
     }
 
     // 3: allocate a block of new ObjectMonitors
     // Both the local and global free lists are empty -- resort to malloc().
-    // In the current implementation objectMonitors are TSM - immortal.
+    // In the current implementation ObjectMonitors are TSM - immortal.
     // Ideally, we'd write "new ObjectMonitor[_BLOCKSIZE], but we want
     // each ObjectMonitor to start at the beginning of a cache line,
     // so we use align_up().
     // A better solution would be to use C++ placement-new.
     // BEWARE: As it stands currently, we don't run the ctors!
     assert(_BLOCKSIZE > 1, "invariant");
-    size_t neededsize = sizeof(PaddedEnd<ObjectMonitor>) * _BLOCKSIZE;
-    PaddedEnd<ObjectMonitor> * temp;
+    size_t neededsize = sizeof(PaddedObjectMonitor) * _BLOCKSIZE;
+    PaddedObjectMonitor* temp;
     size_t aligned_size = neededsize + (DEFAULT_CACHE_LINE_SIZE - 1);
-    void* real_malloc_addr = (void *)NEW_C_HEAP_ARRAY(char, aligned_size,
-                                                      mtInternal);
-    temp = (PaddedEnd<ObjectMonitor> *)
-             align_up(real_malloc_addr, DEFAULT_CACHE_LINE_SIZE);
+    void* real_malloc_addr = (void*)NEW_C_HEAP_ARRAY(char, aligned_size,
+                                                     mtInternal);
+    temp = (PaddedObjectMonitor*)align_up(real_malloc_addr, DEFAULT_CACHE_LINE_SIZE);
 
     // NOTE: (almost) no way to recover if allocation failed.
     // We might be able to induce a STW safepoint and scavenge enough
-    // objectMonitors to permit progress.
+    // ObjectMonitors to permit progress.
     if (temp == NULL) {
       vm_exit_out_of_memory(neededsize, OOM_MALLOC_ERROR,
                             "Allocate ObjectMonitors");
@@ -1114,16 +1092,16 @@
     // initialize the linked list, each monitor points to its next
     // forming the single linked free list, the very first monitor
     // will points to next block, which forms the block list.
-    // The trick of using the 1st element in the block as gBlockList
+    // The trick of using the 1st element in the block as g_block_list
     // linkage should be reconsidered.  A better implementation would
     // look like: class Block { Block * next; int N; ObjectMonitor Body [N] ; }
 
     for (int i = 1; i < _BLOCKSIZE; i++) {
-      temp[i].FreeNext = (ObjectMonitor *)&temp[i+1];
+      temp[i]._next_om = (ObjectMonitor *)&temp[i+1];
     }
 
     // terminate the last monitor as the end of list
-    temp[_BLOCKSIZE - 1].FreeNext = NULL;
+    temp[_BLOCKSIZE - 1]._next_om = NULL;
 
     // Element [0] is reserved for global list linkage
     temp[0].set_object(CHAINMARKER);
@@ -1132,160 +1110,155 @@
     // block in hand.  This avoids some lock traffic and redundant
     // list activity.
 
-    // Acquire the gListLock to manipulate gBlockList and gFreeList.
+    // Acquire the gListLock to manipulate g_block_list and g_free_list.
     // An Oyama-Taura-Yonezawa scheme might be more efficient.
-    Thread::muxAcquire(&gListLock, "omAlloc(2)");
-    gMonitorPopulation += _BLOCKSIZE-1;
-    gMonitorFreeCount += _BLOCKSIZE-1;
+    Thread::muxAcquire(&gListLock, "om_alloc(2)");
+    g_om_population += _BLOCKSIZE-1;
+    g_om_free_count += _BLOCKSIZE-1;
 
-    // Add the new block to the list of extant blocks (gBlockList).
-    // The very first objectMonitor in a block is reserved and dedicated.
+    // Add the new block to the list of extant blocks (g_block_list).
+    // The very first ObjectMonitor in a block is reserved and dedicated.
     // It serves as blocklist "next" linkage.
-    temp[0].FreeNext = gBlockList;
-    // There are lock-free uses of gBlockList so make sure that
-    // the previous stores happen before we update gBlockList.
-    OrderAccess::release_store(&gBlockList, temp);
+    temp[0]._next_om = g_block_list;
+    // There are lock-free uses of g_block_list so make sure that
+    // the previous stores happen before we update g_block_list.
+    OrderAccess::release_store(&g_block_list, temp);
 
-    // Add the new string of objectMonitors to the global free list
-    temp[_BLOCKSIZE - 1].FreeNext = gFreeList;
-    gFreeList = temp + 1;
+    // Add the new string of ObjectMonitors to the global free list
+    temp[_BLOCKSIZE - 1]._next_om = g_free_list;
+    g_free_list = temp + 1;
     Thread::muxRelease(&gListLock);
   }
 }
 
-// Place "m" on the caller's private per-thread omFreeList.
+// Place "m" on the caller's private per-thread om_free_list.
 // In practice there's no need to clamp or limit the number of
-// monitors on a thread's omFreeList as the only time we'll call
-// omRelease is to return a monitor to the free list after a CAS
-// attempt failed.  This doesn't allow unbounded #s of monitors to
+// monitors on a thread's om_free_list as the only non-allocation time
+// we'll call om_release() is to return a monitor to the free list after
+// a CAS attempt failed. This doesn't allow unbounded #s of monitors to
 // accumulate on a thread's free list.
 //
 // Key constraint: all ObjectMonitors on a thread's free list and the global
 // free list must have their object field set to null. This prevents the
-// scavenger -- deflate_monitor_list() -- from reclaiming them.
+// scavenger -- deflate_monitor_list() -- from reclaiming them while we
+// are trying to release them.
 
-void ObjectSynchronizer::omRelease(Thread * Self, ObjectMonitor * m,
-                                   bool fromPerThreadAlloc) {
+void ObjectSynchronizer::om_release(Thread* self, ObjectMonitor* m,
+                                    bool from_per_thread_alloc) {
   guarantee(m->header().value() == 0, "invariant");
   guarantee(m->object() == NULL, "invariant");
   stringStream ss;
   guarantee((m->is_busy() | m->_recursions) == 0, "freeing in-use monitor: "
             "%s, recursions=" INTPTR_FORMAT, m->is_busy_to_string(&ss),
             m->_recursions);
-  // Remove from omInUseList
-  if (fromPerThreadAlloc) {
+  // _next_om is used for both per-thread in-use and free lists so
+  // we have to remove 'm' from the in-use list first (as needed).
+  if (from_per_thread_alloc) {
+    // Need to remove 'm' from om_in_use_list.
     ObjectMonitor* cur_mid_in_use = NULL;
     bool extracted = false;
-    for (ObjectMonitor* mid = Self->omInUseList; mid != NULL; cur_mid_in_use = mid, mid = mid->FreeNext) {
+    for (ObjectMonitor* mid = self->om_in_use_list; mid != NULL; cur_mid_in_use = mid, mid = mid->_next_om) {
       if (m == mid) {
         // extract from per-thread in-use list
-        if (mid == Self->omInUseList) {
-          Self->omInUseList = mid->FreeNext;
+        if (mid == self->om_in_use_list) {
+          self->om_in_use_list = mid->_next_om;
         } else if (cur_mid_in_use != NULL) {
-          cur_mid_in_use->FreeNext = mid->FreeNext; // maintain the current thread in-use list
+          cur_mid_in_use->_next_om = mid->_next_om; // maintain the current thread in-use list
         }
         extracted = true;
-        Self->omInUseCount--;
+        self->om_in_use_count--;
         break;
       }
     }
     assert(extracted, "Should have extracted from in-use list");
   }
 
-  // FreeNext is used for both omInUseList and omFreeList, so clear old before setting new
-  m->FreeNext = Self->omFreeList;
-  Self->omFreeList = m;
-  Self->omFreeCount++;
+  m->_next_om = self->om_free_list;
+  self->om_free_list = m;
+  self->om_free_count++;
 }
 
-// Return the monitors of a moribund thread's local free list to
-// the global free list.  Typically a thread calls omFlush() when
-// it's dying.  We could also consider having the VM thread steal
-// monitors from threads that have not run java code over a few
-// consecutive STW safepoints.  Relatedly, we might decay
-// omFreeProvision at STW safepoints.
-//
-// Also return the monitors of a moribund thread's omInUseList to
-// a global gOmInUseList under the global list lock so these
-// will continue to be scanned.
+// Return ObjectMonitors on a moribund thread's free and in-use
+// lists to the appropriate global lists. The ObjectMonitors on the
+// per-thread in-use list may still be in use by other threads.
 //
-// We currently call omFlush() from Threads::remove() _before the thread
-// has been excised from the thread list and is no longer a mutator.
-// This means that omFlush() cannot run concurrently with a safepoint and
-// interleave with the deflate_idle_monitors scavenge operator. In particular,
-// this ensures that the thread's monitors are scanned by a GC safepoint,
-// either via Thread::oops_do() (if safepoint happens before omFlush()) or via
-// ObjectSynchronizer::oops_do() (if it happens after omFlush() and the thread's
-// monitors have been transferred to the global in-use list).
+// We currently call om_flush() from Threads::remove() before the
+// thread has been excised from the thread list and is no longer a
+// mutator. This means that om_flush() cannot run concurrently with
+// a safepoint and interleave with deflate_idle_monitors(). In
+// particular, this ensures that the thread's in-use monitors are
+// scanned by a GC safepoint, either via Thread::oops_do() (before
+// om_flush() is called) or via ObjectSynchronizer::oops_do() (after
+// om_flush() is called).
 
-void ObjectSynchronizer::omFlush(Thread * Self) {
-  ObjectMonitor * list = Self->omFreeList;  // Null-terminated SLL
-  ObjectMonitor * tail = NULL;
-  int tally = 0;
-  if (list != NULL) {
-    ObjectMonitor * s;
-    // The thread is going away. Set 'tail' to the last per-thread free
-    // monitor which will be linked to gFreeList below under the gListLock.
+void ObjectSynchronizer::om_flush(Thread* self) {
+  ObjectMonitor* free_list = self->om_free_list;
+  ObjectMonitor* free_tail = NULL;
+  int free_count = 0;
+  if (free_list != NULL) {
+    ObjectMonitor* s;
+    // The thread is going away. Set 'free_tail' to the last per-thread free
+    // monitor which will be linked to g_free_list below under the gListLock.
     stringStream ss;
-    for (s = list; s != NULL; s = s->FreeNext) {
-      tally++;
-      tail = s;
+    for (s = free_list; s != NULL; s = s->_next_om) {
+      free_count++;
+      free_tail = s;
       guarantee(s->object() == NULL, "invariant");
       guarantee(!s->is_busy(), "must be !is_busy: %s", s->is_busy_to_string(&ss));
     }
-    guarantee(tail != NULL, "invariant");
-    assert(Self->omFreeCount == tally, "free-count off");
-    Self->omFreeList = NULL;
-    Self->omFreeCount = 0;
+    guarantee(free_tail != NULL, "invariant");
+    assert(self->om_free_count == free_count, "free-count off");
+    self->om_free_list = NULL;
+    self->om_free_count = 0;
   }
 
-  ObjectMonitor * inUseList = Self->omInUseList;
-  ObjectMonitor * inUseTail = NULL;
-  int inUseTally = 0;
-  if (inUseList != NULL) {
+  ObjectMonitor* in_use_list = self->om_in_use_list;
+  ObjectMonitor* in_use_tail = NULL;
+  int in_use_count = 0;
+  if (in_use_list != NULL) {
+    // The thread is going away, however the ObjectMonitors on the
+    // om_in_use_list may still be in-use by other threads. Link
+    // them to in_use_tail, which will be linked into the global
+    // in-use list g_om_in_use_list below, under the gListLock.
     ObjectMonitor *cur_om;
-    // The thread is going away, however the omInUseList inflated
-    // monitors may still be in-use by other threads.
-    // Link them to inUseTail, which will be linked into the global in-use list
-    // gOmInUseList below, under the gListLock
-    for (cur_om = inUseList; cur_om != NULL; cur_om = cur_om->FreeNext) {
-      inUseTail = cur_om;
-      inUseTally++;
+    for (cur_om = in_use_list; cur_om != NULL; cur_om = cur_om->_next_om) {
+      in_use_tail = cur_om;
+      in_use_count++;
     }
-    guarantee(inUseTail != NULL, "invariant");
-    assert(Self->omInUseCount == inUseTally, "in-use count off");
-    Self->omInUseList = NULL;
-    Self->omInUseCount = 0;
+    guarantee(in_use_tail != NULL, "invariant");
+    assert(self->om_in_use_count == in_use_count, "in-use count off");
+    self->om_in_use_list = NULL;
+    self->om_in_use_count = 0;
   }
 
-  Thread::muxAcquire(&gListLock, "omFlush");
-  if (tail != NULL) {
-    tail->FreeNext = gFreeList;
-    gFreeList = list;
-    gMonitorFreeCount += tally;
+  Thread::muxAcquire(&gListLock, "om_flush");
+  if (free_tail != NULL) {
+    free_tail->_next_om = g_free_list;
+    g_free_list = free_list;
+    g_om_free_count += free_count;
   }
 
-  if (inUseTail != NULL) {
-    inUseTail->FreeNext = gOmInUseList;
-    gOmInUseList = inUseList;
-    gOmInUseCount += inUseTally;
+  if (in_use_tail != NULL) {
+    in_use_tail->_next_om = g_om_in_use_list;
+    g_om_in_use_list = in_use_list;
+    g_om_in_use_count += in_use_count;
   }
 
   Thread::muxRelease(&gListLock);
 
   LogStreamHandle(Debug, monitorinflation) lsh_debug;
   LogStreamHandle(Info, monitorinflation) lsh_info;
-  LogStream * ls = NULL;
+  LogStream* ls = NULL;
   if (log_is_enabled(Debug, monitorinflation)) {
     ls = &lsh_debug;
-  } else if ((tally != 0 || inUseTally != 0) &&
+  } else if ((free_count != 0 || in_use_count != 0) &&
              log_is_enabled(Info, monitorinflation)) {
     ls = &lsh_info;
   }
   if (ls != NULL) {
-    ls->print_cr("omFlush: jt=" INTPTR_FORMAT ", free_monitor_tally=%d"
-                 ", in_use_monitor_tally=%d" ", omFreeProvision=%d",
-                 p2i(Self), tally, inUseTally, Self->omFreeProvision);
+    ls->print_cr("om_flush: jt=" INTPTR_FORMAT ", free_count=%d"
+                 ", in_use_count=%d" ", om_free_provision=%d",
+                 p2i(self), free_count, in_use_count, self->om_free_provision);
   }
 }
 
@@ -1311,7 +1284,7 @@
   inflate(Thread::current(), obj, inflate_cause_vm_internal);
 }
 
-ObjectMonitor* ObjectSynchronizer::inflate(Thread * Self,
+ObjectMonitor* ObjectSynchronizer::inflate(Thread* self,
                                            oop object,
                                            const InflateCause cause) {
   // Inflate mutates the heap ...
@@ -1334,7 +1307,7 @@
 
     // CASE: inflated
     if (mark.has_monitor()) {
-      ObjectMonitor * inf = mark.monitor();
+      ObjectMonitor* inf = mark.monitor();
       markWord dmw = inf->header();
       assert(dmw.is_neutral(), "invariant: header=" INTPTR_FORMAT, dmw.value());
       assert(oopDesc::equals((oop) inf->object(), object), "invariant");
@@ -1349,7 +1322,7 @@
     // Currently, we spin/yield/park and poll the markword, waiting for inflation to finish.
     // We could always eliminate polling by parking the thread on some auxiliary list.
     if (mark == markWord::INFLATING()) {
-      ReadStableMark(object);
+      read_stable_mark(object);
       continue;
     }
 
@@ -1368,14 +1341,14 @@
     // critical INFLATING...ST interval.  A thread can transfer
     // multiple objectmonitors en-mass from the global free list to its local free list.
     // This reduces coherency traffic and lock contention on the global free list.
-    // Using such local free lists, it doesn't matter if the omAlloc() call appears
+    // Using such local free lists, it doesn't matter if the om_alloc() call appears
     // before or after the CAS(INFLATING) operation.
-    // See the comments in omAlloc().
+    // See the comments in om_alloc().
 
     LogStreamHandle(Trace, monitorinflation) lsh;
 
     if (mark.has_locker()) {
-      ObjectMonitor * m = omAlloc(Self);
+      ObjectMonitor* m = om_alloc(self);
       // Optimistically prepare the objectmonitor - anticipate successful CAS
       // We do this before the CAS in order to minimize the length of time
       // in which INFLATING appears in the mark.
@@ -1385,7 +1358,7 @@
 
       markWord cmp = object->cas_set_mark(markWord::INFLATING(), mark);
       if (cmp != mark) {
-        omRelease(Self, m, true);
+        om_release(self, m, true);
         continue;       // Interference -- just retry
       }
 
@@ -1398,17 +1371,17 @@
       // mark-word from the stack-locked value directly to the new inflated state?
       // Consider what happens when a thread unlocks a stack-locked object.
       // It attempts to use CAS to swing the displaced header value from the
-      // on-stack basiclock back into the object header.  Recall also that the
+      // on-stack BasicLock back into the object header.  Recall also that the
       // header value (hash code, etc) can reside in (a) the object header, or
       // (b) a displaced header associated with the stack-lock, or (c) a displaced
-      // header in an objectMonitor.  The inflate() routine must copy the header
-      // value from the basiclock on the owner's stack to the objectMonitor, all
+      // header in an ObjectMonitor.  The inflate() routine must copy the header
+      // value from the BasicLock on the owner's stack to the ObjectMonitor, all
       // the while preserving the hashCode stability invariants.  If the owner
       // decides to release the lock while the value is 0, the unlock will fail
       // and control will eventually pass from slow_exit() to inflate.  The owner
       // will then spin, waiting for the 0 value to disappear.   Put another way,
       // the 0 causes the owner to stall if the owner happens to try to
-      // drop the lock (restoring the header from the basiclock to the object)
+      // drop the lock (restoring the header from the BasicLock to the object)
       // while inflation is in-progress.  This protocol avoids races that might
       // would otherwise permit hashCode values to change or "flicker" for an object.
       // Critically, while object->mark is 0 mark.displaced_mark_helper() is stable.
@@ -1428,7 +1401,7 @@
       m->set_header(dmw);
 
       // Optimization: if the mark.locker stack address is associated
-      // with this thread we could simply set m->_owner = Self.
+      // with this thread we could simply set m->_owner = self.
       // Note that a thread can inflate an object
       // that it has stack-locked -- as might happen in wait() -- directly
       // with CAS.  That is, we can avoid the xchg-NULL .... ST idiom.
@@ -1445,7 +1418,7 @@
       // to avoid false sharing on MP systems ...
       OM_PERFDATA_OP(Inflations, inc());
       if (log_is_enabled(Trace, monitorinflation)) {
-        ResourceMark rm(Self);
+        ResourceMark rm(self);
         lsh.print_cr("inflate(has_locker): object=" INTPTR_FORMAT ", mark="
                      INTPTR_FORMAT ", type='%s'", p2i(object),
                      object->mark().value(), object->klass()->external_name());
@@ -1459,17 +1432,16 @@
     // CASE: neutral
     // TODO-FIXME: for entry we currently inflate and then try to CAS _owner.
     // If we know we're inflating for entry it's better to inflate by swinging a
-    // pre-locked objectMonitor pointer into the object header.   A successful
+    // pre-locked ObjectMonitor pointer into the object header.   A successful
     // CAS inflates the object *and* confers ownership to the inflating thread.
     // In the current implementation we use a 2-step mechanism where we CAS()
-    // to inflate and then CAS() again to try to swing _owner from NULL to Self.
-    // An inflateTry() method that we could call from fast_enter() and slow_enter()
-    // would be useful.
+    // to inflate and then CAS() again to try to swing _owner from NULL to self.
+    // An inflateTry() method that we could call from enter() would be useful.
 
     // Catch if the object's header is not neutral (not locked and
     // not marked is what we care about here).
     assert(mark.is_neutral(), "invariant: header=" INTPTR_FORMAT, mark.value());
-    ObjectMonitor * m = omAlloc(Self);
+    ObjectMonitor* m = om_alloc(self);
     // prepare m for installation - set monitor to initial state
     m->Recycle();
     m->set_header(mark);
@@ -1481,7 +1453,7 @@
       m->set_header(markWord::zero());
       m->set_object(NULL);
       m->Recycle();
-      omRelease(Self, m, true);
+      om_release(self, m, true);
       m = NULL;
       continue;
       // interference - the markword changed - just retry.
@@ -1493,7 +1465,7 @@
     // cache lines to avoid false sharing on MP systems ...
     OM_PERFDATA_OP(Inflations, inc());
     if (log_is_enabled(Trace, monitorinflation)) {
-      ResourceMark rm(Self);
+      ResourceMark rm(self);
       lsh.print_cr("inflate(neutral): object=" INTPTR_FORMAT ", mark="
                    INTPTR_FORMAT ", type='%s'", p2i(object),
                    object->mark().value(), object->klass()->external_name());
@@ -1510,7 +1482,7 @@
 //
 // deflate_thread_local_monitors() scans a single thread's in-use list, while
 // deflate_idle_monitors() scans only a global list of in-use monitors which
-// is populated only as a thread dies (see omFlush()).
+// is populated only as a thread dies (see om_flush()).
 //
 // These operations are called at all safepoints, immediately after mutators
 // are stopped, but before any objects have moved. Collectively they traverse
@@ -1530,8 +1502,8 @@
 // Deflate a single monitor if not in-use
 // Return true if deflated, false if in-use
 bool ObjectSynchronizer::deflate_monitor(ObjectMonitor* mid, oop obj,
-                                         ObjectMonitor** freeHeadp,
-                                         ObjectMonitor** freeTailp) {
+                                         ObjectMonitor** free_head_p,
+                                         ObjectMonitor** free_tail_p) {
   bool deflated;
   // Normal case ... The monitor is associated with obj.
   const markWord mark = obj->mark();
@@ -1565,14 +1537,22 @@
     assert(mid->object() == NULL, "invariant: object=" INTPTR_FORMAT,
            p2i(mid->object()));
 
-    // Move the object to the working free list defined by freeHeadp, freeTailp
-    if (*freeHeadp == NULL) *freeHeadp = mid;
-    if (*freeTailp != NULL) {
-      ObjectMonitor * prevtail = *freeTailp;
-      assert(prevtail->FreeNext == NULL, "cleaned up deflated?");
-      prevtail->FreeNext = mid;
+    // Move the deflated ObjectMonitor to the working free list
+    // defined by free_head_p and free_tail_p.
+    if (*free_head_p == NULL) *free_head_p = mid;
+    if (*free_tail_p != NULL) {
+      // We append to the list so the caller can use mid->_next_om
+      // to fix the linkages in its context.
+      ObjectMonitor* prevtail = *free_tail_p;
+      // Should have been cleaned up by the caller:
+      assert(prevtail->_next_om == NULL, "cleaned up deflated?");
+      prevtail->_next_om = mid;
     }
-    *freeTailp = mid;
+    *free_tail_p = mid;
+    // At this point, mid->_next_om still refers to its current
+    // value and another ObjectMonitor's _next_om field still
+    // refers to this ObjectMonitor. Those linkages have to be
+    // cleaned up by the caller who has the complete context.
     deflated = true;
   }
   return deflated;
@@ -1591,57 +1571,58 @@
 // See also ParallelSPCleanupTask and
 // SafepointSynchronize::do_cleanup_tasks() in safepoint.cpp and
 // Threads::parallel_java_threads_do() in thread.cpp.
-int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** listHeadp,
-                                             ObjectMonitor** freeHeadp,
-                                             ObjectMonitor** freeTailp) {
+int ObjectSynchronizer::deflate_monitor_list(ObjectMonitor** list_p,
+                                             ObjectMonitor** free_head_p,
+                                             ObjectMonitor** free_tail_p) {
   ObjectMonitor* mid;
   ObjectMonitor* next;
   ObjectMonitor* cur_mid_in_use = NULL;
   int deflated_count = 0;
 
-  for (mid = *listHeadp; mid != NULL;) {
+  for (mid = *list_p; mid != NULL;) {
     oop obj = (oop) mid->object();
-    if (obj != NULL && deflate_monitor(mid, obj, freeHeadp, freeTailp)) {
-      // if deflate_monitor succeeded,
-      // extract from per-thread in-use list
-      if (mid == *listHeadp) {
-        *listHeadp = mid->FreeNext;
+    if (obj != NULL && deflate_monitor(mid, obj, free_head_p, free_tail_p)) {
+      // Deflation succeeded and already updated free_head_p and
+      // free_tail_p as needed. Finish the move to the local free list
+      // by unlinking mid from the global or per-thread in-use list.
+      if (mid == *list_p) {
+        *list_p = mid->_next_om;
       } else if (cur_mid_in_use != NULL) {
-        cur_mid_in_use->FreeNext = mid->FreeNext; // maintain the current thread in-use list
+        cur_mid_in_use->_next_om = mid->_next_om; // maintain the current thread in-use list
       }
-      next = mid->FreeNext;
-      mid->FreeNext = NULL;  // This mid is current tail in the freeHeadp list
+      next = mid->_next_om;
+      mid->_next_om = NULL;  // This mid is current tail in the free_head_p list
       mid = next;
       deflated_count++;
     } else {
       cur_mid_in_use = mid;
-      mid = mid->FreeNext;
+      mid = mid->_next_om;
     }
   }
   return deflated_count;
 }
 
 void ObjectSynchronizer::prepare_deflate_idle_monitors(DeflateMonitorCounters* counters) {
-  counters->nInuse = 0;              // currently associated with objects
-  counters->nInCirculation = 0;      // extant
-  counters->nScavenged = 0;          // reclaimed (global and per-thread)
-  counters->perThreadScavenged = 0;  // per-thread scavenge total
-  counters->perThreadTimes = 0.0;    // per-thread scavenge times
+  counters->n_in_use = 0;              // currently associated with objects
+  counters->n_in_circulation = 0;      // extant
+  counters->n_scavenged = 0;           // reclaimed (global and per-thread)
+  counters->per_thread_scavenged = 0;  // per-thread scavenge total
+  counters->per_thread_times = 0.0;    // per-thread scavenge times
 }
 
 void ObjectSynchronizer::deflate_idle_monitors(DeflateMonitorCounters* counters) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   bool deflated = false;
 
-  ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
-  ObjectMonitor * freeTailp = NULL;
+  ObjectMonitor* free_head_p = NULL;  // Local SLL of scavenged monitors
+  ObjectMonitor* free_tail_p = NULL;
   elapsedTimer timer;
 
   if (log_is_enabled(Info, monitorinflation)) {
     timer.start();
   }
 
-  // Prevent omFlush from changing mids in Thread dtor's during deflation
+  // Prevent om_flush from changing mids in Thread dtor's during deflation
   // And in case the vm thread is acquiring a lock during a safepoint
   // See e.g. 6320749
   Thread::muxAcquire(&gListLock, "deflate_idle_monitors");
@@ -1649,30 +1630,30 @@
   // Note: the thread-local monitors lists get deflated in
   // a separate pass. See deflate_thread_local_monitors().
 
-  // For moribund threads, scan gOmInUseList
+  // For moribund threads, scan g_om_in_use_list
   int deflated_count = 0;
-  if (gOmInUseList) {
-    counters->nInCirculation += gOmInUseCount;
-    deflated_count = deflate_monitor_list((ObjectMonitor **)&gOmInUseList, &freeHeadp, &freeTailp);
-    gOmInUseCount -= deflated_count;
-    counters->nScavenged += deflated_count;
-    counters->nInuse += gOmInUseCount;
+  if (g_om_in_use_list) {
+    counters->n_in_circulation += g_om_in_use_count;
+    deflated_count = deflate_monitor_list((ObjectMonitor **)&g_om_in_use_list, &free_head_p, &free_tail_p);
+    g_om_in_use_count -= deflated_count;
+    counters->n_scavenged += deflated_count;
+    counters->n_in_use += g_om_in_use_count;
   }
 
-  // Move the scavenged monitors back to the global free list.
-  if (freeHeadp != NULL) {
-    guarantee(freeTailp != NULL && counters->nScavenged > 0, "invariant");
-    assert(freeTailp->FreeNext == NULL, "invariant");
-    // constant-time list splice - prepend scavenged segment to gFreeList
-    freeTailp->FreeNext = gFreeList;
-    gFreeList = freeHeadp;
+  if (free_head_p != NULL) {
+    // Move the deflated ObjectMonitors back to the global free list.
+    guarantee(free_tail_p != NULL && counters->n_scavenged > 0, "invariant");
+    assert(free_tail_p->_next_om == NULL, "invariant");
+    // constant-time list splice - prepend scavenged segment to g_free_list
+    free_tail_p->_next_om = g_free_list;
+    g_free_list = free_head_p;
   }
   Thread::muxRelease(&gListLock);
   timer.stop();
 
   LogStreamHandle(Debug, monitorinflation) lsh_debug;
   LogStreamHandle(Info, monitorinflation) lsh_info;
-  LogStream * ls = NULL;
+  LogStream* ls = NULL;
   if (log_is_enabled(Debug, monitorinflation)) {
     ls = &lsh_debug;
   } else if (deflated_count != 0 && log_is_enabled(Info, monitorinflation)) {
@@ -1688,9 +1669,9 @@
   // monitors. Note: if the work is split among more than one
   // worker thread, then the reported time will likely be more
   // than a beginning to end measurement of the phase.
-  log_info(safepoint, cleanup)("deflating per-thread idle monitors, %3.7f secs, monitors=%d", counters->perThreadTimes, counters->perThreadScavenged);
+  log_info(safepoint, cleanup)("deflating per-thread idle monitors, %3.7f secs, monitors=%d", counters->per_thread_times, counters->per_thread_scavenged);
 
-  gMonitorFreeCount += counters->nScavenged;
+  g_om_free_count += counters->n_scavenged;
 
   if (log_is_enabled(Debug, monitorinflation)) {
     // exit_globals()'s call to audit_and_print_stats() is done
@@ -1698,26 +1679,26 @@
     ObjectSynchronizer::audit_and_print_stats(false /* on_exit */);
   } else if (log_is_enabled(Info, monitorinflation)) {
     Thread::muxAcquire(&gListLock, "finish_deflate_idle_monitors");
-    log_info(monitorinflation)("gMonitorPopulation=%d, gOmInUseCount=%d, "
-                               "gMonitorFreeCount=%d", gMonitorPopulation,
-                               gOmInUseCount, gMonitorFreeCount);
+    log_info(monitorinflation)("g_om_population=%d, g_om_in_use_count=%d, "
+                               "g_om_free_count=%d", g_om_population,
+                               g_om_in_use_count, g_om_free_count);
     Thread::muxRelease(&gListLock);
   }
 
   ForceMonitorScavenge = 0;    // Reset
 
-  OM_PERFDATA_OP(Deflations, inc(counters->nScavenged));
-  OM_PERFDATA_OP(MonExtant, set_value(counters->nInCirculation));
+  OM_PERFDATA_OP(Deflations, inc(counters->n_scavenged));
+  OM_PERFDATA_OP(MonExtant, set_value(counters->n_in_circulation));
 
-  GVars.stwRandom = os::random();
-  GVars.stwCycle++;
+  GVars.stw_random = os::random();
+  GVars.stw_cycle++;
 }
 
 void ObjectSynchronizer::deflate_thread_local_monitors(Thread* thread, DeflateMonitorCounters* counters) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 
-  ObjectMonitor * freeHeadp = NULL;  // Local SLL of scavenged monitors
-  ObjectMonitor * freeTailp = NULL;
+  ObjectMonitor* free_head_p = NULL;  // Local SLL of scavenged monitors
+  ObjectMonitor* free_tail_p = NULL;
   elapsedTimer timer;
 
   if (log_is_enabled(Info, safepoint, cleanup) ||
@@ -1725,38 +1706,38 @@
     timer.start();
   }
 
-  int deflated_count = deflate_monitor_list(thread->omInUseList_addr(), &freeHeadp, &freeTailp);
+  int deflated_count = deflate_monitor_list(thread->om_in_use_list_addr(), &free_head_p, &free_tail_p);
 
   Thread::muxAcquire(&gListLock, "deflate_thread_local_monitors");
 
   // Adjust counters
-  counters->nInCirculation += thread->omInUseCount;
-  thread->omInUseCount -= deflated_count;
-  counters->nScavenged += deflated_count;
-  counters->nInuse += thread->omInUseCount;
-  counters->perThreadScavenged += deflated_count;
+  counters->n_in_circulation += thread->om_in_use_count;
+  thread->om_in_use_count -= deflated_count;
+  counters->n_scavenged += deflated_count;
+  counters->n_in_use += thread->om_in_use_count;
+  counters->per_thread_scavenged += deflated_count;
 
-  // Move the scavenged monitors back to the global free list.
-  if (freeHeadp != NULL) {
-    guarantee(freeTailp != NULL && deflated_count > 0, "invariant");
-    assert(freeTailp->FreeNext == NULL, "invariant");
+  if (free_head_p != NULL) {
+    // Move the deflated ObjectMonitors back to the global free list.
+    guarantee(free_tail_p != NULL && deflated_count > 0, "invariant");
+    assert(free_tail_p->_next_om == NULL, "invariant");
 
-    // constant-time list splice - prepend scavenged segment to gFreeList
-    freeTailp->FreeNext = gFreeList;
-    gFreeList = freeHeadp;
+    // constant-time list splice - prepend scavenged segment to g_free_list
+    free_tail_p->_next_om = g_free_list;
+    g_free_list = free_head_p;
   }
 
   timer.stop();
-  // Safepoint logging cares about cumulative perThreadTimes and
+  // Safepoint logging cares about cumulative per_thread_times and
   // we'll capture most of the cost, but not the muxRelease() which
   // should be cheap.
-  counters->perThreadTimes += timer.seconds();
+  counters->per_thread_times += timer.seconds();
 
   Thread::muxRelease(&gListLock);
 
   LogStreamHandle(Debug, monitorinflation) lsh_debug;
   LogStreamHandle(Info, monitorinflation) lsh_info;
-  LogStream * ls = NULL;
+  LogStream* ls = NULL;
   if (log_is_enabled(Debug, monitorinflation)) {
     ls = &lsh_debug;
   } else if (deflated_count != 0 && log_is_enabled(Info, monitorinflation)) {
@@ -1832,16 +1813,16 @@
   return (u_char*)&GVars;
 }
 
-u_char* ObjectSynchronizer::get_gvars_hcSequence_addr() {
-  return (u_char*)&GVars.hcSequence;
+u_char* ObjectSynchronizer::get_gvars_hc_sequence_addr() {
+  return (u_char*)&GVars.hc_sequence;
 }
 
 size_t ObjectSynchronizer::get_gvars_size() {
   return sizeof(SharedGlobals);
 }
 
-u_char* ObjectSynchronizer::get_gvars_stwRandom_addr() {
-  return (u_char*)&GVars.stwRandom;
+u_char* ObjectSynchronizer::get_gvars_stw_random_addr() {
+  return (u_char*)&GVars.stw_random;
 }
 
 void ObjectSynchronizer::audit_and_print_stats(bool on_exit) {
@@ -1850,7 +1831,7 @@
   LogStreamHandle(Debug, monitorinflation) lsh_debug;
   LogStreamHandle(Info, monitorinflation) lsh_info;
   LogStreamHandle(Trace, monitorinflation) lsh_trace;
-  LogStream * ls = NULL;
+  LogStream* ls = NULL;
   if (log_is_enabled(Trace, monitorinflation)) {
     ls = &lsh_trace;
   } else if (log_is_enabled(Debug, monitorinflation)) {
@@ -1866,26 +1847,26 @@
   }
 
   // Log counts for the global and per-thread monitor lists:
-  int chkMonitorPopulation = log_monitor_list_counts(ls);
+  int chk_om_population = log_monitor_list_counts(ls);
   int error_cnt = 0;
 
   ls->print_cr("Checking global lists:");
 
-  // Check gMonitorPopulation:
-  if (gMonitorPopulation == chkMonitorPopulation) {
-    ls->print_cr("gMonitorPopulation=%d equals chkMonitorPopulation=%d",
-                 gMonitorPopulation, chkMonitorPopulation);
+  // Check g_om_population:
+  if (g_om_population == chk_om_population) {
+    ls->print_cr("g_om_population=%d equals chk_om_population=%d",
+                 g_om_population, chk_om_population);
   } else {
-    ls->print_cr("ERROR: gMonitorPopulation=%d is not equal to "
-                 "chkMonitorPopulation=%d", gMonitorPopulation,
-                 chkMonitorPopulation);
+    ls->print_cr("ERROR: g_om_population=%d is not equal to "
+                 "chk_om_population=%d", g_om_population,
+                 chk_om_population);
     error_cnt++;
   }
 
-  // Check gOmInUseList and gOmInUseCount:
+  // Check g_om_in_use_list and g_om_in_use_count:
   chk_global_in_use_list_and_count(ls, &error_cnt);
 
-  // Check gFreeList and gMonitorFreeCount:
+  // Check g_free_list and g_om_free_count:
   chk_global_free_list_and_count(ls, &error_cnt);
 
   if (!on_exit) {
@@ -1895,10 +1876,10 @@
   ls->print_cr("Checking per-thread lists:");
 
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
-    // Check omInUseList and omInUseCount:
+    // Check om_in_use_list and om_in_use_count:
     chk_per_thread_in_use_list_and_count(jt, ls, &error_cnt);
 
-    // Check omFreeList and omFreeCount:
+    // Check om_free_list and om_free_count:
     chk_per_thread_free_list_and_count(jt, ls, &error_cnt);
   }
 
@@ -1922,7 +1903,7 @@
 }
 
 // Check a free monitor entry; log any errors.
-void ObjectSynchronizer::chk_free_entry(JavaThread * jt, ObjectMonitor * n,
+void ObjectSynchronizer::chk_free_entry(JavaThread* jt, ObjectMonitor* n,
                                         outputStream * out, int *error_cnt_p) {
   stringStream ss;
   if (n->is_busy()) {
@@ -1967,18 +1948,18 @@
 // Check the global free list and count; log the results of the checks.
 void ObjectSynchronizer::chk_global_free_list_and_count(outputStream * out,
                                                         int *error_cnt_p) {
-  int chkMonitorFreeCount = 0;
-  for (ObjectMonitor * n = gFreeList; n != NULL; n = n->FreeNext) {
+  int chk_om_free_count = 0;
+  for (ObjectMonitor* n = g_free_list; n != NULL; n = n->_next_om) {
     chk_free_entry(NULL /* jt */, n, out, error_cnt_p);
-    chkMonitorFreeCount++;
+    chk_om_free_count++;
   }
-  if (gMonitorFreeCount == chkMonitorFreeCount) {
-    out->print_cr("gMonitorFreeCount=%d equals chkMonitorFreeCount=%d",
-                  gMonitorFreeCount, chkMonitorFreeCount);
+  if (g_om_free_count == chk_om_free_count) {
+    out->print_cr("g_om_free_count=%d equals chk_om_free_count=%d",
+                  g_om_free_count, chk_om_free_count);
   } else {
-    out->print_cr("ERROR: gMonitorFreeCount=%d is not equal to "
-                  "chkMonitorFreeCount=%d", gMonitorFreeCount,
-                  chkMonitorFreeCount);
+    out->print_cr("ERROR: g_om_free_count=%d is not equal to "
+                  "chk_om_free_count=%d", g_om_free_count,
+                  chk_om_free_count);
     *error_cnt_p = *error_cnt_p + 1;
   }
 }
@@ -1986,23 +1967,23 @@
 // Check the global in-use list and count; log the results of the checks.
 void ObjectSynchronizer::chk_global_in_use_list_and_count(outputStream * out,
                                                           int *error_cnt_p) {
-  int chkOmInUseCount = 0;
-  for (ObjectMonitor * n = gOmInUseList; n != NULL; n = n->FreeNext) {
+  int chk_om_in_use_count = 0;
+  for (ObjectMonitor* n = g_om_in_use_list; n != NULL; n = n->_next_om) {
     chk_in_use_entry(NULL /* jt */, n, out, error_cnt_p);
-    chkOmInUseCount++;
+    chk_om_in_use_count++;
   }
-  if (gOmInUseCount == chkOmInUseCount) {
-    out->print_cr("gOmInUseCount=%d equals chkOmInUseCount=%d", gOmInUseCount,
-                  chkOmInUseCount);
+  if (g_om_in_use_count == chk_om_in_use_count) {
+    out->print_cr("g_om_in_use_count=%d equals chk_om_in_use_count=%d", g_om_in_use_count,
+                  chk_om_in_use_count);
   } else {
-    out->print_cr("ERROR: gOmInUseCount=%d is not equal to chkOmInUseCount=%d",
-                  gOmInUseCount, chkOmInUseCount);
+    out->print_cr("ERROR: g_om_in_use_count=%d is not equal to chk_om_in_use_count=%d",
+                  g_om_in_use_count, chk_om_in_use_count);
     *error_cnt_p = *error_cnt_p + 1;
   }
 }
 
 // Check an in-use monitor entry; log any errors.
-void ObjectSynchronizer::chk_in_use_entry(JavaThread * jt, ObjectMonitor * n,
+void ObjectSynchronizer::chk_in_use_entry(JavaThread* jt, ObjectMonitor* n,
                                           outputStream * out, int *error_cnt_p) {
   if (n->header().value() == 0) {
     if (jt != NULL) {
@@ -2042,7 +2023,7 @@
     }
     *error_cnt_p = *error_cnt_p + 1;
   }
-  ObjectMonitor * const obj_mon = mark.monitor();
+  ObjectMonitor* const obj_mon = mark.monitor();
   if (n != obj_mon) {
     if (jt != NULL) {
       out->print_cr("ERROR: jt=" INTPTR_FORMAT ", monitor=" INTPTR_FORMAT
@@ -2064,18 +2045,18 @@
 void ObjectSynchronizer::chk_per_thread_free_list_and_count(JavaThread *jt,
                                                             outputStream * out,
                                                             int *error_cnt_p) {
-  int chkOmFreeCount = 0;
-  for (ObjectMonitor * n = jt->omFreeList; n != NULL; n = n->FreeNext) {
+  int chk_om_free_count = 0;
+  for (ObjectMonitor* n = jt->om_free_list; n != NULL; n = n->_next_om) {
     chk_free_entry(jt, n, out, error_cnt_p);
-    chkOmFreeCount++;
+    chk_om_free_count++;
   }
-  if (jt->omFreeCount == chkOmFreeCount) {
-    out->print_cr("jt=" INTPTR_FORMAT ": omFreeCount=%d equals "
-                  "chkOmFreeCount=%d", p2i(jt), jt->omFreeCount, chkOmFreeCount);
+  if (jt->om_free_count == chk_om_free_count) {
+    out->print_cr("jt=" INTPTR_FORMAT ": om_free_count=%d equals "
+                  "chk_om_free_count=%d", p2i(jt), jt->om_free_count, chk_om_free_count);
   } else {
-    out->print_cr("ERROR: jt=" INTPTR_FORMAT ": omFreeCount=%d is not "
-                  "equal to chkOmFreeCount=%d", p2i(jt), jt->omFreeCount,
-                  chkOmFreeCount);
+    out->print_cr("ERROR: jt=" INTPTR_FORMAT ": om_free_count=%d is not "
+                  "equal to chk_om_free_count=%d", p2i(jt), jt->om_free_count,
+                  chk_om_free_count);
     *error_cnt_p = *error_cnt_p + 1;
   }
 }
@@ -2084,19 +2065,19 @@
 void ObjectSynchronizer::chk_per_thread_in_use_list_and_count(JavaThread *jt,
                                                               outputStream * out,
                                                               int *error_cnt_p) {
-  int chkOmInUseCount = 0;
-  for (ObjectMonitor * n = jt->omInUseList; n != NULL; n = n->FreeNext) {
+  int chk_om_in_use_count = 0;
+  for (ObjectMonitor* n = jt->om_in_use_list; n != NULL; n = n->_next_om) {
     chk_in_use_entry(jt, n, out, error_cnt_p);
-    chkOmInUseCount++;
+    chk_om_in_use_count++;
   }
-  if (jt->omInUseCount == chkOmInUseCount) {
-    out->print_cr("jt=" INTPTR_FORMAT ": omInUseCount=%d equals "
-                  "chkOmInUseCount=%d", p2i(jt), jt->omInUseCount,
-                  chkOmInUseCount);
+  if (jt->om_in_use_count == chk_om_in_use_count) {
+    out->print_cr("jt=" INTPTR_FORMAT ": om_in_use_count=%d equals "
+                  "chk_om_in_use_count=%d", p2i(jt), jt->om_in_use_count,
+                  chk_om_in_use_count);
   } else {
-    out->print_cr("ERROR: jt=" INTPTR_FORMAT ": omInUseCount=%d is not "
-                  "equal to chkOmInUseCount=%d", p2i(jt), jt->omInUseCount,
-                  chkOmInUseCount);
+    out->print_cr("ERROR: jt=" INTPTR_FORMAT ": om_in_use_count=%d is not "
+                  "equal to chk_om_in_use_count=%d", p2i(jt), jt->om_in_use_count,
+                  chk_om_in_use_count);
     *error_cnt_p = *error_cnt_p + 1;
   }
 }
@@ -2112,13 +2093,13 @@
   }
 
   stringStream ss;
-  if (gOmInUseCount > 0) {
+  if (g_om_in_use_count > 0) {
     out->print_cr("In-use global monitor info:");
     out->print_cr("(B -> is_busy, H -> has hash code, L -> lock status)");
     out->print_cr("%18s  %s  %18s  %18s",
                   "monitor", "BHL", "object", "object type");
     out->print_cr("==================  ===  ==================  ==================");
-    for (ObjectMonitor * n = gOmInUseList; n != NULL; n = n->FreeNext) {
+    for (ObjectMonitor* n = g_om_in_use_list; n != NULL; n = n->_next_om) {
       const oop obj = (oop) n->object();
       const markWord mark = n->header();
       ResourceMark rm;
@@ -2143,7 +2124,7 @@
                 "jt", "monitor", "BHL", "object", "object type");
   out->print_cr("==================  ==================  ===  ==================  ==================");
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
-    for (ObjectMonitor * n = jt->omInUseList; n != NULL; n = n->FreeNext) {
+    for (ObjectMonitor* n = jt->om_in_use_list; n != NULL; n = n->_next_om) {
       const oop obj = (oop) n->object();
       const markWord mark = n->header();
       ResourceMark rm;
@@ -2165,13 +2146,13 @@
 // Log counts for the global and per-thread monitor lists and return
 // the population count.
 int ObjectSynchronizer::log_monitor_list_counts(outputStream * out) {
-  int popCount = 0;
+  int pop_count = 0;
   out->print_cr("%18s  %10s  %10s  %10s",
                 "Global Lists:", "InUse", "Free", "Total");
   out->print_cr("==================  ==========  ==========  ==========");
   out->print_cr("%18s  %10d  %10d  %10d", "",
-                gOmInUseCount, gMonitorFreeCount, gMonitorPopulation);
-  popCount += gOmInUseCount + gMonitorFreeCount;
+                g_om_in_use_count, g_om_free_count, g_om_population);
+  pop_count += g_om_in_use_count + g_om_free_count;
 
   out->print_cr("%18s  %10s  %10s  %10s",
                 "Per-Thread Lists:", "InUse", "Free", "Provision");
@@ -2179,10 +2160,10 @@
 
   for (JavaThreadIteratorWithHandle jtiwh; JavaThread *jt = jtiwh.next(); ) {
     out->print_cr(INTPTR_FORMAT "  %10d  %10d  %10d", p2i(jt),
-                  jt->omInUseCount, jt->omFreeCount, jt->omFreeProvision);
-    popCount += jt->omInUseCount + jt->omFreeCount;
+                  jt->om_in_use_count, jt->om_free_count, jt->om_free_provision);
+    pop_count += jt->om_in_use_count + jt->om_free_count;
   }
-  return popCount;
+  return pop_count;
 }
 
 #ifndef PRODUCT
@@ -2192,17 +2173,17 @@
 // the list of extant blocks without taking a lock.
 
 int ObjectSynchronizer::verify_objmon_isinpool(ObjectMonitor *monitor) {
-  PaddedEnd<ObjectMonitor> * block = OrderAccess::load_acquire(&gBlockList);
+  PaddedObjectMonitor* block = OrderAccess::load_acquire(&g_block_list);
   while (block != NULL) {
     assert(block->object() == CHAINMARKER, "must be a block header");
     if (monitor > &block[0] && monitor < &block[_BLOCKSIZE]) {
       address mon = (address)monitor;
       address blk = (address)block;
       size_t diff = mon - blk;
-      assert((diff % sizeof(PaddedEnd<ObjectMonitor>)) == 0, "must be aligned");
+      assert((diff % sizeof(PaddedObjectMonitor)) == 0, "must be aligned");
       return 1;
     }
-    block = (PaddedEnd<ObjectMonitor> *)block->FreeNext;
+    block = (PaddedObjectMonitor*)block->_next_om;
   }
   return 0;
 }
--- a/src/hotspot/share/runtime/synchronizer.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/synchronizer.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -26,7 +26,7 @@
 #define SHARE_RUNTIME_SYNCHRONIZER_HPP
 
 #include "memory/padded.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "runtime/basicLock.hpp"
 #include "runtime/handles.hpp"
 #include "runtime/perfData.hpp"
@@ -34,12 +34,14 @@
 class ObjectMonitor;
 class ThreadsList;
 
+typedef PaddedEnd<ObjectMonitor, DEFAULT_CACHE_LINE_SIZE> PaddedObjectMonitor;
+
 struct DeflateMonitorCounters {
-  int nInuse;              // currently associated with objects
-  int nInCirculation;      // extant
-  int nScavenged;          // reclaimed (global and per-thread)
-  int perThreadScavenged;  // per-thread scavenge total
-  double perThreadTimes;   // per-thread scavenge times
+  int n_in_use;              // currently associated with objects
+  int n_in_circulation;      // extant
+  int n_scavenged;           // reclaimed (global and per-thread)
+  int per_thread_scavenged;  // per-thread scavenge total
+  double per_thread_times;   // per-thread scavenge times
 };
 
 class ObjectSynchronizer : AllStatic {
@@ -65,22 +67,9 @@
   // exit must be implemented non-blocking, since the compiler cannot easily handle
   // deoptimization at monitor exit. Hence, it does not take a Handle argument.
 
-  // This is full version of monitor enter and exit. I choose not
-  // to use enter() and exit() in order to make sure user be ware
-  // of the performance and semantics difference. They are normally
-  // used by ObjectLocker etc. The interpreter and compiler use
-  // assembly copies of these routines. Please keep them synchronized.
-  //
-  // attempt_rebias flag is used by UseBiasedLocking implementation
-  static void fast_enter(Handle obj, BasicLock* lock, bool attempt_rebias,
-                         TRAPS);
-  static void fast_exit(oop obj, BasicLock* lock, Thread* THREAD);
-
-  // WARNING: They are ONLY used to handle the slow cases. They should
-  // only be used when the fast cases failed. Use of these functions
-  // without previous fast case check may cause fatal error.
-  static void slow_enter(Handle obj, BasicLock* lock, TRAPS);
-  static void slow_exit(oop obj, BasicLock* lock, Thread* THREAD);
+  // This is the "slow path" version of monitor enter and exit.
+  static void enter(Handle obj, BasicLock* lock, TRAPS);
+  static void exit(oop obj, BasicLock* lock, Thread* THREAD);
 
   // Used only to handle jni locks or other unmatched monitor enter/exit
   // Internally they will use heavy weight monitor.
@@ -92,13 +81,13 @@
   static void notify(Handle obj, TRAPS);
   static void notifyall(Handle obj, TRAPS);
 
-  static bool quick_notify(oopDesc* obj, Thread* Self, bool All);
-  static bool quick_enter(oop obj, Thread* Self, BasicLock* Lock);
+  static bool quick_notify(oopDesc* obj, Thread* self, bool All);
+  static bool quick_enter(oop obj, Thread* self, BasicLock* Lock);
 
   // Special internal-use-only method for use by JVM infrastructure
   // that needs to wait() on a java-level object but that can't risk
   // throwing unexpected InterruptedExecutionExceptions.
-  static void waitUninterruptibly(Handle obj, jlong Millis, Thread * THREAD);
+  static void wait_uninterruptibly(Handle obj, jlong Millis, Thread* THREAD);
 
   // used by classloading to free classloader object lock,
   // wait on an internal lock, and reclaim original lock
@@ -106,14 +95,14 @@
   static intptr_t complete_exit(Handle obj, TRAPS);
   static void reenter (Handle obj, intptr_t recursion, TRAPS);
 
-  // thread-specific and global objectMonitor free list accessors
-  static ObjectMonitor * omAlloc(Thread * Self);
-  static void omRelease(Thread * Self, ObjectMonitor * m,
-                        bool FromPerThreadAlloc);
-  static void omFlush(Thread * Self);
+  // thread-specific and global ObjectMonitor free list accessors
+  static ObjectMonitor* om_alloc(Thread* self);
+  static void om_release(Thread* self, ObjectMonitor* m,
+                         bool FromPerThreadAlloc);
+  static void om_flush(Thread* self);
 
   // Inflate light weight monitor to heavy weight monitor
-  static ObjectMonitor* inflate(Thread * Self, oop obj, const InflateCause cause);
+  static ObjectMonitor* inflate(Thread* self, oop obj, const InflateCause cause);
   // This version is only for internal use
   static void inflate_helper(oop obj);
   static const char* inflate_cause_name(const InflateCause cause);
@@ -121,11 +110,11 @@
   // Returns the identity hash value for an oop
   // NOTE: It may cause monitor inflation
   static intptr_t identity_hash_value_for(Handle obj);
-  static intptr_t FastHashCode(Thread * Self, oop obj);
+  static intptr_t FastHashCode(Thread* self, oop obj);
 
   // java.lang.Thread support
   static bool current_thread_holds_lock(JavaThread* thread, Handle h_obj);
-  static LockOwnership query_lock_ownership(JavaThread * self, Handle h_obj);
+  static LockOwnership query_lock_ownership(JavaThread* self, Handle h_obj);
 
   static JavaThread* get_lock_owner(ThreadsList * t_list, Handle h_obj);
 
@@ -142,12 +131,12 @@
   static void finish_deflate_idle_monitors(DeflateMonitorCounters* counters);
 
   // For a given monitor list: global or per-thread, deflate idle monitors
-  static int deflate_monitor_list(ObjectMonitor** listheadp,
-                                  ObjectMonitor** freeHeadp,
-                                  ObjectMonitor** freeTailp);
+  static int deflate_monitor_list(ObjectMonitor** list_p,
+                                  ObjectMonitor** free_head_p,
+                                  ObjectMonitor** free_tail_p);
   static bool deflate_monitor(ObjectMonitor* mid, oop obj,
-                              ObjectMonitor** freeHeadp,
-                              ObjectMonitor** freeTailp);
+                              ObjectMonitor** free_head_p,
+                              ObjectMonitor** free_tail_p);
   static bool is_cleanup_needed();
   static void oops_do(OopClosure* f);
   // Process oops in thread local used monitors
@@ -155,13 +144,13 @@
 
   // debugging
   static void audit_and_print_stats(bool on_exit);
-  static void chk_free_entry(JavaThread * jt, ObjectMonitor * n,
+  static void chk_free_entry(JavaThread* jt, ObjectMonitor* n,
                              outputStream * out, int *error_cnt_p);
   static void chk_global_free_list_and_count(outputStream * out,
                                              int *error_cnt_p);
   static void chk_global_in_use_list_and_count(outputStream * out,
                                                int *error_cnt_p);
-  static void chk_in_use_entry(JavaThread * jt, ObjectMonitor * n,
+  static void chk_in_use_entry(JavaThread* jt, ObjectMonitor* n,
                                outputStream * out, int *error_cnt_p);
   static void chk_per_thread_in_use_list_and_count(JavaThread *jt,
                                                    outputStream * out,
@@ -178,14 +167,14 @@
 
   enum { _BLOCKSIZE = 128 };
   // global list of blocks of monitors
-  static PaddedEnd<ObjectMonitor> * volatile gBlockList;
+  static PaddedObjectMonitor* volatile g_block_list;
   // global monitor free list
-  static ObjectMonitor * volatile gFreeList;
+  static ObjectMonitor* volatile g_free_list;
   // global monitor in-use list, for moribund threads,
   // monitors they inflated need to be scanned for deflation
-  static ObjectMonitor * volatile gOmInUseList;
-  // count of entries in gOmInUseList
-  static int gOmInUseCount;
+  static ObjectMonitor* volatile g_om_in_use_list;
+  // count of entries in g_om_in_use_list
+  static int g_om_in_use_count;
 
   // Process oops in all global used monitors (i.e. moribund thread's monitors)
   static void global_used_oops_do(OopClosure* f);
@@ -194,9 +183,9 @@
 
   // Support for SynchronizerTest access to GVars fields:
   static u_char* get_gvars_addr();
-  static u_char* get_gvars_hcSequence_addr();
+  static u_char* get_gvars_hc_sequence_addr();
   static size_t get_gvars_size();
-  static u_char* get_gvars_stwRandom_addr();
+  static u_char* get_gvars_stw_random_addr();
 };
 
 // ObjectLocker enforces balanced locking and can never throw an
@@ -211,13 +200,13 @@
   BasicLock _lock;
   bool      _dolock;   // default true
  public:
-  ObjectLocker(Handle obj, Thread* thread, bool doLock = true);
+  ObjectLocker(Handle obj, Thread* thread, bool do_lock = true);
   ~ObjectLocker();
 
   // Monitor behavior
   void wait(TRAPS)  { ObjectSynchronizer::wait(_obj, 0, CHECK); } // wait forever
   void notify_all(TRAPS)  { ObjectSynchronizer::notifyall(_obj, CHECK); }
-  void waitUninterruptibly(TRAPS) { ObjectSynchronizer::waitUninterruptibly(_obj, 0, CHECK); }
+  void wait_uninterruptibly(TRAPS) { ObjectSynchronizer::wait_uninterruptibly(_obj, 0, CHECK); }
   // complete_exit gives up lock completely, returning recursion count
   // reenter reclaims lock with original recursion count
   intptr_t complete_exit(TRAPS)  { return ObjectSynchronizer::complete_exit(_obj, THREAD); }
--- a/src/hotspot/share/runtime/thread.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/thread.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -259,11 +259,11 @@
   _current_pending_monitor_is_from_java = true;
   _current_waiting_monitor = NULL;
   _num_nested_signal = 0;
-  omFreeList = NULL;
-  omFreeCount = 0;
-  omFreeProvision = 32;
-  omInUseList = NULL;
-  omInUseCount = 0;
+  om_free_list = NULL;
+  om_free_count = 0;
+  om_free_provision = 32;
+  om_in_use_list = NULL;
+  om_in_use_count = 0;
 
 #ifdef ASSERT
   _visited_for_critical_count = false;
@@ -971,7 +971,7 @@
 
 #ifdef ASSERT
 void Thread::print_owned_locks_on(outputStream* st) const {
-  Monitor *cur = _owned_locks;
+  Mutex* cur = _owned_locks;
   if (cur == NULL) {
     st->print(" (no locks) ");
   } else {
@@ -1011,7 +1011,7 @@
   if (potential_vm_operation && !Universe::is_bootstrapping()) {
     // Make sure we do not hold any locks that the VM thread also uses.
     // This could potentially lead to deadlocks
-    for (Monitor *cur = _owned_locks; cur; cur = cur->next()) {
+    for (Mutex* cur = _owned_locks; cur; cur = cur->next()) {
       // Threads_lock is special, since the safepoint synchronization will not start before this is
       // acquired. Hence, a JavaThread cannot be holding it at a safepoint. So is VMOperationRequest_lock,
       // since it is used to transfer control between JavaThreads and the VMThread
@@ -4414,8 +4414,8 @@
 
 void Threads::remove(JavaThread* p, bool is_daemon) {
 
-  // Reclaim the ObjectMonitors from the omInUseList and omFreeList of the moribund thread.
-  ObjectSynchronizer::omFlush(p);
+  // Reclaim the ObjectMonitors from the om_in_use_list and om_free_list of the moribund thread.
+  ObjectSynchronizer::om_flush(p);
 
   // Extra scope needed for Thread_lock, so we can check
   // that we do not remove thread without safepoint code notice
--- a/src/hotspot/share/runtime/thread.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/thread.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -408,13 +408,13 @@
   // ObjectMonitor on which this thread called Object.wait()
   ObjectMonitor* _current_waiting_monitor;
 
-  // Private thread-local objectmonitor list - a simple cache organized as a SLL.
+  // Per-thread ObjectMonitor lists:
  public:
-  ObjectMonitor* omFreeList;
-  int omFreeCount;                              // length of omFreeList
-  int omFreeProvision;                          // reload chunk size
-  ObjectMonitor* omInUseList;                   // SLL to track monitors in circulation
-  int omInUseCount;                             // length of omInUseList
+  ObjectMonitor* om_free_list;                  // SLL of free ObjectMonitors
+  int om_free_count;                            // # on om_free_list
+  int om_free_provision;                        // # to try to allocate next
+  ObjectMonitor* om_in_use_list;                // SLL of in-use ObjectMonitors
+  int om_in_use_count;                          // # on om_in_use_list
 
 #ifdef ASSERT
  private:
@@ -522,7 +522,7 @@
     os::set_native_thread_name(name);
   }
 
-  ObjectMonitor** omInUseList_addr()             { return (ObjectMonitor **)&omInUseList; }
+  ObjectMonitor** om_in_use_list_addr()          { return (ObjectMonitor **)&om_in_use_list; }
   Monitor* SR_lock() const                       { return _SR_lock; }
 
   bool has_async_exception() const { return (_suspend_flags & _has_async_exception) != 0; }
@@ -736,7 +736,7 @@
 #ifdef ASSERT
  private:
   // Deadlock detection support for Mutex locks. List of locks own by thread.
-  Monitor* _owned_locks;
+  Mutex* _owned_locks;
   // Mutex::set_owner_implementation is the only place where _owned_locks is modified,
   // thus the friendship
   friend class Mutex;
@@ -745,7 +745,7 @@
  public:
   void print_owned_locks_on(outputStream* st) const;
   void print_owned_locks() const                 { print_owned_locks_on(tty);    }
-  Monitor* owned_locks() const                   { return _owned_locks;          }
+  Mutex* owned_locks() const                     { return _owned_locks;          }
   bool owns_locks() const                        { return owned_locks() != NULL; }
 
   // Deadlock detection
--- a/src/hotspot/share/runtime/vmStructs.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/vmStructs.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -70,7 +70,7 @@
 #include "oops/instanceMirrorKlass.hpp"
 #include "oops/instanceOop.hpp"
 #include "oops/klass.hpp"
-#include "oops/markOop.hpp"
+#include "oops/markWord.hpp"
 #include "oops/method.hpp"
 #include "oops/methodCounters.hpp"
 #include "oops/methodData.hpp"
@@ -167,8 +167,6 @@
 typedef Hashtable<InstanceKlass*, mtClass>       KlassHashtable;
 typedef HashtableEntry<InstanceKlass*, mtClass>  KlassHashtableEntry;
 
-typedef PaddedEnd<ObjectMonitor>              PaddedObjectMonitor;
-
 //--------------------------------------------------------------------------------
 // VM_STRUCTS
 //
@@ -914,11 +912,11 @@
   volatile_nonstatic_field(ObjectMonitor,      _contentions,                                  jint)                                  \
   volatile_nonstatic_field(ObjectMonitor,      _waiters,                                      jint)                                  \
   volatile_nonstatic_field(ObjectMonitor,      _recursions,                                   intptr_t)                              \
-  nonstatic_field(ObjectMonitor,               FreeNext,                                      ObjectMonitor*)                        \
+  nonstatic_field(ObjectMonitor,               _next_om,                                      ObjectMonitor*)                        \
   volatile_nonstatic_field(BasicLock,          _displaced_header,                             markWord)                              \
   nonstatic_field(BasicObjectLock,             _lock,                                         BasicLock)                             \
   nonstatic_field(BasicObjectLock,             _obj,                                          oop)                                   \
-  static_ptr_volatile_field(ObjectSynchronizer, gBlockList,                                   PaddedObjectMonitor*)                  \
+  static_ptr_volatile_field(ObjectSynchronizer, g_block_list,                                 PaddedObjectMonitor*)                  \
                                                                                                                                      \
   /*********************/                                                                                                            \
   /* Matcher (C2 only) */                                                                                                            \
--- a/src/hotspot/share/runtime/vmStructs.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/vmStructs.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -168,7 +168,7 @@
  { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, &typeName::fieldName },
 
 // This macro generates a VMStructEntry line for a static pointer volatile field,
-// e.g.: "static ObjectMonitor * volatile gBlockList;"
+// e.g.: "static ObjectMonitor * volatile g_block_list;"
 #define GENERATE_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type)    \
  { QUOTE(typeName), QUOTE(fieldName), QUOTE(type), 1, 0, (void *)&typeName::fieldName },
 
@@ -202,7 +202,7 @@
  {type* dummy = &typeName::fieldName; }
 
 // This macro checks the type of a static pointer volatile VMStructEntry by comparing pointer types,
-// e.g.: "static ObjectMonitor * volatile gBlockList;"
+// e.g.: "static ObjectMonitor * volatile g_block_list;"
 #define CHECK_STATIC_PTR_VOLATILE_VM_STRUCT_ENTRY(typeName, fieldName, type)       \
  {type volatile * dummy = &typeName::fieldName; }
 
--- a/src/hotspot/share/runtime/vm_version.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/vm_version.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -42,6 +42,7 @@
 bool Abstract_VM_Version::_supports_atomic_getadd8 = false;
 unsigned int Abstract_VM_Version::_logical_processors_per_package = 1U;
 unsigned int Abstract_VM_Version::_L1_data_cache_line_size = 0;
+unsigned int Abstract_VM_Version::_data_cache_line_flush_size = 0;
 
 VirtualizationType Abstract_VM_Version::_detected_virtualization = NoDetectedVirtualization;
 
--- a/src/hotspot/share/runtime/vm_version.hpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/runtime/vm_version.hpp	Wed Aug 28 11:58:56 2019 -0400
@@ -67,6 +67,7 @@
   static int          _vm_security_version;
   static int          _vm_patch_version;
   static int          _vm_build_number;
+  static unsigned int _data_cache_line_flush_size;
 
   static VirtualizationType _detected_virtualization;
 
@@ -155,6 +156,18 @@
     return _L1_data_cache_line_size;
   }
 
+  // the size in bytes of a data cache line flushed by a flush
+  // operation which should be a power of two or zero if cache line
+  // writeback is not supported by the current os_cpu combination
+  static unsigned int data_cache_line_flush_size() {
+    return _data_cache_line_flush_size;
+  }
+
+  // returns true if and only if cache line writeback is supported
+  static bool supports_data_cache_line_flush() {
+    return _data_cache_line_flush_size != 0;
+  }
+
   // ARCH specific policy for the BiasedLocking
   static bool use_biased_locking()  { return true; }
 
--- a/src/hotspot/share/services/attachListener.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/services/attachListener.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -331,7 +331,7 @@
     out->print_cr("flag name is missing");
     return JNI_ERR;
   }
-  JVMFlag* f = JVMFlag::find_flag((char*)name, strlen(name));
+  JVMFlag* f = JVMFlag::find_flag(name);
   if (f) {
     f->print_as_flag(out);
     out->cr();
--- a/src/hotspot/share/services/dtraceAttacher.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/services/dtraceAttacher.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -50,9 +50,9 @@
   }
 };
 
-static void set_bool_flag(const char* flag, bool value) {
-  JVMFlag::boolAtPut((char*)flag, strlen(flag), &value,
-                              JVMFlag::ATTACH_ON_DEMAND);
+static void set_bool_flag(const char* name, bool value) {
+  JVMFlag* flag = JVMFlag::find_flag(name);
+  JVMFlag::boolAtPut(flag, &value, JVMFlag::ATTACH_ON_DEMAND);
 }
 
 // Enable only the "fine grained" flags. Do *not* touch
--- a/src/hotspot/share/services/heapDumper.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/services/heapDumper.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -760,7 +760,7 @@
   switch (type) {
     case JVM_SIGNATURE_CLASS :
     case JVM_SIGNATURE_ARRAY : {
-      oop o = obj->obj_field_access<ON_UNKNOWN_OOP_REF>(offset);
+      oop o = obj->obj_field_access<ON_UNKNOWN_OOP_REF | AS_NO_KEEPALIVE>(offset);
       assert(oopDesc::is_oop_or_null(o), "Expected an oop or NULL at " PTR_FORMAT, p2i(o));
       writer->write_objectID(o);
       break;
--- a/src/hotspot/share/services/management.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/services/management.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -1546,7 +1546,7 @@
 
       Handle sh(THREAD, s);
       char* str = java_lang_String::as_utf8_string(s);
-      JVMFlag* flag = JVMFlag::find_flag(str, strlen(str));
+      JVMFlag* flag = JVMFlag::find_flag(str);
       if (flag != NULL &&
           add_global_entry(env, sh, &globals[i], flag, THREAD)) {
         num_entries++;
--- a/src/hotspot/share/services/writeableFlags.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/services/writeableFlags.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -38,8 +38,8 @@
   strncat(buffer, src, TEMP_BUF_SIZE - 1 - strlen(buffer));
 }
 
-static void print_flag_error_message_bounds(const char* name, char* buffer) {
-  JVMFlagRange* range = JVMFlagRangeList::find(name);
+static void print_flag_error_message_bounds(const JVMFlag* flag, char* buffer) {
+  JVMFlagRange* range = JVMFlagRangeList::find(flag);
   if (range != NULL) {
     buffer_concat(buffer, "must have value in range ");
 
@@ -59,11 +59,12 @@
   }
 }
 
-static void print_flag_error_message_if_needed(JVMFlag::Error error, const char* name, FormatBuffer<80>& err_msg) {
+static void print_flag_error_message_if_needed(JVMFlag::Error error, const JVMFlag* flag, FormatBuffer<80>& err_msg) {
   if (error == JVMFlag::SUCCESS) {
     return;
   }
 
+  const char* name = flag->_name;
   char buffer[TEMP_BUF_SIZE] = {'\0'};
   if ((error != JVMFlag::MISSING_NAME) && (name != NULL)) {
     buffer_concat(buffer, name);
@@ -79,7 +80,7 @@
     case JVMFlag::NON_WRITABLE:
       buffer_concat(buffer, "flag is not writeable."); break;
     case JVMFlag::OUT_OF_BOUNDS:
-      if (name != NULL) { print_flag_error_message_bounds(name, buffer); } break;
+      if (name != NULL) { print_flag_error_message_bounds(flag, buffer); } break;
     case JVMFlag::VIOLATES_CONSTRAINT:
       buffer_concat(buffer, "value violates its flag's constraint."); break;
     case JVMFlag::INVALID_FLAG:
@@ -107,8 +108,9 @@
 }
 
 JVMFlag::Error WriteableFlags::set_bool_flag(const char* name, bool value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
-  JVMFlag::Error err = JVMFlag::boolAtPut(name, &value, origin);
-  print_flag_error_message_if_needed(err, name, err_msg);
+  JVMFlag* flag = JVMFlag::find_flag(name);
+  JVMFlag::Error err = JVMFlag::boolAtPut(flag, &value, origin);
+  print_flag_error_message_if_needed(err, flag, err_msg);
   return err;
 }
 
@@ -124,8 +126,9 @@
 }
 
 JVMFlag::Error WriteableFlags::set_int_flag(const char* name, int value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
-  JVMFlag::Error err = JVMFlag::intAtPut(name, &value, origin);
-  print_flag_error_message_if_needed(err, name, err_msg);
+  JVMFlag* flag = JVMFlag::find_flag(name);
+  JVMFlag::Error err = JVMFlag::intAtPut(flag, &value, origin);
+  print_flag_error_message_if_needed(err, flag, err_msg);
   return err;
 }
 
@@ -141,8 +144,9 @@
 }
 
 JVMFlag::Error WriteableFlags::set_uint_flag(const char* name, uint value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
-  JVMFlag::Error err = JVMFlag::uintAtPut(name, &value, origin);
-  print_flag_error_message_if_needed(err, name, err_msg);
+  JVMFlag* flag = JVMFlag::find_flag(name);
+  JVMFlag::Error err = JVMFlag::uintAtPut(flag, &value, origin);
+  print_flag_error_message_if_needed(err, flag, err_msg);
   return err;
 }
 
@@ -158,8 +162,9 @@
 }
 
 JVMFlag::Error WriteableFlags::set_intx_flag(const char* name, intx value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
-  JVMFlag::Error err = JVMFlag::intxAtPut(name, &value, origin);
-  print_flag_error_message_if_needed(err, name, err_msg);
+  JVMFlag* flag = JVMFlag::find_flag(name);
+  JVMFlag::Error err = JVMFlag::intxAtPut(flag, &value, origin);
+  print_flag_error_message_if_needed(err, flag, err_msg);
   return err;
 }
 
@@ -175,8 +180,9 @@
 }
 
 JVMFlag::Error WriteableFlags::set_uintx_flag(const char* name, uintx value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
-  JVMFlag::Error err = JVMFlag::uintxAtPut(name, &value, origin);
-  print_flag_error_message_if_needed(err, name, err_msg);
+  JVMFlag* flag = JVMFlag::find_flag(name);
+  JVMFlag::Error err = JVMFlag::uintxAtPut(flag, &value, origin);
+  print_flag_error_message_if_needed(err, flag, err_msg);
   return err;
 }
 
@@ -192,8 +198,9 @@
 }
 
 JVMFlag::Error WriteableFlags::set_uint64_t_flag(const char* name, uint64_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
-  JVMFlag::Error err = JVMFlag::uint64_tAtPut(name, &value, origin);
-  print_flag_error_message_if_needed(err, name, err_msg);
+  JVMFlag* flag = JVMFlag::find_flag(name);
+  JVMFlag::Error err = JVMFlag::uint64_tAtPut(flag, &value, origin);
+  print_flag_error_message_if_needed(err, flag, err_msg);
   return err;
 }
 
@@ -209,8 +216,9 @@
 }
 
 JVMFlag::Error WriteableFlags::set_size_t_flag(const char* name, size_t value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
-  JVMFlag::Error err = JVMFlag::size_tAtPut(name, &value, origin);
-  print_flag_error_message_if_needed(err, name, err_msg);
+  JVMFlag* flag = JVMFlag::find_flag(name);
+  JVMFlag::Error err = JVMFlag::size_tAtPut(flag, &value, origin);
+  print_flag_error_message_if_needed(err, flag, err_msg);
   return err;
 }
 
@@ -226,15 +234,17 @@
 }
 
 JVMFlag::Error WriteableFlags::set_double_flag(const char* name, double value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
-  JVMFlag::Error err = JVMFlag::doubleAtPut(name, &value, origin);
-  print_flag_error_message_if_needed(err, name, err_msg);
+  JVMFlag* flag = JVMFlag::find_flag(name);
+  JVMFlag::Error err = JVMFlag::doubleAtPut(flag, &value, origin);
+  print_flag_error_message_if_needed(err, flag, err_msg);
   return err;
 }
 
 // set a string global flag using value from AttachOperation
 JVMFlag::Error WriteableFlags::set_ccstr_flag(const char* name, const char* value, JVMFlag::Flags origin, FormatBuffer<80>& err_msg) {
-  JVMFlag::Error err = JVMFlag::ccstrAtPut((char*)name, &value, origin);
-  print_flag_error_message_if_needed(err, name, err_msg);
+  JVMFlag* flag = JVMFlag::find_flag(name);
+  JVMFlag::Error err = JVMFlag::ccstrAtPut(flag, &value, origin);
+  print_flag_error_message_if_needed(err, flag, err_msg);
   return err;
 }
 
@@ -267,7 +277,7 @@
     return JVMFlag::MISSING_VALUE;
   }
 
-  JVMFlag* f = JVMFlag::find_flag((char*)name, strlen(name));
+  JVMFlag* f = JVMFlag::find_flag(name);
   if (f) {
     // only writeable flags are allowed to be set
     if (f->is_writeable()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/utilities/classpathStream.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,44 @@
+/*
+ * 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/allocation.inline.hpp"
+#include "runtime/os.hpp"
+#include "utilities/classpathStream.hpp"
+
+const char* ClasspathStream::get_next() {
+  while (_class_path[_end] != '\0' && _class_path[_end] != os::path_separator()[0]) {
+    _end++;
+  }
+  int path_len = _end - _start;
+  char* path = NEW_RESOURCE_ARRAY(char, path_len + 1);
+  strncpy(path, &_class_path[_start], path_len);
+  path[path_len] = '\0';
+
+  while (_class_path[_end] == os::path_separator()[0]) {
+    _end++;
+  }
+  _start = _end;
+  return path;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/utilities/classpathStream.hpp	Wed Aug 28 11:58:56 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_UTILITIES_CLASSPATHSTREAM_HPP
+#define SHARE_UTILITIES_CLASSPATHSTREAM_HPP
+
+class ClasspathStream : public StackObj {
+  const char* _class_path;
+  int _len;
+  int _start;
+  int _end;
+
+public:
+  ClasspathStream(const char* class_path) {
+    _class_path = class_path;
+    _len = (int)strlen(class_path);
+    _start = 0;
+    _end = 0;
+  }
+
+  bool has_next() {
+    return _start < _len;
+  }
+
+  const char* get_next();
+};
+
+#endif // SHARE_UTILITIES_CLASSPATHSTREAM_HPP
--- a/src/hotspot/share/utilities/globalDefinitions.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/utilities/globalDefinitions.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/os.hpp"
 #include "utilities/globalDefinitions.hpp"
 
--- a/src/hotspot/share/utilities/virtualizationSupport.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/hotspot/share/utilities/virtualizationSupport.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -24,6 +24,7 @@
  */
 
 #include "precompiled.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/os.hpp"
 #include "utilities/virtualizationSupport.hpp"
 
@@ -101,4 +102,3 @@
     }
   }
 }
-
--- a/src/java.base/share/classes/java/io/File.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/io/File.java	Wed Aug 28 11:58:56 2019 -0400
@@ -182,11 +182,13 @@
      * @return true if the file path is invalid.
      */
     final boolean isInvalid() {
-        if (status == null) {
-            status = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
-                                                       : PathStatus.INVALID;
+        PathStatus s = status;
+        if (s == null) {
+            s = (this.path.indexOf('\u0000') < 0) ? PathStatus.CHECKED
+                                                  : PathStatus.INVALID;
+            status = s;
         }
-        return status == PathStatus.INVALID;
+        return s == PathStatus.INVALID;
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/io/Serial.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,101 @@
+/*
+ * 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.  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 java.io;
+
+import java.lang.annotation.*;
+
+/**
+ * Indicates that an annotated field or method is part of the {@linkplain
+ * Serializable serialization mechanism} defined by the
+ * <cite>Java Object Serialization Specification</cite>. This
+ * annotation type is intended to allow compile-time checking of
+ * serialization-related declarations, analogous to the checking
+ * enabled by the {@link java.lang.Override} annotation type to
+ * validate method overriding. {@code Serializable} classes are encouraged to
+ * use <code>&#64;Serial</code> annotations to help a compiler catch
+ * mis-declared serialization-related fields and methods,
+ * mis-declarations that may otherwise be difficult to detect.
+ *
+ * <p>Specifically, annotations of this type should be
+ * applied to serialization-related methods and fields in classes
+ * declared to be {@code Serializable}. The five serialization-related
+ * methods are:
+ *
+ * <ul>
+ * <li>{@code private void writeObject(java.io.ObjectOutputStream stream) throws IOException}
+ * <li>{@code private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException}
+ * <li>{@code private void readObjectNoData() throws ObjectStreamException}
+ * <li><i>ANY-ACCESS-MODIFIER</i> {@code Object writeReplace() throws ObjectStreamException}
+ * <li><i>ANY-ACCESS-MODIFIER</i> {@code Object readResolve() throws ObjectStreamException}
+ * </ul>
+ *
+ * The two serialization-related fields are:
+ *
+ * <ul>
+ * <li>{@code private static final ObjectStreamField[] serialPersistentFields}
+ * <li>{@code private static final long serialVersionUID}
+ * </ul>
+ *
+ * Compilers are encouraged to validate that a method or field marked with a
+ * <code>&#64;Serial</code> annotation is one of the defined serialization-related
+ * methods or fields declared in a meaningful context and issue a warning
+ * if that is not the case.
+ *
+ * <p>It is a semantic error to apply this annotation to other fields or methods, including:
+ * <ul>
+ * <li>fields or methods in a class that is not {@code Serializable}
+ *
+ * <li>fields or methods of the proper structural declaration, but in
+ * a type where they are ineffectual. For example, {@code enum} types
+ * are defined to have a {@code serialVersionUID} of {@code 0L} so a
+ * {@code serialVersionUID} field declared in an {@code enum} type is
+ * ignored. The five serialization-related methods identified above
+ * are likewise ignored for an {@code enum} type.
+ *
+ * <li>in a class that is {@code Externalizable}:
+ * <ul>
+ *   <li> method declarations of {@code writeObject}, {@code
+ *   readObject}, and {@code readObjectNoData}
+ *
+ *  <li>a field declaration for {@code serialPersistentFields}
+ * </ul>
+ *
+ * While the {@code Externalizable} interface extends {@code
+ * Serializable}, the three methods and one field above are
+ * <em>not</em> used for externalizable classes.
+ *
+ * </ul>
+ *
+ * Note that serialization mechanism accesses its designated fields
+ * and methods reflectively and those fields and methods may appear
+ * otherwise unused in a {@code Serializable} class.
+ *
+ * @see Serializable
+ * @see Externalizable
+ */
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Retention(RetentionPolicy.SOURCE)
+public @interface Serial {}
--- a/src/java.base/share/classes/java/lang/Math.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/lang/Math.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2017, 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
@@ -92,12 +92,12 @@
  * The best practice is to choose the primitive type and algorithm to avoid
  * overflow. In cases where the size is {@code int} or {@code long} and
  * overflow errors need to be detected, the methods {@code addExact},
- * {@code subtractExact}, {@code multiplyExact}, and {@code toIntExact}
+ * {@code subtractExact}, {@code multiplyExact}, {@code toIntExact},
+ * {@code incrementExact}, {@code decrementExact} and {@code negateExact}
  * throw an {@code ArithmeticException} when the results overflow.
- * For other arithmetic operations such as divide, absolute value,
- * increment by one, decrement by one, and negation, overflow occurs only with
- * a specific minimum or maximum value and should be checked against
- * the minimum or maximum as appropriate.
+ * For the arithmetic operations divide and absolute value, overflow
+ * occurs only with a specific minimum or maximum value and
+ * should be checked against the minimum or maximum as appropriate.
  *
  * @author  unascribed
  * @author  Joseph D. Darcy
@@ -1058,7 +1058,7 @@
     }
 
     /**
-     * Returns the value of the {@code long} argument;
+     * Returns the value of the {@code long} argument,
      * throwing an exception if the value overflows an {@code int}.
      *
      * @param value the long value
--- a/src/java.base/share/classes/java/lang/StrictMath.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/lang/StrictMath.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, 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
@@ -67,12 +67,12 @@
  * The best practice is to choose the primitive type and algorithm to avoid
  * overflow. In cases where the size is {@code int} or {@code long} and
  * overflow errors need to be detected, the methods {@code addExact},
- * {@code subtractExact}, {@code multiplyExact}, and {@code toIntExact}
+ * {@code subtractExact}, {@code multiplyExact}, {@code toIntExact},
+ * {@code incrementExact}, {@code decrementExact} and {@code negateExact}
  * throw an {@code ArithmeticException} when the results overflow.
- * For other arithmetic operations such as divide, absolute value,
- * increment by one, decrement by one, and negation overflow occurs only with
- * a specific minimum or maximum value and should be checked against
- * the minimum or maximum as appropriate.
+ * For the arithmetic operations divide and absolute value, overflow
+ * occurs only with a specific minimum or maximum value and
+ * should be checked against the minimum or maximum as appropriate.
  *
  * @author  unascribed
  * @author  Joseph D. Darcy
@@ -835,8 +835,92 @@
     }
 
     /**
-     * Returns the value of the {@code long} argument;
-     * throwing an exception if the value overflows an {@code int}.
+     * Returns the argument incremented by one,
+     * throwing an exception if the result overflows an {@code int}.
+     *
+     * @param a the value to increment
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @see Math#incrementExact(int)
+     * @since 14
+     */
+    public static int incrementExact(int a) {
+        return Math.incrementExact(a);
+    }
+
+    /**
+     * Returns the argument incremented by one,
+     * throwing an exception if the result overflows a {@code long}.
+     *
+     * @param a the value to increment
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @see Math#incrementExact(long)
+     * @since 14
+     */
+    public static long incrementExact(long a) {
+        return Math.incrementExact(a);
+    }
+
+    /**
+     * Returns the argument decremented by one,
+     * throwing an exception if the result overflows an {@code int}.
+     *
+     * @param a the value to decrement
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @see Math#decrementExact(int)
+     * @since 14
+     */
+    public static int decrementExact(int a) {
+        return Math.decrementExact(a);
+    }
+
+    /**
+     * Returns the argument decremented by one,
+     * throwing an exception if the result overflows a {@code long}.
+     *
+     * @param a the value to decrement
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @see Math#decrementExact(long)
+     * @since 14
+     */
+    public static long decrementExact(long a) {
+        return Math.decrementExact(a);
+    }
+
+    /**
+     * Returns the negation of the argument,
+     * throwing an exception if the result overflows an {@code int}.
+     *
+     * @param a the value to negate
+     * @return the result
+     * @throws ArithmeticException if the result overflows an int
+     * @see Math#negateExact(int)
+     * @since 14
+     */
+    public static int negateExact(int a) {
+        return Math.negateExact(a);
+    }
+
+    /**
+     * Returns the negation of the argument,
+     * throwing an exception if the result overflows a {@code long}.
+     *
+     * @param a the value to negate
+     * @return the result
+     * @throws ArithmeticException if the result overflows a long
+     * @see Math#negateExact(long)
+     * @since 14
+     */
+    public static long negateExact(long a) {
+        return Math.negateExact(a);
+    }
+
+    /**
+     * Returns the value of the {@code long} argument, throwing an exception
+     * if the value overflows an {@code int}.
      *
      * @param value the long value
      * @return the argument as an int
--- a/src/java.base/share/classes/java/lang/reflect/Method.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/lang/reflect/Method.java	Wed Aug 28 11:58:56 2019 -0400
@@ -420,17 +420,16 @@
 
     @Override
     String toShortString() {
-        StringBuilder sb = new StringBuilder("method ");
-        sb.append(getDeclaringClass().getTypeName()).append('.');
-        sb.append(getName());
-        sb.append('(');
-        StringJoiner sj = new StringJoiner(",");
+        return "method " + getDeclaringClass().getTypeName() +
+                '.' + toShortSignature();
+    }
+
+    String toShortSignature() {
+        StringJoiner sj = new StringJoiner(",", getName() + "(", ")");
         for (Class<?> parameterType : getParameterTypes()) {
             sj.add(parameterType.getTypeName());
         }
-        sb.append(sj);
-        sb.append(')');
-        return sb.toString();
+        return sj.toString();
     }
 
     /**
--- a/src/java.base/share/classes/java/lang/reflect/Proxy.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/lang/reflect/Proxy.java	Wed Aug 28 11:58:56 2019 -0400
@@ -49,6 +49,7 @@
 import jdk.internal.reflect.Reflection;
 import jdk.internal.loader.ClassLoaderValue;
 import sun.reflect.misc.ReflectUtil;
+import sun.security.action.GetBooleanAction;
 import sun.security.action.GetPropertyAction;
 import sun.security.util.SecurityConstants;
 
@@ -99,7 +100,7 @@
  * <li>A proxy class extends {@code java.lang.reflect.Proxy}.
  *
  * <li>A proxy class implements exactly the interfaces specified at its
- * creation, in the same order. Invoking {@link Class#getInterfaces getInterfaces}
+ * creation, in the same order. Invoking {@link Class#getInterfaces() getInterfaces}
  * on its {@code Class} object will return an array containing the same
  * list of interfaces (in the order specified at its creation), invoking
  * {@link Class#getMethods getMethods} on its {@code Class} object will return
@@ -296,6 +297,13 @@
         new ClassLoaderValue<>();
 
     /**
+     * System property to revert to generation of proxy class files for version 1.5 (V49).
+     * Set to "true" to generate v49 class file format.
+     */
+    private static final boolean PROXY_GENERATOR_V49 =
+            GetBooleanAction.privilegedGetProperty("jdk.proxy.ProxyGenerator.v49");
+
+    /**
      * the invocation handler for this proxy instance.
      * @serial
      */
@@ -531,8 +539,9 @@
             /*
              * Generate the specified proxy class.
              */
-            byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
-                    proxyName, interfaces.toArray(EMPTY_CLASS_ARRAY), accessFlags);
+            byte[] proxyClassFile = PROXY_GENERATOR_V49
+                    ? ProxyGenerator_v49.generateProxyClass(proxyName, interfaces, accessFlags)
+                    : ProxyGenerator.generateProxyClass(loader, proxyName, interfaces, accessFlags);
             try {
                 Class<?> pc = JLA.defineClass(loader, proxyName, proxyClassFile,
                                               null, "__dynamic_proxy__");
@@ -1116,6 +1125,5 @@
         return ih;
     }
 
-    private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
     private static final String PROXY_PACKAGE_PREFIX = ReflectUtil.PROXY_PACKAGE;
 }
--- a/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, 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
@@ -25,302 +25,134 @@
 
 package java.lang.reflect;
 
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.File;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.Label;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import sun.security.action.GetBooleanAction;
+
 import java.io.IOException;
-import java.io.OutputStream;
-import java.lang.reflect.Array;
-import java.lang.reflect.Method;
+import java.lang.invoke.MethodType;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Map;
-import sun.security.action.GetBooleanAction;
+
+import static jdk.internal.org.objectweb.asm.Opcodes.*;
 
 /**
  * ProxyGenerator contains the code to generate a dynamic proxy class
  * for the java.lang.reflect.Proxy API.
- *
- * The external interfaces to ProxyGenerator is the static
+ * <p>
+ * The external interface to ProxyGenerator is the static
  * "generateProxyClass" method.
- *
- * @author      Peter Jones
- * @since       1.3
  */
-class ProxyGenerator {
-    /*
-     * In the comments below, "JVMS" refers to The Java Virtual Machine
-     * Specification Second Edition and "JLS" refers to the original
-     * version of The Java Language Specification, unless otherwise
-     * specified.
-     */
-
-    /* generate 1.5-era class file version */
-    private static final int CLASSFILE_MAJOR_VERSION = 49;
-    private static final int CLASSFILE_MINOR_VERSION = 0;
-
-    /*
-     * beginning of constants copied from
-     * sun.tools.java.RuntimeConstants (which no longer exists):
-     */
+final class ProxyGenerator extends ClassWriter {
 
-    /* constant pool tags */
-    private static final int CONSTANT_UTF8              = 1;
-    private static final int CONSTANT_UNICODE           = 2;
-    private static final int CONSTANT_INTEGER           = 3;
-    private static final int CONSTANT_FLOAT             = 4;
-    private static final int CONSTANT_LONG              = 5;
-    private static final int CONSTANT_DOUBLE            = 6;
-    private static final int CONSTANT_CLASS             = 7;
-    private static final int CONSTANT_STRING            = 8;
-    private static final int CONSTANT_FIELD             = 9;
-    private static final int CONSTANT_METHOD            = 10;
-    private static final int CONSTANT_INTERFACEMETHOD   = 11;
-    private static final int CONSTANT_NAMEANDTYPE       = 12;
-
-    /* access and modifier flags */
-    private static final int ACC_PUBLIC                 = 0x00000001;
-    private static final int ACC_PRIVATE                = 0x00000002;
-//  private static final int ACC_PROTECTED              = 0x00000004;
-    private static final int ACC_STATIC                 = 0x00000008;
-    private static final int ACC_FINAL                  = 0x00000010;
-//  private static final int ACC_SYNCHRONIZED           = 0x00000020;
-//  private static final int ACC_VOLATILE               = 0x00000040;
-//  private static final int ACC_TRANSIENT              = 0x00000080;
-//  private static final int ACC_NATIVE                 = 0x00000100;
-//  private static final int ACC_INTERFACE              = 0x00000200;
-//  private static final int ACC_ABSTRACT               = 0x00000400;
-    private static final int ACC_SUPER                  = 0x00000020;
-//  private static final int ACC_STRICT                 = 0x00000800;
+    private static final String JL_CLASS = "java/lang/Class";
+    private static final String JL_OBJECT = "java/lang/Object";
+    private static final String JL_THROWABLE = "java/lang/Throwable";
+    private static final String JL_CLASS_NOT_FOUND_EX = "java/lang/ClassNotFoundException";
+    private static final String JL_NO_CLASS_DEF_FOUND_ERROR = "java/lang/NoClassDefFoundError";
+    private static final String JL_NO_SUCH_METHOD_EX = "java/lang/NoSuchMethodException";
+    private static final String JL_NO_SUCH_METHOD_ERROR = "java/lang/NoSuchMethodError";
 
-    /* opcodes */
-//  private static final int opc_nop                    = 0;
-    private static final int opc_aconst_null            = 1;
-//  private static final int opc_iconst_m1              = 2;
-    private static final int opc_iconst_0               = 3;
-//  private static final int opc_iconst_1               = 4;
-//  private static final int opc_iconst_2               = 5;
-//  private static final int opc_iconst_3               = 6;
-//  private static final int opc_iconst_4               = 7;
-//  private static final int opc_iconst_5               = 8;
-//  private static final int opc_lconst_0               = 9;
-//  private static final int opc_lconst_1               = 10;
-//  private static final int opc_fconst_0               = 11;
-//  private static final int opc_fconst_1               = 12;
-//  private static final int opc_fconst_2               = 13;
-//  private static final int opc_dconst_0               = 14;
-//  private static final int opc_dconst_1               = 15;
-    private static final int opc_bipush                 = 16;
-    private static final int opc_sipush                 = 17;
-    private static final int opc_ldc                    = 18;
-    private static final int opc_ldc_w                  = 19;
-//  private static final int opc_ldc2_w                 = 20;
-    private static final int opc_iload                  = 21;
-    private static final int opc_lload                  = 22;
-    private static final int opc_fload                  = 23;
-    private static final int opc_dload                  = 24;
-    private static final int opc_aload                  = 25;
-    private static final int opc_iload_0                = 26;
-//  private static final int opc_iload_1                = 27;
-//  private static final int opc_iload_2                = 28;
-//  private static final int opc_iload_3                = 29;
-    private static final int opc_lload_0                = 30;
-//  private static final int opc_lload_1                = 31;
-//  private static final int opc_lload_2                = 32;
-//  private static final int opc_lload_3                = 33;
-    private static final int opc_fload_0                = 34;
-//  private static final int opc_fload_1                = 35;
-//  private static final int opc_fload_2                = 36;
-//  private static final int opc_fload_3                = 37;
-    private static final int opc_dload_0                = 38;
-//  private static final int opc_dload_1                = 39;
-//  private static final int opc_dload_2                = 40;
-//  private static final int opc_dload_3                = 41;
-    private static final int opc_aload_0                = 42;
-//  private static final int opc_aload_1                = 43;
-//  private static final int opc_aload_2                = 44;
-//  private static final int opc_aload_3                = 45;
-//  private static final int opc_iaload                 = 46;
-//  private static final int opc_laload                 = 47;
-//  private static final int opc_faload                 = 48;
-//  private static final int opc_daload                 = 49;
-//  private static final int opc_aaload                 = 50;
-//  private static final int opc_baload                 = 51;
-//  private static final int opc_caload                 = 52;
-//  private static final int opc_saload                 = 53;
-//  private static final int opc_istore                 = 54;
-//  private static final int opc_lstore                 = 55;
-//  private static final int opc_fstore                 = 56;
-//  private static final int opc_dstore                 = 57;
-    private static final int opc_astore                 = 58;
-//  private static final int opc_istore_0               = 59;
-//  private static final int opc_istore_1               = 60;
-//  private static final int opc_istore_2               = 61;
-//  private static final int opc_istore_3               = 62;
-//  private static final int opc_lstore_0               = 63;
-//  private static final int opc_lstore_1               = 64;
-//  private static final int opc_lstore_2               = 65;
-//  private static final int opc_lstore_3               = 66;
-//  private static final int opc_fstore_0               = 67;
-//  private static final int opc_fstore_1               = 68;
-//  private static final int opc_fstore_2               = 69;
-//  private static final int opc_fstore_3               = 70;
-//  private static final int opc_dstore_0               = 71;
-//  private static final int opc_dstore_1               = 72;
-//  private static final int opc_dstore_2               = 73;
-//  private static final int opc_dstore_3               = 74;
-    private static final int opc_astore_0               = 75;
-//  private static final int opc_astore_1               = 76;
-//  private static final int opc_astore_2               = 77;
-//  private static final int opc_astore_3               = 78;
-//  private static final int opc_iastore                = 79;
-//  private static final int opc_lastore                = 80;
-//  private static final int opc_fastore                = 81;
-//  private static final int opc_dastore                = 82;
-    private static final int opc_aastore                = 83;
-//  private static final int opc_bastore                = 84;
-//  private static final int opc_castore                = 85;
-//  private static final int opc_sastore                = 86;
-    private static final int opc_pop                    = 87;
-//  private static final int opc_pop2                   = 88;
-    private static final int opc_dup                    = 89;
-//  private static final int opc_dup_x1                 = 90;
-//  private static final int opc_dup_x2                 = 91;
-//  private static final int opc_dup2                   = 92;
-//  private static final int opc_dup2_x1                = 93;
-//  private static final int opc_dup2_x2                = 94;
-//  private static final int opc_swap                   = 95;
-//  private static final int opc_iadd                   = 96;
-//  private static final int opc_ladd                   = 97;
-//  private static final int opc_fadd                   = 98;
-//  private static final int opc_dadd                   = 99;
-//  private static final int opc_isub                   = 100;
-//  private static final int opc_lsub                   = 101;
-//  private static final int opc_fsub                   = 102;
-//  private static final int opc_dsub                   = 103;
-//  private static final int opc_imul                   = 104;
-//  private static final int opc_lmul                   = 105;
-//  private static final int opc_fmul                   = 106;
-//  private static final int opc_dmul                   = 107;
-//  private static final int opc_idiv                   = 108;
-//  private static final int opc_ldiv                   = 109;
-//  private static final int opc_fdiv                   = 110;
-//  private static final int opc_ddiv                   = 111;
-//  private static final int opc_irem                   = 112;
-//  private static final int opc_lrem                   = 113;
-//  private static final int opc_frem                   = 114;
-//  private static final int opc_drem                   = 115;
-//  private static final int opc_ineg                   = 116;
-//  private static final int opc_lneg                   = 117;
-//  private static final int opc_fneg                   = 118;
-//  private static final int opc_dneg                   = 119;
-//  private static final int opc_ishl                   = 120;
-//  private static final int opc_lshl                   = 121;
-//  private static final int opc_ishr                   = 122;
-//  private static final int opc_lshr                   = 123;
-//  private static final int opc_iushr                  = 124;
-//  private static final int opc_lushr                  = 125;
-//  private static final int opc_iand                   = 126;
-//  private static final int opc_land                   = 127;
-//  private static final int opc_ior                    = 128;
-//  private static final int opc_lor                    = 129;
-//  private static final int opc_ixor                   = 130;
-//  private static final int opc_lxor                   = 131;
-//  private static final int opc_iinc                   = 132;
-//  private static final int opc_i2l                    = 133;
-//  private static final int opc_i2f                    = 134;
-//  private static final int opc_i2d                    = 135;
-//  private static final int opc_l2i                    = 136;
-//  private static final int opc_l2f                    = 137;
-//  private static final int opc_l2d                    = 138;
-//  private static final int opc_f2i                    = 139;
-//  private static final int opc_f2l                    = 140;
-//  private static final int opc_f2d                    = 141;
-//  private static final int opc_d2i                    = 142;
-//  private static final int opc_d2l                    = 143;
-//  private static final int opc_d2f                    = 144;
-//  private static final int opc_i2b                    = 145;
-//  private static final int opc_i2c                    = 146;
-//  private static final int opc_i2s                    = 147;
-//  private static final int opc_lcmp                   = 148;
-//  private static final int opc_fcmpl                  = 149;
-//  private static final int opc_fcmpg                  = 150;
-//  private static final int opc_dcmpl                  = 151;
-//  private static final int opc_dcmpg                  = 152;
-//  private static final int opc_ifeq                   = 153;
-//  private static final int opc_ifne                   = 154;
-//  private static final int opc_iflt                   = 155;
-//  private static final int opc_ifge                   = 156;
-//  private static final int opc_ifgt                   = 157;
-//  private static final int opc_ifle                   = 158;
-//  private static final int opc_if_icmpeq              = 159;
-//  private static final int opc_if_icmpne              = 160;
-//  private static final int opc_if_icmplt              = 161;
-//  private static final int opc_if_icmpge              = 162;
-//  private static final int opc_if_icmpgt              = 163;
-//  private static final int opc_if_icmple              = 164;
-//  private static final int opc_if_acmpeq              = 165;
-//  private static final int opc_if_acmpne              = 166;
-//  private static final int opc_goto                   = 167;
-//  private static final int opc_jsr                    = 168;
-//  private static final int opc_ret                    = 169;
-//  private static final int opc_tableswitch            = 170;
-//  private static final int opc_lookupswitch           = 171;
-    private static final int opc_ireturn                = 172;
-    private static final int opc_lreturn                = 173;
-    private static final int opc_freturn                = 174;
-    private static final int opc_dreturn                = 175;
-    private static final int opc_areturn                = 176;
-    private static final int opc_return                 = 177;
-    private static final int opc_getstatic              = 178;
-    private static final int opc_putstatic              = 179;
-    private static final int opc_getfield               = 180;
-//  private static final int opc_putfield               = 181;
-    private static final int opc_invokevirtual          = 182;
-    private static final int opc_invokespecial          = 183;
-    private static final int opc_invokestatic           = 184;
-    private static final int opc_invokeinterface        = 185;
-    private static final int opc_new                    = 187;
-//  private static final int opc_newarray               = 188;
-    private static final int opc_anewarray              = 189;
-//  private static final int opc_arraylength            = 190;
-    private static final int opc_athrow                 = 191;
-    private static final int opc_checkcast              = 192;
-//  private static final int opc_instanceof             = 193;
-//  private static final int opc_monitorenter           = 194;
-//  private static final int opc_monitorexit            = 195;
-    private static final int opc_wide                   = 196;
-//  private static final int opc_multianewarray         = 197;
-//  private static final int opc_ifnull                 = 198;
-//  private static final int opc_ifnonnull              = 199;
-//  private static final int opc_goto_w                 = 200;
-//  private static final int opc_jsr_w                  = 201;
+    private static final String JLR_INVOCATION_HANDLER = "java/lang/reflect/InvocationHandler";
+    private static final String JLR_PROXY = "java/lang/reflect/Proxy";
+    private static final String JLR_UNDECLARED_THROWABLE_EX = "java/lang/reflect/UndeclaredThrowableException";
+
+    private static final String LJL_CLASS = "Ljava/lang/Class;";
+    private static final String LJLR_METHOD = "Ljava/lang/reflect/Method;";
+    private static final String LJLR_INVOCATION_HANDLER = "Ljava/lang/reflect/InvocationHandler;";
 
-    // end of constants copied from sun.tools.java.RuntimeConstants
+    private static final String MJLR_INVOCATIONHANDLER = "(Ljava/lang/reflect/InvocationHandler;)V";
+
+    private static final String NAME_CTOR = "<init>";
+    private static final String NAME_CLINIT = "<clinit>";
 
-    /** name of the superclass of proxy classes */
-    private static final String superclassName = "java/lang/reflect/Proxy";
+    private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
 
-    /** name of field for storing a proxy instance's invocation handler */
+    /**
+     * name of field for storing a proxy instance's invocation handler
+     */
     private static final String handlerFieldName = "h";
 
-    /** debugging flag for saving generated class files */
+    /**
+     * debugging flag for saving generated class files
+     */
     private static final boolean saveGeneratedFiles =
-        java.security.AccessController.doPrivileged(
-            new GetBooleanAction(
-                "jdk.proxy.ProxyGenerator.saveGeneratedFiles")).booleanValue();
+            java.security.AccessController.doPrivileged(
+                    new GetBooleanAction(
+                            "jdk.proxy.ProxyGenerator.saveGeneratedFiles"));
+
+    /* Preloaded ProxyMethod objects for methods in java.lang.Object */
+    private final static ProxyMethod hashCodeMethod;
+    private final static ProxyMethod equalsMethod;
+    private final static ProxyMethod toStringMethod;
+
+    static {
+        try {
+            hashCodeMethod = new ProxyMethod(Object.class.getMethod("hashCode"), "m0");
+            equalsMethod = new ProxyMethod(Object.class.getMethod("equals", Object.class), "m1");
+            toStringMethod = new ProxyMethod(Object.class.getMethod("toString"), "m2");
+        } catch (NoSuchMethodException e) {
+            throw new NoSuchMethodError(e.getMessage());
+        }
+    }
+
+    /**
+     * Class loader
+     */
+    private final ClassLoader loader;
+
+    /**
+     * Name of proxy class
+     */
+    private final String className;
 
     /**
-     * Generate a public proxy class given a name and a list of proxy interfaces.
+     * Proxy interfaces
+     */
+    private final List<Class<?>> interfaces;
+
+    /**
+     * Proxy class access flags
+     */
+    private final int accessFlags;
+
+    /**
+     * Maps method signature string to list of ProxyMethod objects for
+     * proxy methods with that signature.
+     * Kept in insertion order to make it easier to compare old and new.
      */
-    static byte[] generateProxyClass(final String name,
-                                     Class<?>[] interfaces) {
-        return generateProxyClass(name, interfaces, (ACC_PUBLIC | ACC_FINAL | ACC_SUPER));
+    private final Map<String, List<ProxyMethod>> proxyMethods = new LinkedHashMap<>();
+
+    /**
+     * Ordinal of next ProxyMethod object added to proxyMethods.
+     * Indexes are reserved for hashcode(0), equals(1), toString(2).
+     */
+    private int proxyMethodCount = 3;
+
+    /**
+     * Construct a ProxyGenerator to generate a proxy class with the
+     * specified name and for the given interfaces.
+     * <p>
+     * A ProxyGenerator object contains the state for the ongoing
+     * generation of a particular proxy class.
+     */
+    private ProxyGenerator(ClassLoader loader, String className, List<Class<?>> interfaces,
+                           int accessFlags) {
+        super(ClassWriter.COMPUTE_FRAMES);
+        this.loader = loader;
+        this.className = className;
+        this.interfaces = interfaces;
+        this.accessFlags = accessFlags;
     }
 
     /**
@@ -329,295 +161,55 @@
      * @param name        the class name of the proxy class
      * @param interfaces  proxy interfaces
      * @param accessFlags access flags of the proxy class
-    */
-    static byte[] generateProxyClass(final String name,
-                                     Class<?>[] interfaces,
-                                     int accessFlags)
-    {
-        ProxyGenerator gen = new ProxyGenerator(name, interfaces, accessFlags);
+     */
+    static byte[] generateProxyClass(ClassLoader loader,
+                                     final String name,
+                                     List<Class<?>> interfaces,
+                                     int accessFlags) {
+        ProxyGenerator gen = new ProxyGenerator(loader, name, interfaces, accessFlags);
         final byte[] classFile = gen.generateClassFile();
 
         if (saveGeneratedFiles) {
             java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction<Void>() {
-                public Void run() {
-                    try {
-                        int i = name.lastIndexOf('.');
-                        Path path;
-                        if (i > 0) {
-                            Path dir = Path.of(name.substring(0, i).replace('.', File.separatorChar));
-                            Files.createDirectories(dir);
-                            path = dir.resolve(name.substring(i+1, name.length()) + ".class");
-                        } else {
-                            path = Path.of(name + ".class");
+                    new java.security.PrivilegedAction<Void>() {
+                        public Void run() {
+                            try {
+                                int i = name.lastIndexOf('.');
+                                Path path;
+                                if (i > 0) {
+                                    Path dir = Path.of(dotToSlash(name.substring(0, i)));
+                                    Files.createDirectories(dir);
+                                    path = dir.resolve(name.substring(i + 1) + ".class");
+                                } else {
+                                    path = Path.of(name + ".class");
+                                }
+                                Files.write(path, classFile);
+                                return null;
+                            } catch (IOException e) {
+                                throw new InternalError(
+                                        "I/O exception saving generated file: " + e);
+                            }
                         }
-                        Files.write(path, classFile);
-                        return null;
-                    } catch (IOException e) {
-                        throw new InternalError(
-                            "I/O exception saving generated file: " + e);
-                    }
-                }
-            });
+                    });
         }
 
         return classFile;
     }
 
-    /* preloaded Method objects for methods in java.lang.Object */
-    private static Method hashCodeMethod;
-    private static Method equalsMethod;
-    private static Method toStringMethod;
-    static {
-        try {
-            hashCodeMethod = Object.class.getMethod("hashCode");
-            equalsMethod =
-                Object.class.getMethod("equals", new Class<?>[] { Object.class });
-            toStringMethod = Object.class.getMethod("toString");
-        } catch (NoSuchMethodException e) {
-            throw new NoSuchMethodError(e.getMessage());
-        }
-    }
-
-    /** name of proxy class */
-    private String className;
-
-    /** proxy interfaces */
-    private Class<?>[] interfaces;
-
-    /** proxy class access flags */
-    private int accessFlags;
-
-    /** constant pool of class being generated */
-    private ConstantPool cp = new ConstantPool();
-
-    /** FieldInfo struct for each field of generated class */
-    private List<FieldInfo> fields = new ArrayList<>();
-
-    /** MethodInfo struct for each method of generated class */
-    private List<MethodInfo> methods = new ArrayList<>();
-
     /**
-     * maps method signature string to list of ProxyMethod objects for
-     * proxy methods with that signature
-     */
-    private Map<String, List<ProxyMethod>> proxyMethods = new HashMap<>();
-
-    /** count of ProxyMethod objects added to proxyMethods */
-    private int proxyMethodCount = 0;
-
-    /**
-     * Construct a ProxyGenerator to generate a proxy class with the
-     * specified name and for the given interfaces.
+     * Return an array of the type names from an array of Classes.
      *
-     * A ProxyGenerator object contains the state for the ongoing
-     * generation of a particular proxy class.
-     */
-    private ProxyGenerator(String className, Class<?>[] interfaces, int accessFlags) {
-        this.className = className;
-        this.interfaces = interfaces;
-        this.accessFlags = accessFlags;
-    }
-
-    /**
-     * Generate a class file for the proxy class.  This method drives the
-     * class file generation process.
+     * @param classes an array of classes or interfaces
+     * @return the array of class names; or null if there are no classes
      */
-    private byte[] generateClassFile() {
-
-        /* ============================================================
-         * Step 1: Assemble ProxyMethod objects for all methods to
-         * generate proxy dispatching code for.
-         */
-
-        /*
-         * Record that proxy methods are needed for the hashCode, equals,
-         * and toString methods of java.lang.Object.  This is done before
-         * the methods from the proxy interfaces so that the methods from
-         * java.lang.Object take precedence over duplicate methods in the
-         * proxy interfaces.
-         */
-        addProxyMethod(hashCodeMethod, Object.class);
-        addProxyMethod(equalsMethod, Object.class);
-        addProxyMethod(toStringMethod, Object.class);
-
-        /*
-         * Now record all of the methods from the proxy interfaces, giving
-         * earlier interfaces precedence over later ones with duplicate
-         * methods.
-         */
-        for (Class<?> intf : interfaces) {
-            for (Method m : intf.getMethods()) {
-                if (!Modifier.isStatic(m.getModifiers())) {
-                    addProxyMethod(m, intf);
-                }
-            }
-        }
-
-        /*
-         * For each set of proxy methods with the same signature,
-         * verify that the methods' return types are compatible.
-         */
-        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
-            checkReturnTypes(sigmethods);
-        }
-
-        /* ============================================================
-         * Step 2: Assemble FieldInfo and MethodInfo structs for all of
-         * fields and methods in the class we are generating.
-         */
-        try {
-            methods.add(generateConstructor());
-
-            for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
-                for (ProxyMethod pm : sigmethods) {
-
-                    // add static field for method's Method object
-                    fields.add(new FieldInfo(pm.methodFieldName,
-                        "Ljava/lang/reflect/Method;",
-                         ACC_PRIVATE | ACC_STATIC));
-
-                    // generate code for proxy method and add it
-                    methods.add(pm.generateMethod());
-                }
-            }
-
-            methods.add(generateStaticInitializer());
-
-        } catch (IOException e) {
-            throw new InternalError("unexpected I/O Exception", e);
-        }
-
-        if (methods.size() > 65535) {
-            throw new IllegalArgumentException("method limit exceeded");
-        }
-        if (fields.size() > 65535) {
-            throw new IllegalArgumentException("field limit exceeded");
-        }
-
-        /* ============================================================
-         * Step 3: Write the final class file.
-         */
-
-        /*
-         * Make sure that constant pool indexes are reserved for the
-         * following items before starting to write the final class file.
-         */
-        cp.getClass(dotToSlash(className));
-        cp.getClass(superclassName);
-        for (Class<?> intf: interfaces) {
-            cp.getClass(dotToSlash(intf.getName()));
-        }
-
-        /*
-         * Disallow new constant pool additions beyond this point, since
-         * we are about to write the final constant pool table.
-         */
-        cp.setReadOnly();
-
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-        DataOutputStream dout = new DataOutputStream(bout);
-
-        try {
-            /*
-             * Write all the items of the "ClassFile" structure.
-             * See JVMS section 4.1.
-             */
-                                        // u4 magic;
-            dout.writeInt(0xCAFEBABE);
-                                        // u2 minor_version;
-            dout.writeShort(CLASSFILE_MINOR_VERSION);
-                                        // u2 major_version;
-            dout.writeShort(CLASSFILE_MAJOR_VERSION);
-
-            cp.write(dout);             // (write constant pool)
-
-                                        // u2 access_flags;
-            dout.writeShort(accessFlags);
-                                        // u2 this_class;
-            dout.writeShort(cp.getClass(dotToSlash(className)));
-                                        // u2 super_class;
-            dout.writeShort(cp.getClass(superclassName));
-
-                                        // u2 interfaces_count;
-            dout.writeShort(interfaces.length);
-                                        // u2 interfaces[interfaces_count];
-            for (Class<?> intf : interfaces) {
-                dout.writeShort(cp.getClass(
-                    dotToSlash(intf.getName())));
-            }
-
-                                        // u2 fields_count;
-            dout.writeShort(fields.size());
-                                        // field_info fields[fields_count];
-            for (FieldInfo f : fields) {
-                f.write(dout);
-            }
-
-                                        // u2 methods_count;
-            dout.writeShort(methods.size());
-                                        // method_info methods[methods_count];
-            for (MethodInfo m : methods) {
-                m.write(dout);
-            }
-
-                                         // u2 attributes_count;
-            dout.writeShort(0); // (no ClassFile attributes for proxy classes)
-
-        } catch (IOException e) {
-            throw new InternalError("unexpected I/O Exception", e);
-        }
-
-        return bout.toByteArray();
-    }
-
-    /**
-     * Add another method to be proxied, either by creating a new
-     * ProxyMethod object or augmenting an old one for a duplicate
-     * method.
-     *
-     * "fromClass" indicates the proxy interface that the method was
-     * found through, which may be different from (a subinterface of)
-     * the method's "declaring class".  Note that the first Method
-     * object passed for a given name and descriptor identifies the
-     * Method object (and thus the declaring class) that will be
-     * passed to the invocation handler's "invoke" method for a given
-     * set of duplicate methods.
-     */
-    private void addProxyMethod(Method m, Class<?> fromClass) {
-        String name = m.getName();
-        Class<?>[] parameterTypes = m.getParameterTypes();
-        Class<?> returnType = m.getReturnType();
-        Class<?>[] exceptionTypes = m.getExceptionTypes();
-
-        String sig = name + getParameterDescriptors(parameterTypes);
-        List<ProxyMethod> sigmethods = proxyMethods.get(sig);
-        if (sigmethods != null) {
-            for (ProxyMethod pm : sigmethods) {
-                if (returnType == pm.returnType) {
-                    /*
-                     * Found a match: reduce exception types to the
-                     * greatest set of exceptions that can thrown
-                     * compatibly with the throws clauses of both
-                     * overridden methods.
-                     */
-                    List<Class<?>> legalExceptions = new ArrayList<>();
-                    collectCompatibleTypes(
-                        exceptionTypes, pm.exceptionTypes, legalExceptions);
-                    collectCompatibleTypes(
-                        pm.exceptionTypes, exceptionTypes, legalExceptions);
-                    pm.exceptionTypes = new Class<?>[legalExceptions.size()];
-                    pm.exceptionTypes =
-                        legalExceptions.toArray(pm.exceptionTypes);
-                    return;
-                }
-            }
-        } else {
-            sigmethods = new ArrayList<>(3);
-            proxyMethods.put(sig, sigmethods);
-        }
-        sigmethods.add(new ProxyMethod(name, parameterTypes, returnType,
-                                       exceptionTypes, fromClass));
+    private static String[] typeNames(List<Class<?>> classes) {
+        if (classes == null || classes.size() == 0)
+            return null;
+        int size = classes.size();
+        String[] ifaces = new String[size];
+        for (int i = 0; i < size; i++)
+            ifaces[i] = dotToSlash(classes.get(i).getName());
+        return ifaces;
     }
 
     /**
@@ -645,16 +237,15 @@
          */
         LinkedList<Class<?>> uncoveredReturnTypes = new LinkedList<>();
 
-    nextNewReturnType:
+        nextNewReturnType:
         for (ProxyMethod pm : methods) {
             Class<?> newReturnType = pm.returnType;
             if (newReturnType.isPrimitive()) {
                 throw new IllegalArgumentException(
-                    "methods with same signature " +
-                    getFriendlyMethodSignature(pm.methodName,
-                                               pm.parameterTypes) +
-                    " but incompatible return types: " +
-                    newReturnType.getName() + " and others");
+                        "methods with same signature " +
+                                pm.shortSignature +
+                                " but incompatible return types: " +
+                                newReturnType.getName() + " and others");
             }
             boolean added = false;
 
@@ -709,856 +300,9 @@
         if (uncoveredReturnTypes.size() > 1) {
             ProxyMethod pm = methods.get(0);
             throw new IllegalArgumentException(
-                "methods with same signature " +
-                getFriendlyMethodSignature(pm.methodName, pm.parameterTypes) +
-                " but incompatible return types: " + uncoveredReturnTypes);
-        }
-    }
-
-    /**
-     * A FieldInfo object contains information about a particular field
-     * in the class being generated.  The class mirrors the data items of
-     * the "field_info" structure of the class file format (see JVMS 4.5).
-     */
-    private class FieldInfo {
-        public int accessFlags;
-        public String name;
-        public String descriptor;
-
-        public FieldInfo(String name, String descriptor, int accessFlags) {
-            this.name = name;
-            this.descriptor = descriptor;
-            this.accessFlags = accessFlags;
-
-            /*
-             * Make sure that constant pool indexes are reserved for the
-             * following items before starting to write the final class file.
-             */
-            cp.getUtf8(name);
-            cp.getUtf8(descriptor);
-        }
-
-        public void write(DataOutputStream out) throws IOException {
-            /*
-             * Write all the items of the "field_info" structure.
-             * See JVMS section 4.5.
-             */
-                                        // u2 access_flags;
-            out.writeShort(accessFlags);
-                                        // u2 name_index;
-            out.writeShort(cp.getUtf8(name));
-                                        // u2 descriptor_index;
-            out.writeShort(cp.getUtf8(descriptor));
-                                        // u2 attributes_count;
-            out.writeShort(0);  // (no field_info attributes for proxy classes)
-        }
-    }
-
-    /**
-     * An ExceptionTableEntry object holds values for the data items of
-     * an entry in the "exception_table" item of the "Code" attribute of
-     * "method_info" structures (see JVMS 4.7.3).
-     */
-    private static class ExceptionTableEntry {
-        public short startPc;
-        public short endPc;
-        public short handlerPc;
-        public short catchType;
-
-        public ExceptionTableEntry(short startPc, short endPc,
-                                   short handlerPc, short catchType)
-        {
-            this.startPc = startPc;
-            this.endPc = endPc;
-            this.handlerPc = handlerPc;
-            this.catchType = catchType;
-        }
-    };
-
-    /**
-     * A MethodInfo object contains information about a particular method
-     * in the class being generated.  This class mirrors the data items of
-     * the "method_info" structure of the class file format (see JVMS 4.6).
-     */
-    private class MethodInfo {
-        public int accessFlags;
-        public String name;
-        public String descriptor;
-        public short maxStack;
-        public short maxLocals;
-        public ByteArrayOutputStream code = new ByteArrayOutputStream();
-        public List<ExceptionTableEntry> exceptionTable =
-            new ArrayList<ExceptionTableEntry>();
-        public short[] declaredExceptions;
-
-        public MethodInfo(String name, String descriptor, int accessFlags) {
-            this.name = name;
-            this.descriptor = descriptor;
-            this.accessFlags = accessFlags;
-
-            /*
-             * Make sure that constant pool indexes are reserved for the
-             * following items before starting to write the final class file.
-             */
-            cp.getUtf8(name);
-            cp.getUtf8(descriptor);
-            cp.getUtf8("Code");
-            cp.getUtf8("Exceptions");
-        }
-
-        public void write(DataOutputStream out) throws IOException {
-            /*
-             * Write all the items of the "method_info" structure.
-             * See JVMS section 4.6.
-             */
-                                        // u2 access_flags;
-            out.writeShort(accessFlags);
-                                        // u2 name_index;
-            out.writeShort(cp.getUtf8(name));
-                                        // u2 descriptor_index;
-            out.writeShort(cp.getUtf8(descriptor));
-                                        // u2 attributes_count;
-            out.writeShort(2);  // (two method_info attributes:)
-
-            // Write "Code" attribute. See JVMS section 4.7.3.
-
-                                        // u2 attribute_name_index;
-            out.writeShort(cp.getUtf8("Code"));
-                                        // u4 attribute_length;
-            out.writeInt(12 + code.size() + 8 * exceptionTable.size());
-                                        // u2 max_stack;
-            out.writeShort(maxStack);
-                                        // u2 max_locals;
-            out.writeShort(maxLocals);
-                                        // u2 code_length;
-            out.writeInt(code.size());
-                                        // u1 code[code_length];
-            code.writeTo(out);
-                                        // u2 exception_table_length;
-            out.writeShort(exceptionTable.size());
-            for (ExceptionTableEntry e : exceptionTable) {
-                                        // u2 start_pc;
-                out.writeShort(e.startPc);
-                                        // u2 end_pc;
-                out.writeShort(e.endPc);
-                                        // u2 handler_pc;
-                out.writeShort(e.handlerPc);
-                                        // u2 catch_type;
-                out.writeShort(e.catchType);
-            }
-                                        // u2 attributes_count;
-            out.writeShort(0);
-
-            // write "Exceptions" attribute.  See JVMS section 4.7.4.
-
-                                        // u2 attribute_name_index;
-            out.writeShort(cp.getUtf8("Exceptions"));
-                                        // u4 attributes_length;
-            out.writeInt(2 + 2 * declaredExceptions.length);
-                                        // u2 number_of_exceptions;
-            out.writeShort(declaredExceptions.length);
-                        // u2 exception_index_table[number_of_exceptions];
-            for (short value : declaredExceptions) {
-                out.writeShort(value);
-            }
-        }
-
-    }
-
-    /**
-     * A ProxyMethod object represents a proxy method in the proxy class
-     * being generated: a method whose implementation will encode and
-     * dispatch invocations to the proxy instance's invocation handler.
-     */
-    private class ProxyMethod {
-
-        public String methodName;
-        public Class<?>[] parameterTypes;
-        public Class<?> returnType;
-        public Class<?>[] exceptionTypes;
-        public Class<?> fromClass;
-        public String methodFieldName;
-
-        private ProxyMethod(String methodName, Class<?>[] parameterTypes,
-                            Class<?> returnType, Class<?>[] exceptionTypes,
-                            Class<?> fromClass)
-        {
-            this.methodName = methodName;
-            this.parameterTypes = parameterTypes;
-            this.returnType = returnType;
-            this.exceptionTypes = exceptionTypes;
-            this.fromClass = fromClass;
-            this.methodFieldName = "m" + proxyMethodCount++;
-        }
-
-        /**
-         * Return a MethodInfo object for this method, including generating
-         * the code and exception table entry.
-         */
-        private MethodInfo generateMethod() throws IOException {
-            String desc = getMethodDescriptor(parameterTypes, returnType);
-            MethodInfo minfo = new MethodInfo(methodName, desc,
-                ACC_PUBLIC | ACC_FINAL);
-
-            int[] parameterSlot = new int[parameterTypes.length];
-            int nextSlot = 1;
-            for (int i = 0; i < parameterSlot.length; i++) {
-                parameterSlot[i] = nextSlot;
-                nextSlot += getWordsPerType(parameterTypes[i]);
-            }
-            int localSlot0 = nextSlot;
-            short pc, tryBegin = 0, tryEnd;
-
-            DataOutputStream out = new DataOutputStream(minfo.code);
-
-            code_aload(0, out);
-
-            out.writeByte(opc_getfield);
-            out.writeShort(cp.getFieldRef(
-                superclassName,
-                handlerFieldName, "Ljava/lang/reflect/InvocationHandler;"));
-
-            code_aload(0, out);
-
-            out.writeByte(opc_getstatic);
-            out.writeShort(cp.getFieldRef(
-                dotToSlash(className),
-                methodFieldName, "Ljava/lang/reflect/Method;"));
-
-            if (parameterTypes.length > 0) {
-
-                code_ipush(parameterTypes.length, out);
-
-                out.writeByte(opc_anewarray);
-                out.writeShort(cp.getClass("java/lang/Object"));
-
-                for (int i = 0; i < parameterTypes.length; i++) {
-
-                    out.writeByte(opc_dup);
-
-                    code_ipush(i, out);
-
-                    codeWrapArgument(parameterTypes[i], parameterSlot[i], out);
-
-                    out.writeByte(opc_aastore);
-                }
-            } else {
-
-                out.writeByte(opc_aconst_null);
-            }
-
-            out.writeByte(opc_invokeinterface);
-            out.writeShort(cp.getInterfaceMethodRef(
-                "java/lang/reflect/InvocationHandler",
-                "invoke",
-                "(Ljava/lang/Object;Ljava/lang/reflect/Method;" +
-                    "[Ljava/lang/Object;)Ljava/lang/Object;"));
-            out.writeByte(4);
-            out.writeByte(0);
-
-            if (returnType == void.class) {
-
-                out.writeByte(opc_pop);
-
-                out.writeByte(opc_return);
-
-            } else {
-
-                codeUnwrapReturnValue(returnType, out);
-            }
-
-            tryEnd = pc = (short) minfo.code.size();
-
-            List<Class<?>> catchList = computeUniqueCatchList(exceptionTypes);
-            if (catchList.size() > 0) {
-
-                for (Class<?> ex : catchList) {
-                    minfo.exceptionTable.add(new ExceptionTableEntry(
-                        tryBegin, tryEnd, pc,
-                        cp.getClass(dotToSlash(ex.getName()))));
-                }
-
-                out.writeByte(opc_athrow);
-
-                pc = (short) minfo.code.size();
-
-                minfo.exceptionTable.add(new ExceptionTableEntry(
-                    tryBegin, tryEnd, pc, cp.getClass("java/lang/Throwable")));
-
-                code_astore(localSlot0, out);
-
-                out.writeByte(opc_new);
-                out.writeShort(cp.getClass(
-                    "java/lang/reflect/UndeclaredThrowableException"));
-
-                out.writeByte(opc_dup);
-
-                code_aload(localSlot0, out);
-
-                out.writeByte(opc_invokespecial);
-
-                out.writeShort(cp.getMethodRef(
-                    "java/lang/reflect/UndeclaredThrowableException",
-                    "<init>", "(Ljava/lang/Throwable;)V"));
-
-                out.writeByte(opc_athrow);
-            }
-
-            if (minfo.code.size() > 65535) {
-                throw new IllegalArgumentException("code size limit exceeded");
-            }
-
-            minfo.maxStack = 10;
-            minfo.maxLocals = (short) (localSlot0 + 1);
-            minfo.declaredExceptions = new short[exceptionTypes.length];
-            for (int i = 0; i < exceptionTypes.length; i++) {
-                minfo.declaredExceptions[i] = cp.getClass(
-                    dotToSlash(exceptionTypes[i].getName()));
-            }
-
-            return minfo;
-        }
-
-        /**
-         * Generate code for wrapping an argument of the given type
-         * whose value can be found at the specified local variable
-         * index, in order for it to be passed (as an Object) to the
-         * invocation handler's "invoke" method.  The code is written
-         * to the supplied stream.
-         */
-        private void codeWrapArgument(Class<?> type, int slot,
-                                      DataOutputStream out)
-            throws IOException
-        {
-            if (type.isPrimitive()) {
-                PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
-
-                if (type == int.class ||
-                    type == boolean.class ||
-                    type == byte.class ||
-                    type == char.class ||
-                    type == short.class)
-                {
-                    code_iload(slot, out);
-                } else if (type == long.class) {
-                    code_lload(slot, out);
-                } else if (type == float.class) {
-                    code_fload(slot, out);
-                } else if (type == double.class) {
-                    code_dload(slot, out);
-                } else {
-                    throw new AssertionError();
-                }
-
-                out.writeByte(opc_invokestatic);
-                out.writeShort(cp.getMethodRef(
-                    prim.wrapperClassName,
-                    "valueOf", prim.wrapperValueOfDesc));
-
-            } else {
-
-                code_aload(slot, out);
-            }
-        }
-
-        /**
-         * Generate code for unwrapping a return value of the given
-         * type from the invocation handler's "invoke" method (as type
-         * Object) to its correct type.  The code is written to the
-         * supplied stream.
-         */
-        private void codeUnwrapReturnValue(Class<?> type, DataOutputStream out)
-            throws IOException
-        {
-            if (type.isPrimitive()) {
-                PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
-
-                out.writeByte(opc_checkcast);
-                out.writeShort(cp.getClass(prim.wrapperClassName));
-
-                out.writeByte(opc_invokevirtual);
-                out.writeShort(cp.getMethodRef(
-                    prim.wrapperClassName,
-                    prim.unwrapMethodName, prim.unwrapMethodDesc));
-
-                if (type == int.class ||
-                    type == boolean.class ||
-                    type == byte.class ||
-                    type == char.class ||
-                    type == short.class)
-                {
-                    out.writeByte(opc_ireturn);
-                } else if (type == long.class) {
-                    out.writeByte(opc_lreturn);
-                } else if (type == float.class) {
-                    out.writeByte(opc_freturn);
-                } else if (type == double.class) {
-                    out.writeByte(opc_dreturn);
-                } else {
-                    throw new AssertionError();
-                }
-
-            } else {
-
-                out.writeByte(opc_checkcast);
-                out.writeShort(cp.getClass(dotToSlash(type.getName())));
-
-                out.writeByte(opc_areturn);
-            }
-        }
-
-        /**
-         * Generate code for initializing the static field that stores
-         * the Method object for this proxy method.  The code is written
-         * to the supplied stream.
-         */
-        private void codeFieldInitialization(DataOutputStream out)
-            throws IOException
-        {
-            codeClassForName(fromClass, out);
-
-            code_ldc(cp.getString(methodName), out);
-
-            code_ipush(parameterTypes.length, out);
-
-            out.writeByte(opc_anewarray);
-            out.writeShort(cp.getClass("java/lang/Class"));
-
-            for (int i = 0; i < parameterTypes.length; i++) {
-
-                out.writeByte(opc_dup);
-
-                code_ipush(i, out);
-
-                if (parameterTypes[i].isPrimitive()) {
-                    PrimitiveTypeInfo prim =
-                        PrimitiveTypeInfo.get(parameterTypes[i]);
-
-                    out.writeByte(opc_getstatic);
-                    out.writeShort(cp.getFieldRef(
-                        prim.wrapperClassName, "TYPE", "Ljava/lang/Class;"));
-
-                } else {
-                    codeClassForName(parameterTypes[i], out);
-                }
-
-                out.writeByte(opc_aastore);
-            }
-
-            out.writeByte(opc_invokevirtual);
-            out.writeShort(cp.getMethodRef(
-                "java/lang/Class",
-                "getMethod",
-                "(Ljava/lang/String;[Ljava/lang/Class;)" +
-                "Ljava/lang/reflect/Method;"));
-
-            out.writeByte(opc_putstatic);
-            out.writeShort(cp.getFieldRef(
-                dotToSlash(className),
-                methodFieldName, "Ljava/lang/reflect/Method;"));
-        }
-    }
-
-    /**
-     * Generate the constructor method for the proxy class.
-     */
-    private MethodInfo generateConstructor() throws IOException {
-        MethodInfo minfo = new MethodInfo(
-            "<init>", "(Ljava/lang/reflect/InvocationHandler;)V",
-            ACC_PUBLIC);
-
-        DataOutputStream out = new DataOutputStream(minfo.code);
-
-        code_aload(0, out);
-
-        code_aload(1, out);
-
-        out.writeByte(opc_invokespecial);
-        out.writeShort(cp.getMethodRef(
-            superclassName,
-            "<init>", "(Ljava/lang/reflect/InvocationHandler;)V"));
-
-        out.writeByte(opc_return);
-
-        minfo.maxStack = 10;
-        minfo.maxLocals = 2;
-        minfo.declaredExceptions = new short[0];
-
-        return minfo;
-    }
-
-    /**
-     * Generate the static initializer method for the proxy class.
-     */
-    private MethodInfo generateStaticInitializer() throws IOException {
-        MethodInfo minfo = new MethodInfo(
-            "<clinit>", "()V", ACC_STATIC);
-
-        int localSlot0 = 1;
-        short pc, tryBegin = 0, tryEnd;
-
-        DataOutputStream out = new DataOutputStream(minfo.code);
-
-        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
-            for (ProxyMethod pm : sigmethods) {
-                pm.codeFieldInitialization(out);
-            }
-        }
-
-        out.writeByte(opc_return);
-
-        tryEnd = pc = (short) minfo.code.size();
-
-        minfo.exceptionTable.add(new ExceptionTableEntry(
-            tryBegin, tryEnd, pc,
-            cp.getClass("java/lang/NoSuchMethodException")));
-
-        code_astore(localSlot0, out);
-
-        out.writeByte(opc_new);
-        out.writeShort(cp.getClass("java/lang/NoSuchMethodError"));
-
-        out.writeByte(opc_dup);
-
-        code_aload(localSlot0, out);
-
-        out.writeByte(opc_invokevirtual);
-        out.writeShort(cp.getMethodRef(
-            "java/lang/Throwable", "getMessage", "()Ljava/lang/String;"));
-
-        out.writeByte(opc_invokespecial);
-        out.writeShort(cp.getMethodRef(
-            "java/lang/NoSuchMethodError", "<init>", "(Ljava/lang/String;)V"));
-
-        out.writeByte(opc_athrow);
-
-        pc = (short) minfo.code.size();
-
-        minfo.exceptionTable.add(new ExceptionTableEntry(
-            tryBegin, tryEnd, pc,
-            cp.getClass("java/lang/ClassNotFoundException")));
-
-        code_astore(localSlot0, out);
-
-        out.writeByte(opc_new);
-        out.writeShort(cp.getClass("java/lang/NoClassDefFoundError"));
-
-        out.writeByte(opc_dup);
-
-        code_aload(localSlot0, out);
-
-        out.writeByte(opc_invokevirtual);
-        out.writeShort(cp.getMethodRef(
-            "java/lang/Throwable", "getMessage", "()Ljava/lang/String;"));
-
-        out.writeByte(opc_invokespecial);
-        out.writeShort(cp.getMethodRef(
-            "java/lang/NoClassDefFoundError",
-            "<init>", "(Ljava/lang/String;)V"));
-
-        out.writeByte(opc_athrow);
-
-        if (minfo.code.size() > 65535) {
-            throw new IllegalArgumentException("code size limit exceeded");
-        }
-
-        minfo.maxStack = 10;
-        minfo.maxLocals = (short) (localSlot0 + 1);
-        minfo.declaredExceptions = new short[0];
-
-        return minfo;
-    }
-
-
-    /*
-     * =============== Code Generation Utility Methods ===============
-     */
-
-    /*
-     * The following methods generate code for the load or store operation
-     * indicated by their name for the given local variable.  The code is
-     * written to the supplied stream.
-     */
-
-    private void code_iload(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_iload, opc_iload_0, out);
-    }
-
-    private void code_lload(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_lload, opc_lload_0, out);
-    }
-
-    private void code_fload(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_fload, opc_fload_0, out);
-    }
-
-    private void code_dload(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_dload, opc_dload_0, out);
-    }
-
-    private void code_aload(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_aload, opc_aload_0, out);
-    }
-
-//  private void code_istore(int lvar, DataOutputStream out)
-//      throws IOException
-//  {
-//      codeLocalLoadStore(lvar, opc_istore, opc_istore_0, out);
-//  }
-
-//  private void code_lstore(int lvar, DataOutputStream out)
-//      throws IOException
-//  {
-//      codeLocalLoadStore(lvar, opc_lstore, opc_lstore_0, out);
-//  }
-
-//  private void code_fstore(int lvar, DataOutputStream out)
-//      throws IOException
-//  {
-//      codeLocalLoadStore(lvar, opc_fstore, opc_fstore_0, out);
-//  }
-
-//  private void code_dstore(int lvar, DataOutputStream out)
-//      throws IOException
-//  {
-//      codeLocalLoadStore(lvar, opc_dstore, opc_dstore_0, out);
-//  }
-
-    private void code_astore(int lvar, DataOutputStream out)
-        throws IOException
-    {
-        codeLocalLoadStore(lvar, opc_astore, opc_astore_0, out);
-    }
-
-    /**
-     * Generate code for a load or store instruction for the given local
-     * variable.  The code is written to the supplied stream.
-     *
-     * "opcode" indicates the opcode form of the desired load or store
-     * instruction that takes an explicit local variable index, and
-     * "opcode_0" indicates the corresponding form of the instruction
-     * with the implicit index 0.
-     */
-    private void codeLocalLoadStore(int lvar, int opcode, int opcode_0,
-                                    DataOutputStream out)
-        throws IOException
-    {
-        assert lvar >= 0 && lvar <= 0xFFFF;
-        if (lvar <= 3) {
-            out.writeByte(opcode_0 + lvar);
-        } else if (lvar <= 0xFF) {
-            out.writeByte(opcode);
-            out.writeByte(lvar & 0xFF);
-        } else {
-            /*
-             * Use the "wide" instruction modifier for local variable
-             * indexes that do not fit into an unsigned byte.
-             */
-            out.writeByte(opc_wide);
-            out.writeByte(opcode);
-            out.writeShort(lvar & 0xFFFF);
-        }
-    }
-
-    /**
-     * Generate code for an "ldc" instruction for the given constant pool
-     * index (the "ldc_w" instruction is used if the index does not fit
-     * into an unsigned byte).  The code is written to the supplied stream.
-     */
-    private void code_ldc(int index, DataOutputStream out)
-        throws IOException
-    {
-        assert index >= 0 && index <= 0xFFFF;
-        if (index <= 0xFF) {
-            out.writeByte(opc_ldc);
-            out.writeByte(index & 0xFF);
-        } else {
-            out.writeByte(opc_ldc_w);
-            out.writeShort(index & 0xFFFF);
-        }
-    }
-
-    /**
-     * Generate code to push a constant integer value on to the operand
-     * stack, using the "iconst_<i>", "bipush", or "sipush" instructions
-     * depending on the size of the value.  The code is written to the
-     * supplied stream.
-     */
-    private void code_ipush(int value, DataOutputStream out)
-        throws IOException
-    {
-        if (value >= -1 && value <= 5) {
-            out.writeByte(opc_iconst_0 + value);
-        } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
-            out.writeByte(opc_bipush);
-            out.writeByte(value & 0xFF);
-        } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
-            out.writeByte(opc_sipush);
-            out.writeShort(value & 0xFFFF);
-        } else {
-            throw new AssertionError();
-        }
-    }
-
-    /**
-     * Generate code to invoke the Class.forName with the name of the given
-     * class to get its Class object at runtime.  The code is written to
-     * the supplied stream.  Note that the code generated by this method
-     * may cause the checked ClassNotFoundException to be thrown.
-     */
-    private void codeClassForName(Class<?> cl, DataOutputStream out)
-        throws IOException
-    {
-        code_ldc(cp.getString(cl.getName()), out);
-
-        out.writeByte(opc_invokestatic);
-        out.writeShort(cp.getMethodRef(
-            "java/lang/Class",
-            "forName", "(Ljava/lang/String;)Ljava/lang/Class;"));
-    }
-
-
-    /*
-     * ==================== General Utility Methods ====================
-     */
-
-    /**
-     * Convert a fully qualified class name that uses '.' as the package
-     * separator, the external representation used by the Java language
-     * and APIs, to a fully qualified class name that uses '/' as the
-     * package separator, the representation used in the class file
-     * format (see JVMS section 4.2).
-     */
-    private static String dotToSlash(String name) {
-        return name.replace('.', '/');
-    }
-
-    /**
-     * Return the "method descriptor" string for a method with the given
-     * parameter types and return type.  See JVMS section 4.3.3.
-     */
-    private static String getMethodDescriptor(Class<?>[] parameterTypes,
-                                              Class<?> returnType)
-    {
-        return getParameterDescriptors(parameterTypes) +
-            ((returnType == void.class) ? "V" : getFieldType(returnType));
-    }
-
-    /**
-     * Return the list of "parameter descriptor" strings enclosed in
-     * parentheses corresponding to the given parameter types (in other
-     * words, a method descriptor without a return descriptor).  This
-     * string is useful for constructing string keys for methods without
-     * regard to their return type.
-     */
-    private static String getParameterDescriptors(Class<?>[] parameterTypes) {
-        StringBuilder desc = new StringBuilder("(");
-        for (int i = 0; i < parameterTypes.length; i++) {
-            desc.append(getFieldType(parameterTypes[i]));
-        }
-        desc.append(')');
-        return desc.toString();
-    }
-
-    /**
-     * Return the "field type" string for the given type, appropriate for
-     * a field descriptor, a parameter descriptor, or a return descriptor
-     * other than "void".  See JVMS section 4.3.2.
-     */
-    private static String getFieldType(Class<?> type) {
-        if (type.isPrimitive()) {
-            return PrimitiveTypeInfo.get(type).baseTypeString;
-        } else if (type.isArray()) {
-            /*
-             * According to JLS 20.3.2, the getName() method on Class does
-             * return the VM type descriptor format for array classes (only);
-             * using that should be quicker than the otherwise obvious code:
-             *
-             *     return "[" + getTypeDescriptor(type.getComponentType());
-             */
-            return type.getName().replace('.', '/');
-        } else {
-            return "L" + dotToSlash(type.getName()) + ";";
-        }
-    }
-
-    /**
-     * Returns a human-readable string representing the signature of a
-     * method with the given name and parameter types.
-     */
-    private static String getFriendlyMethodSignature(String name,
-                                                     Class<?>[] parameterTypes)
-    {
-        StringBuilder sig = new StringBuilder(name);
-        sig.append('(');
-        for (int i = 0; i < parameterTypes.length; i++) {
-            if (i > 0) {
-                sig.append(',');
-            }
-            Class<?> parameterType = parameterTypes[i];
-            int dimensions = 0;
-            while (parameterType.isArray()) {
-                parameterType = parameterType.getComponentType();
-                dimensions++;
-            }
-            sig.append(parameterType.getName());
-            while (dimensions-- > 0) {
-                sig.append("[]");
-            }
-        }
-        sig.append(')');
-        return sig.toString();
-    }
-
-    /**
-     * Return the number of abstract "words", or consecutive local variable
-     * indexes, required to contain a value of the given type.  See JVMS
-     * section 3.6.1.
-     *
-     * Note that the original version of the JVMS contained a definition of
-     * this abstract notion of a "word" in section 3.4, but that definition
-     * was removed for the second edition.
-     */
-    private static int getWordsPerType(Class<?> type) {
-        if (type == long.class || type == double.class) {
-            return 2;
-        } else {
-            return 1;
-        }
-    }
-
-    /**
-     * Add to the given list all of the types in the "from" array that
-     * are not already contained in the list and are assignable to at
-     * least one of the types in the "with" array.
-     *
-     * This method is useful for computing the greatest common set of
-     * declared exceptions from duplicate methods inherited from
-     * different interfaces.
-     */
-    private static void collectCompatibleTypes(Class<?>[] from,
-                                               Class<?>[] with,
-                                               List<Class<?>> list)
-    {
-        for (Class<?> fc: from) {
-            if (!list.contains(fc)) {
-                for (Class<?> wc: with) {
-                    if (wc.isAssignableFrom(fc)) {
-                        list.add(fc);
-                        break;
-                    }
-                }
-            }
+                    "methods with same signature " +
+                            pm.shortSignature +
+                            " but incompatible return types: " + uncoveredReturnTypes);
         }
     }
 
@@ -1585,13 +329,13 @@
      */
     private static List<Class<?>> computeUniqueCatchList(Class<?>[] exceptions) {
         List<Class<?>> uniqueList = new ArrayList<>();
-                                                // unique exceptions to catch
+        // unique exceptions to catch
 
         uniqueList.add(Error.class);            // always catch/rethrow these
         uniqueList.add(RuntimeException.class);
 
-    nextException:
-        for (Class<?> ex: exceptions) {
+        nextException:
+        for (Class<?> ex : exceptions) {
             if (ex.isAssignableFrom(Throwable.class)) {
                 /*
                  * If Throwable is declared to be thrown by the proxy method,
@@ -1610,7 +354,7 @@
              * Compare this exception against the current list of
              * exceptions that need to be caught:
              */
-            for (int j = 0; j < uniqueList.size();) {
+            for (int j = 0; j < uniqueList.size(); ) {
                 Class<?> ex2 = uniqueList.get(j);
                 if (ex2.isAssignableFrom(ex)) {
                     /*
@@ -1635,28 +379,535 @@
     }
 
     /**
+     * Convert a fully qualified class name that uses '.' as the package
+     * separator, the external representation used by the Java language
+     * and APIs, to a fully qualified class name that uses '/' as the
+     * package separator, the representation used in the class file
+     * format (see JVMS section 4.2).
+     */
+    private static String dotToSlash(String name) {
+        return name.replace('.', '/');
+    }
+
+    /**
+     * Return the number of abstract "words", or consecutive local variable
+     * indexes, required to contain a value of the given type.  See JVMS
+     * section 3.6.1.
+     * <p>
+     * Note that the original version of the JVMS contained a definition of
+     * this abstract notion of a "word" in section 3.4, but that definition
+     * was removed for the second edition.
+     */
+    private static int getWordsPerType(Class<?> type) {
+        if (type == long.class || type == double.class) {
+            return 2;
+        } else {
+            return 1;
+        }
+    }
+
+    /**
+     * Add to the given list all of the types in the "from" array that
+     * are not already contained in the list and are assignable to at
+     * least one of the types in the "with" array.
+     * <p>
+     * This method is useful for computing the greatest common set of
+     * declared exceptions from duplicate methods inherited from
+     * different interfaces.
+     */
+    private static void collectCompatibleTypes(Class<?>[] from,
+                                               Class<?>[] with,
+                                               List<Class<?>> list) {
+        for (Class<?> fc : from) {
+            if (!list.contains(fc)) {
+                for (Class<?> wc : with) {
+                    if (wc.isAssignableFrom(fc)) {
+                        list.add(fc);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the {@link ClassLoader} to be used by the default implementation of {@link
+     * #getCommonSuperClass(String, String)}, that of this {@link ClassWriter}'s runtime type by
+     * default.
+     *
+     * @return ClassLoader
+     */
+    protected ClassLoader getClassLoader() {
+        return loader;
+    }
+
+    /**
+     * Generate a class file for the proxy class.  This method drives the
+     * class file generation process.
+     */
+    private byte[] generateClassFile() {
+        visit(V14, accessFlags, dotToSlash(className), null,
+                JLR_PROXY, typeNames(interfaces));
+
+        /*
+         * Add proxy methods for the hashCode, equals,
+         * and toString methods of java.lang.Object.  This is done before
+         * the methods from the proxy interfaces so that the methods from
+         * java.lang.Object take precedence over duplicate methods in the
+         * proxy interfaces.
+         */
+        addProxyMethod(hashCodeMethod);
+        addProxyMethod(equalsMethod);
+        addProxyMethod(toStringMethod);
+
+        /*
+         * Accumulate all of the methods from the proxy interfaces.
+         */
+        for (Class<?> intf : interfaces) {
+            for (Method m : intf.getMethods()) {
+                if (!Modifier.isStatic(m.getModifiers())) {
+                    addProxyMethod(m, intf);
+                }
+            }
+        }
+
+        /*
+         * For each set of proxy methods with the same signature,
+         * verify that the methods' return types are compatible.
+         */
+        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
+            checkReturnTypes(sigmethods);
+        }
+
+        generateConstructor();
+
+        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
+            for (ProxyMethod pm : sigmethods) {
+                // add static field for the Method object
+                visitField(Modifier.PRIVATE | Modifier.STATIC, pm.methodFieldName,
+                        LJLR_METHOD, null, null);
+
+                // Generate code for proxy method
+                pm.generateMethod(this, className);
+            }
+        }
+
+        generateStaticInitializer();
+
+        return toByteArray();
+    }
+
+    /**
+     * Add another method to be proxied, either by creating a new
+     * ProxyMethod object or augmenting an old one for a duplicate
+     * method.
+     *
+     * "fromClass" indicates the proxy interface that the method was
+     * found through, which may be different from (a subinterface of)
+     * the method's "declaring class".  Note that the first Method
+     * object passed for a given name and descriptor identifies the
+     * Method object (and thus the declaring class) that will be
+     * passed to the invocation handler's "invoke" method for a given
+     * set of duplicate methods.
+     */
+    private void addProxyMethod(Method m, Class<?> fromClass) {
+        Class<?> returnType = m.getReturnType();
+        Class<?>[] exceptionTypes = m.getExceptionTypes();
+
+        String sig = m.toShortSignature();
+        List<ProxyMethod> sigmethods = proxyMethods.computeIfAbsent(sig,
+                (f) -> new ArrayList<>(3));
+        for (ProxyMethod pm : sigmethods) {
+            if (returnType == pm.returnType) {
+                /*
+                 * Found a match: reduce exception types to the
+                 * greatest set of exceptions that can be thrown
+                 * compatibly with the throws clauses of both
+                 * overridden methods.
+                 */
+                List<Class<?>> legalExceptions = new ArrayList<>();
+                collectCompatibleTypes(
+                        exceptionTypes, pm.exceptionTypes, legalExceptions);
+                collectCompatibleTypes(
+                        pm.exceptionTypes, exceptionTypes, legalExceptions);
+                pm.exceptionTypes = legalExceptions.toArray(EMPTY_CLASS_ARRAY);
+                return;
+            }
+        }
+        sigmethods.add(new ProxyMethod(m, sig, m.getParameterTypes(), returnType,
+                exceptionTypes, fromClass,
+                "m" + proxyMethodCount++));
+    }
+
+    /**
+     * Add an existing ProxyMethod (hashcode, equals, toString).
+     *
+     * @param pm an existing ProxyMethod
+     */
+    private void addProxyMethod(ProxyMethod pm) {
+        String sig = pm.shortSignature;
+        List<ProxyMethod> sigmethods = proxyMethods.computeIfAbsent(sig,
+                (f) -> new ArrayList<>(3));
+        sigmethods.add(pm);
+    }
+
+    /**
+     * Generate the constructor method for the proxy class.
+     */
+    private void generateConstructor() {
+        MethodVisitor ctor = visitMethod(Modifier.PUBLIC, NAME_CTOR,
+                MJLR_INVOCATIONHANDLER, null, null);
+        ctor.visitParameter(null, 0);
+        ctor.visitCode();
+        ctor.visitVarInsn(ALOAD, 0);
+        ctor.visitVarInsn(ALOAD, 1);
+        ctor.visitMethodInsn(INVOKESPECIAL, JLR_PROXY, NAME_CTOR,
+                MJLR_INVOCATIONHANDLER, false);
+        ctor.visitInsn(RETURN);
+
+        // Maxs computed by ClassWriter.COMPUTE_FRAMES, these arguments ignored
+        ctor.visitMaxs(-1, -1);
+        ctor.visitEnd();
+    }
+
+    /**
+     * Generate the static initializer method for the proxy class.
+     */
+    private void generateStaticInitializer() {
+
+        MethodVisitor mv = visitMethod(Modifier.STATIC, NAME_CLINIT,
+                "()V", null, null);
+        mv.visitCode();
+        Label L_startBlock = new Label();
+        Label L_endBlock = new Label();
+        Label L_NoMethodHandler = new Label();
+        Label L_NoClassHandler = new Label();
+
+        mv.visitTryCatchBlock(L_startBlock, L_endBlock, L_NoMethodHandler,
+                JL_NO_SUCH_METHOD_EX);
+        mv.visitTryCatchBlock(L_startBlock, L_endBlock, L_NoClassHandler,
+                JL_CLASS_NOT_FOUND_EX);
+
+        mv.visitLabel(L_startBlock);
+        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
+            for (ProxyMethod pm : sigmethods) {
+                pm.codeFieldInitialization(mv, className);
+            }
+        }
+        mv.visitInsn(RETURN);
+        mv.visitLabel(L_endBlock);
+        // Generate exception handler
+
+        mv.visitLabel(L_NoMethodHandler);
+        mv.visitVarInsn(ASTORE, 1);
+        mv.visitTypeInsn(Opcodes.NEW, JL_NO_SUCH_METHOD_ERROR);
+        mv.visitInsn(DUP);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitMethodInsn(INVOKEVIRTUAL, JL_THROWABLE,
+                "getMessage", "()Ljava/lang/String;", false);
+        mv.visitMethodInsn(INVOKESPECIAL, JL_NO_SUCH_METHOD_ERROR,
+                "<init>", "(Ljava/lang/String;)V", false);
+        mv.visitInsn(ATHROW);
+
+        mv.visitLabel(L_NoClassHandler);
+        mv.visitVarInsn(ASTORE, 1);
+        mv.visitTypeInsn(Opcodes.NEW, JL_NO_CLASS_DEF_FOUND_ERROR);
+        mv.visitInsn(DUP);
+        mv.visitVarInsn(ALOAD, 1);
+        mv.visitMethodInsn(INVOKEVIRTUAL, JL_THROWABLE,
+                "getMessage", "()Ljava/lang/String;", false);
+        mv.visitMethodInsn(INVOKESPECIAL, JL_NO_CLASS_DEF_FOUND_ERROR,
+                "<init>", "(Ljava/lang/String;)V", false);
+        mv.visitInsn(ATHROW);
+
+        // Maxs computed by ClassWriter.COMPUTE_FRAMES, these arguments ignored
+        mv.visitMaxs(-1, -1);
+        mv.visitEnd();
+    }
+
+    /**
+     * A ProxyMethod object represents a proxy method in the proxy class
+     * being generated: a method whose implementation will encode and
+     * dispatch invocations to the proxy instance's invocation handler.
+     */
+    private static class ProxyMethod {
+
+        private final Method method;
+        private final String shortSignature;
+        private final Class<?> fromClass;
+        private final Class<?>[] parameterTypes;
+        private final Class<?> returnType;
+        private final String methodFieldName;
+        private Class<?>[] exceptionTypes;
+
+        private ProxyMethod(Method method, String sig, Class<?>[] parameterTypes,
+                            Class<?> returnType, Class<?>[] exceptionTypes,
+                            Class<?> fromClass, String methodFieldName) {
+            this.method = method;
+            this.shortSignature = sig;
+            this.parameterTypes = parameterTypes;
+            this.returnType = returnType;
+            this.exceptionTypes = exceptionTypes;
+            this.fromClass = fromClass;
+            this.methodFieldName = methodFieldName;
+        }
+
+        /**
+         * Create a new specific ProxyMethod with a specific field name
+         *
+         * @param method          The method for which to create a proxy
+         * @param methodFieldName the fieldName to generate
+         */
+        private ProxyMethod(Method method, String methodFieldName) {
+            this(method, method.toShortSignature(),
+                    method.getParameterTypes(), method.getReturnType(),
+                    method.getExceptionTypes(), method.getDeclaringClass(), methodFieldName);
+        }
+
+        /**
+         * Generate this method, including the code and exception table entry.
+         */
+        private void generateMethod(ClassWriter cw, String className) {
+            MethodType mt = MethodType.methodType(returnType, parameterTypes);
+            String desc = mt.toMethodDescriptorString();
+            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_FINAL,
+                    method.getName(), desc, null,
+                    typeNames(Arrays.asList(exceptionTypes)));
+
+            int[] parameterSlot = new int[parameterTypes.length];
+            int nextSlot = 1;
+            for (int i = 0; i < parameterSlot.length; i++) {
+                parameterSlot[i] = nextSlot;
+                nextSlot += getWordsPerType(parameterTypes[i]);
+            }
+
+            mv.visitCode();
+            Label L_startBlock = new Label();
+            Label L_endBlock = new Label();
+            Label L_RuntimeHandler = new Label();
+            Label L_ThrowableHandler = new Label();
+
+            List<Class<?>> catchList = computeUniqueCatchList(exceptionTypes);
+            if (catchList.size() > 0) {
+                for (Class<?> ex : catchList) {
+                    mv.visitTryCatchBlock(L_startBlock, L_endBlock, L_RuntimeHandler,
+                            dotToSlash(ex.getName()));
+                }
+
+                mv.visitTryCatchBlock(L_startBlock, L_endBlock, L_ThrowableHandler,
+                        JL_THROWABLE);
+            }
+            mv.visitLabel(L_startBlock);
+
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETFIELD, JLR_PROXY, handlerFieldName,
+                    LJLR_INVOCATION_HANDLER);
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETSTATIC, dotToSlash(className), methodFieldName,
+                    LJLR_METHOD);
+
+            if (parameterTypes.length > 0) {
+                // Create an array and fill with the parameters converting primitives to wrappers
+                emitIconstInsn(mv, parameterTypes.length);
+                mv.visitTypeInsn(Opcodes.ANEWARRAY, JL_OBJECT);
+                for (int i = 0; i < parameterTypes.length; i++) {
+                    mv.visitInsn(DUP);
+                    emitIconstInsn(mv, i);
+                    codeWrapArgument(mv, parameterTypes[i], parameterSlot[i]);
+                    mv.visitInsn(Opcodes.AASTORE);
+                }
+            } else {
+                mv.visitInsn(Opcodes.ACONST_NULL);
+            }
+
+            mv.visitMethodInsn(INVOKEINTERFACE, JLR_INVOCATION_HANDLER,
+                    "invoke",
+                    "(Ljava/lang/Object;Ljava/lang/reflect/Method;" +
+                            "[Ljava/lang/Object;)Ljava/lang/Object;", true);
+
+            if (returnType == void.class) {
+                mv.visitInsn(POP);
+                mv.visitInsn(RETURN);
+            } else {
+                codeUnwrapReturnValue(mv, returnType);
+            }
+
+            mv.visitLabel(L_endBlock);
+
+            // Generate exception handler
+            mv.visitLabel(L_RuntimeHandler);
+            mv.visitInsn(ATHROW);   // just rethrow the exception
+
+            mv.visitLabel(L_ThrowableHandler);
+            mv.visitVarInsn(ASTORE, 1);
+            mv.visitTypeInsn(Opcodes.NEW, JLR_UNDECLARED_THROWABLE_EX);
+            mv.visitInsn(DUP);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitMethodInsn(INVOKESPECIAL, JLR_UNDECLARED_THROWABLE_EX,
+                    "<init>", "(Ljava/lang/Throwable;)V", false);
+            mv.visitInsn(ATHROW);
+            // Maxs computed by ClassWriter.COMPUTE_FRAMES, these arguments ignored
+            mv.visitMaxs(-1, -1);
+            mv.visitEnd();
+        }
+
+        /**
+         * Generate code for wrapping an argument of the given type
+         * whose value can be found at the specified local variable
+         * index, in order for it to be passed (as an Object) to the
+         * invocation handler's "invoke" method.
+         */
+        private void codeWrapArgument(MethodVisitor mv, Class<?> type, int slot) {
+            if (type.isPrimitive()) {
+                PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
+
+                if (type == int.class ||
+                        type == boolean.class ||
+                        type == byte.class ||
+                        type == char.class ||
+                        type == short.class) {
+                    mv.visitVarInsn(ILOAD, slot);
+                } else if (type == long.class) {
+                    mv.visitVarInsn(LLOAD, slot);
+                } else if (type == float.class) {
+                    mv.visitVarInsn(FLOAD, slot);
+                } else if (type == double.class) {
+                    mv.visitVarInsn(DLOAD, slot);
+                } else {
+                    throw new AssertionError();
+                }
+                mv.visitMethodInsn(INVOKESTATIC, prim.wrapperClassName, "valueOf",
+                        prim.wrapperValueOfDesc, false);
+            } else {
+                mv.visitVarInsn(ALOAD, slot);
+            }
+        }
+
+        /**
+         * Generate code for unwrapping a return value of the given
+         * type from the invocation handler's "invoke" method (as type
+         * Object) to its correct type.
+         */
+        private void codeUnwrapReturnValue(MethodVisitor mv, Class<?> type) {
+            if (type.isPrimitive()) {
+                PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
+
+                mv.visitTypeInsn(CHECKCAST, prim.wrapperClassName);
+                mv.visitMethodInsn(INVOKEVIRTUAL,
+                        prim.wrapperClassName,
+                        prim.unwrapMethodName, prim.unwrapMethodDesc, false);
+
+                if (type == int.class ||
+                        type == boolean.class ||
+                        type == byte.class ||
+                        type == char.class ||
+                        type == short.class) {
+                    mv.visitInsn(IRETURN);
+                } else if (type == long.class) {
+                    mv.visitInsn(LRETURN);
+                } else if (type == float.class) {
+                    mv.visitInsn(FRETURN);
+                } else if (type == double.class) {
+                    mv.visitInsn(DRETURN);
+                } else {
+                    throw new AssertionError();
+                }
+            } else {
+                mv.visitTypeInsn(CHECKCAST, dotToSlash(type.getName()));
+                mv.visitInsn(ARETURN);
+            }
+        }
+
+        /**
+         * Generate code for initializing the static field that stores
+         * the Method object for this proxy method.
+         */
+        private void codeFieldInitialization(MethodVisitor mv, String className) {
+            codeClassForName(mv, fromClass);
+
+            mv.visitLdcInsn(method.getName());
+
+            emitIconstInsn(mv, parameterTypes.length);
+
+            mv.visitTypeInsn(Opcodes.ANEWARRAY, JL_CLASS);
+
+            // Construct an array with the parameter types mapping primitives to Wrapper types
+            for (int i = 0; i < parameterTypes.length; i++) {
+                mv.visitInsn(DUP);
+                emitIconstInsn(mv, i);
+
+                if (parameterTypes[i].isPrimitive()) {
+                    PrimitiveTypeInfo prim =
+                            PrimitiveTypeInfo.get(parameterTypes[i]);
+                    mv.visitFieldInsn(GETSTATIC,
+                            prim.wrapperClassName, "TYPE", LJL_CLASS);
+                } else {
+                    codeClassForName(mv, parameterTypes[i]);
+                }
+                mv.visitInsn(Opcodes.AASTORE);
+            }
+            // lookup the method
+            mv.visitMethodInsn(INVOKEVIRTUAL,
+                    JL_CLASS,
+                    "getMethod",
+                    "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;",
+                    false);
+
+            mv.visitFieldInsn(PUTSTATIC,
+                    dotToSlash(className),
+                    methodFieldName, LJLR_METHOD);
+        }
+
+        /*
+         * =============== Code Generation Utility Methods ===============
+         */
+
+        /**
+         * Generate code to invoke the Class.forName with the name of the given
+         * class to get its Class object at runtime.  The code is written to
+         * the supplied stream.  Note that the code generated by this method
+         * may cause the checked ClassNotFoundException to be thrown.
+         */
+        private void codeClassForName(MethodVisitor mv, Class<?> cl) {
+            mv.visitLdcInsn(cl.getName());
+            mv.visitMethodInsn(INVOKESTATIC,
+                    JL_CLASS,
+                    "forName", "(Ljava/lang/String;)Ljava/lang/Class;", false);
+        }
+
+        /**
+         * Visit a bytecode for a constant.
+         *
+         * @param mv  The MethodVisitor
+         * @param cst The constant value
+         */
+        private void emitIconstInsn(MethodVisitor mv, final int cst) {
+            if (cst >= -1 && cst <= 5) {
+                mv.visitInsn(Opcodes.ICONST_0 + cst);
+            } else if (cst >= Byte.MIN_VALUE && cst <= Byte.MAX_VALUE) {
+                mv.visitIntInsn(Opcodes.BIPUSH, cst);
+            } else if (cst >= Short.MIN_VALUE && cst <= Short.MAX_VALUE) {
+                mv.visitIntInsn(Opcodes.SIPUSH, cst);
+            } else {
+                mv.visitLdcInsn(cst);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return method.toShortString();
+        }
+    }
+
+    /**
      * A PrimitiveTypeInfo object contains assorted information about
      * a primitive type in its public fields.  The struct for a particular
      * primitive type can be obtained using the static "get" method.
      */
     private static class PrimitiveTypeInfo {
 
-        /** "base type" used in various descriptors (see JVMS section 4.3.2) */
-        public String baseTypeString;
-
-        /** name of corresponding wrapper class */
-        public String wrapperClassName;
+        private static Map<Class<?>, PrimitiveTypeInfo> table = new HashMap<>();
 
-        /** method descriptor for wrapper class "valueOf" factory method */
-        public String wrapperValueOfDesc;
-
-        /** name of wrapper class method for retrieving primitive value */
-        public String unwrapMethodName;
-
-        /** descriptor of same method */
-        public String unwrapMethodDesc;
-
-        private static Map<Class<?>,PrimitiveTypeInfo> table = new HashMap<>();
         static {
             add(byte.class, Byte.class);
             add(char.class, Character.class);
@@ -1668,365 +919,46 @@
             add(boolean.class, Boolean.class);
         }
 
-        private static void add(Class<?> primitiveClass, Class<?> wrapperClass) {
-            table.put(primitiveClass,
-                      new PrimitiveTypeInfo(primitiveClass, wrapperClass));
-        }
+        /**
+         * name of corresponding wrapper class
+         */
+        private String wrapperClassName;
+        /**
+         * method descriptor for wrapper class "valueOf" factory method
+         */
+        private String wrapperValueOfDesc;
+        /**
+         * name of wrapper class method for retrieving primitive value
+         */
+        private String unwrapMethodName;
+        /**
+         * descriptor of same method
+         */
+        private String unwrapMethodDesc;
 
         private PrimitiveTypeInfo(Class<?> primitiveClass, Class<?> wrapperClass) {
             assert primitiveClass.isPrimitive();
 
-            baseTypeString =
-                Array.newInstance(primitiveClass, 0)
-                .getClass().getName().substring(1);
+            /**
+             * "base type" used in various descriptors (see JVMS section 4.3.2)
+             */
+            String baseTypeString =
+                    Array.newInstance(primitiveClass, 0)
+                            .getClass().getName().substring(1);
             wrapperClassName = dotToSlash(wrapperClass.getName());
             wrapperValueOfDesc =
-                "(" + baseTypeString + ")L" + wrapperClassName + ";";
+                    "(" + baseTypeString + ")L" + wrapperClassName + ";";
             unwrapMethodName = primitiveClass.getName() + "Value";
             unwrapMethodDesc = "()" + baseTypeString;
         }
 
+        private static void add(Class<?> primitiveClass, Class<?> wrapperClass) {
+            table.put(primitiveClass,
+                    new PrimitiveTypeInfo(primitiveClass, wrapperClass));
+        }
+
         public static PrimitiveTypeInfo get(Class<?> cl) {
             return table.get(cl);
         }
     }
-
-
-    /**
-     * A ConstantPool object represents the constant pool of a class file
-     * being generated.  This representation of a constant pool is designed
-     * specifically for use by ProxyGenerator; in particular, it assumes
-     * that constant pool entries will not need to be resorted (for example,
-     * by their type, as the Java compiler does), so that the final index
-     * value can be assigned and used when an entry is first created.
-     *
-     * Note that new entries cannot be created after the constant pool has
-     * been written to a class file.  To prevent such logic errors, a
-     * ConstantPool instance can be marked "read only", so that further
-     * attempts to add new entries will fail with a runtime exception.
-     *
-     * See JVMS section 4.4 for more information about the constant pool
-     * of a class file.
-     */
-    private static class ConstantPool {
-
-        /**
-         * list of constant pool entries, in constant pool index order.
-         *
-         * This list is used when writing the constant pool to a stream
-         * and for assigning the next index value.  Note that element 0
-         * of this list corresponds to constant pool index 1.
-         */
-        private List<Entry> pool = new ArrayList<>(32);
-
-        /**
-         * maps constant pool data of all types to constant pool indexes.
-         *
-         * This map is used to look up the index of an existing entry for
-         * values of all types.
-         */
-        private Map<Object,Integer> map = new HashMap<>(16);
-
-        /** true if no new constant pool entries may be added */
-        private boolean readOnly = false;
-
-        /**
-         * Get or assign the index for a CONSTANT_Utf8 entry.
-         */
-        public short getUtf8(String s) {
-            if (s == null) {
-                throw new NullPointerException();
-            }
-            return getValue(s);
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_Integer entry.
-         */
-        public short getInteger(int i) {
-            return getValue(i);
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_Float entry.
-         */
-        public short getFloat(float f) {
-            return getValue(f);
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_Class entry.
-         */
-        public short getClass(String name) {
-            short utf8Index = getUtf8(name);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_CLASS, utf8Index));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_String entry.
-         */
-        public short getString(String s) {
-            short utf8Index = getUtf8(s);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_STRING, utf8Index));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_FieldRef entry.
-         */
-        public short getFieldRef(String className,
-                                 String name, String descriptor)
-        {
-            short classIndex = getClass(className);
-            short nameAndTypeIndex = getNameAndType(name, descriptor);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_FIELD, classIndex, nameAndTypeIndex));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_MethodRef entry.
-         */
-        public short getMethodRef(String className,
-                                  String name, String descriptor)
-        {
-            short classIndex = getClass(className);
-            short nameAndTypeIndex = getNameAndType(name, descriptor);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_METHOD, classIndex, nameAndTypeIndex));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_InterfaceMethodRef entry.
-         */
-        public short getInterfaceMethodRef(String className, String name,
-                                           String descriptor)
-        {
-            short classIndex = getClass(className);
-            short nameAndTypeIndex = getNameAndType(name, descriptor);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_INTERFACEMETHOD, classIndex, nameAndTypeIndex));
-        }
-
-        /**
-         * Get or assign the index for a CONSTANT_NameAndType entry.
-         */
-        public short getNameAndType(String name, String descriptor) {
-            short nameIndex = getUtf8(name);
-            short descriptorIndex = getUtf8(descriptor);
-            return getIndirect(new IndirectEntry(
-                CONSTANT_NAMEANDTYPE, nameIndex, descriptorIndex));
-        }
-
-        /**
-         * Set this ConstantPool instance to be "read only".
-         *
-         * After this method has been called, further requests to get
-         * an index for a non-existent entry will cause an InternalError
-         * to be thrown instead of creating of the entry.
-         */
-        public void setReadOnly() {
-            readOnly = true;
-        }
-
-        /**
-         * Write this constant pool to a stream as part of
-         * the class file format.
-         *
-         * This consists of writing the "constant_pool_count" and
-         * "constant_pool[]" items of the "ClassFile" structure, as
-         * described in JVMS section 4.1.
-         */
-        public void write(OutputStream out) throws IOException {
-            DataOutputStream dataOut = new DataOutputStream(out);
-
-            // constant_pool_count: number of entries plus one
-            dataOut.writeShort(pool.size() + 1);
-
-            for (Entry e : pool) {
-                e.write(dataOut);
-            }
-        }
-
-        /**
-         * Add a new constant pool entry and return its index.
-         */
-        private short addEntry(Entry entry) {
-            pool.add(entry);
-            /*
-             * Note that this way of determining the index of the
-             * added entry is wrong if this pool supports
-             * CONSTANT_Long or CONSTANT_Double entries.
-             */
-            if (pool.size() >= 65535) {
-                throw new IllegalArgumentException(
-                    "constant pool size limit exceeded");
-            }
-            return (short) pool.size();
-        }
-
-        /**
-         * Get or assign the index for an entry of a type that contains
-         * a direct value.  The type of the given object determines the
-         * type of the desired entry as follows:
-         *
-         *      java.lang.String        CONSTANT_Utf8
-         *      java.lang.Integer       CONSTANT_Integer
-         *      java.lang.Float         CONSTANT_Float
-         *      java.lang.Long          CONSTANT_Long
-         *      java.lang.Double        CONSTANT_DOUBLE
-         */
-        private short getValue(Object key) {
-            Integer index = map.get(key);
-            if (index != null) {
-                return index.shortValue();
-            } else {
-                if (readOnly) {
-                    throw new InternalError(
-                        "late constant pool addition: " + key);
-                }
-                short i = addEntry(new ValueEntry(key));
-                map.put(key, (int)i);
-                return i;
-            }
-        }
-
-        /**
-         * Get or assign the index for an entry of a type that contains
-         * references to other constant pool entries.
-         */
-        private short getIndirect(IndirectEntry e) {
-            Integer index = map.get(e);
-            if (index != null) {
-                return index.shortValue();
-            } else {
-                if (readOnly) {
-                    throw new InternalError("late constant pool addition");
-                }
-                short i = addEntry(e);
-                map.put(e, (int)i);
-                return i;
-            }
-        }
-
-        /**
-         * Entry is the abstact superclass of all constant pool entry types
-         * that can be stored in the "pool" list; its purpose is to define a
-         * common method for writing constant pool entries to a class file.
-         */
-        private abstract static class Entry {
-            public abstract void write(DataOutputStream out)
-                throws IOException;
-        }
-
-        /**
-         * ValueEntry represents a constant pool entry of a type that
-         * contains a direct value (see the comments for the "getValue"
-         * method for a list of such types).
-         *
-         * ValueEntry objects are not used as keys for their entries in the
-         * Map "map", so no useful hashCode or equals methods are defined.
-         */
-        private static class ValueEntry extends Entry {
-            private Object value;
-
-            public ValueEntry(Object value) {
-                this.value = value;
-            }
-
-            public void write(DataOutputStream out) throws IOException {
-                if (value instanceof String) {
-                    out.writeByte(CONSTANT_UTF8);
-                    out.writeUTF((String) value);
-                } else if (value instanceof Integer) {
-                    out.writeByte(CONSTANT_INTEGER);
-                    out.writeInt(((Integer) value).intValue());
-                } else if (value instanceof Float) {
-                    out.writeByte(CONSTANT_FLOAT);
-                    out.writeFloat(((Float) value).floatValue());
-                } else if (value instanceof Long) {
-                    out.writeByte(CONSTANT_LONG);
-                    out.writeLong(((Long) value).longValue());
-                } else if (value instanceof Double) {
-                    out.writeDouble(CONSTANT_DOUBLE);
-                    out.writeDouble(((Double) value).doubleValue());
-                } else {
-                    throw new InternalError("bogus value entry: " + value);
-                }
-            }
-        }
-
-        /**
-         * IndirectEntry represents a constant pool entry of a type that
-         * references other constant pool entries, i.e., the following types:
-         *
-         *      CONSTANT_Class, CONSTANT_String, CONSTANT_Fieldref,
-         *      CONSTANT_Methodref, CONSTANT_InterfaceMethodref, and
-         *      CONSTANT_NameAndType.
-         *
-         * Each of these entry types contains either one or two indexes of
-         * other constant pool entries.
-         *
-         * IndirectEntry objects are used as the keys for their entries in
-         * the Map "map", so the hashCode and equals methods are overridden
-         * to allow matching.
-         */
-        private static class IndirectEntry extends Entry {
-            private int tag;
-            private short index0;
-            private short index1;
-
-            /**
-             * Construct an IndirectEntry for a constant pool entry type
-             * that contains one index of another entry.
-             */
-            public IndirectEntry(int tag, short index) {
-                this.tag = tag;
-                this.index0 = index;
-                this.index1 = 0;
-            }
-
-            /**
-             * Construct an IndirectEntry for a constant pool entry type
-             * that contains two indexes for other entries.
-             */
-            public IndirectEntry(int tag, short index0, short index1) {
-                this.tag = tag;
-                this.index0 = index0;
-                this.index1 = index1;
-            }
-
-            public void write(DataOutputStream out) throws IOException {
-                out.writeByte(tag);
-                out.writeShort(index0);
-                /*
-                 * If this entry type contains two indexes, write
-                 * out the second, too.
-                 */
-                if (tag == CONSTANT_FIELD ||
-                    tag == CONSTANT_METHOD ||
-                    tag == CONSTANT_INTERFACEMETHOD ||
-                    tag == CONSTANT_NAMEANDTYPE)
-                {
-                    out.writeShort(index1);
-                }
-            }
-
-            public int hashCode() {
-                return tag + index0 + index1;
-            }
-
-            public boolean equals(Object obj) {
-                if (obj instanceof IndirectEntry) {
-                    IndirectEntry other = (IndirectEntry) obj;
-                    if (tag == other.tag &&
-                        index0 == other.index0 && index1 == other.index1)
-                    {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }
-    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/reflect/ProxyGenerator_v49.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,2031 @@
+/*
+ * 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
+ * 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 java.lang.reflect;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import sun.security.action.GetBooleanAction;
+
+/**
+ * ProxyGenerator contains the code to generate a dynamic proxy class
+ * for the java.lang.reflect.Proxy API.
+ *
+ * The external interfaces to ProxyGenerator is the static
+ * "generateProxyClass" method.
+ *
+ * @author      Peter Jones
+ * @since       1.3
+ */
+class ProxyGenerator_v49 {
+    /*
+     * In the comments below, "JVMS" refers to The Java Virtual Machine
+     * Specification Second Edition and "JLS" refers to the original
+     * version of The Java Language Specification, unless otherwise
+     * specified.
+     */
+
+    /* generate 1.5-era class file version */
+    private static final int CLASSFILE_MAJOR_VERSION = 49;
+    private static final int CLASSFILE_MINOR_VERSION = 0;
+
+    /*
+     * beginning of constants copied from
+     * sun.tools.java.RuntimeConstants (which no longer exists):
+     */
+
+    /* constant pool tags */
+    private static final int CONSTANT_UTF8              = 1;
+    private static final int CONSTANT_UNICODE           = 2;
+    private static final int CONSTANT_INTEGER           = 3;
+    private static final int CONSTANT_FLOAT             = 4;
+    private static final int CONSTANT_LONG              = 5;
+    private static final int CONSTANT_DOUBLE            = 6;
+    private static final int CONSTANT_CLASS             = 7;
+    private static final int CONSTANT_STRING            = 8;
+    private static final int CONSTANT_FIELD             = 9;
+    private static final int CONSTANT_METHOD            = 10;
+    private static final int CONSTANT_INTERFACEMETHOD   = 11;
+    private static final int CONSTANT_NAMEANDTYPE       = 12;
+
+    /* access and modifier flags */
+    private static final int ACC_PUBLIC                 = 0x00000001;
+    private static final int ACC_PRIVATE                = 0x00000002;
+//  private static final int ACC_PROTECTED              = 0x00000004;
+    private static final int ACC_STATIC                 = 0x00000008;
+    private static final int ACC_FINAL                  = 0x00000010;
+//  private static final int ACC_SYNCHRONIZED           = 0x00000020;
+//  private static final int ACC_VOLATILE               = 0x00000040;
+//  private static final int ACC_TRANSIENT              = 0x00000080;
+//  private static final int ACC_NATIVE                 = 0x00000100;
+//  private static final int ACC_INTERFACE              = 0x00000200;
+//  private static final int ACC_ABSTRACT               = 0x00000400;
+    private static final int ACC_SUPER                  = 0x00000020;
+//  private static final int ACC_STRICT                 = 0x00000800;
+
+    /* opcodes */
+//  private static final int opc_nop                    = 0;
+    private static final int opc_aconst_null            = 1;
+//  private static final int opc_iconst_m1              = 2;
+    private static final int opc_iconst_0               = 3;
+//  private static final int opc_iconst_1               = 4;
+//  private static final int opc_iconst_2               = 5;
+//  private static final int opc_iconst_3               = 6;
+//  private static final int opc_iconst_4               = 7;
+//  private static final int opc_iconst_5               = 8;
+//  private static final int opc_lconst_0               = 9;
+//  private static final int opc_lconst_1               = 10;
+//  private static final int opc_fconst_0               = 11;
+//  private static final int opc_fconst_1               = 12;
+//  private static final int opc_fconst_2               = 13;
+//  private static final int opc_dconst_0               = 14;
+//  private static final int opc_dconst_1               = 15;
+    private static final int opc_bipush                 = 16;
+    private static final int opc_sipush                 = 17;
+    private static final int opc_ldc                    = 18;
+    private static final int opc_ldc_w                  = 19;
+//  private static final int opc_ldc2_w                 = 20;
+    private static final int opc_iload                  = 21;
+    private static final int opc_lload                  = 22;
+    private static final int opc_fload                  = 23;
+    private static final int opc_dload                  = 24;
+    private static final int opc_aload                  = 25;
+    private static final int opc_iload_0                = 26;
+//  private static final int opc_iload_1                = 27;
+//  private static final int opc_iload_2                = 28;
+//  private static final int opc_iload_3                = 29;
+    private static final int opc_lload_0                = 30;
+//  private static final int opc_lload_1                = 31;
+//  private static final int opc_lload_2                = 32;
+//  private static final int opc_lload_3                = 33;
+    private static final int opc_fload_0                = 34;
+//  private static final int opc_fload_1                = 35;
+//  private static final int opc_fload_2                = 36;
+//  private static final int opc_fload_3                = 37;
+    private static final int opc_dload_0                = 38;
+//  private static final int opc_dload_1                = 39;
+//  private static final int opc_dload_2                = 40;
+//  private static final int opc_dload_3                = 41;
+    private static final int opc_aload_0                = 42;
+//  private static final int opc_aload_1                = 43;
+//  private static final int opc_aload_2                = 44;
+//  private static final int opc_aload_3                = 45;
+//  private static final int opc_iaload                 = 46;
+//  private static final int opc_laload                 = 47;
+//  private static final int opc_faload                 = 48;
+//  private static final int opc_daload                 = 49;
+//  private static final int opc_aaload                 = 50;
+//  private static final int opc_baload                 = 51;
+//  private static final int opc_caload                 = 52;
+//  private static final int opc_saload                 = 53;
+//  private static final int opc_istore                 = 54;
+//  private static final int opc_lstore                 = 55;
+//  private static final int opc_fstore                 = 56;
+//  private static final int opc_dstore                 = 57;
+    private static final int opc_astore                 = 58;
+//  private static final int opc_istore_0               = 59;
+//  private static final int opc_istore_1               = 60;
+//  private static final int opc_istore_2               = 61;
+//  private static final int opc_istore_3               = 62;
+//  private static final int opc_lstore_0               = 63;
+//  private static final int opc_lstore_1               = 64;
+//  private static final int opc_lstore_2               = 65;
+//  private static final int opc_lstore_3               = 66;
+//  private static final int opc_fstore_0               = 67;
+//  private static final int opc_fstore_1               = 68;
+//  private static final int opc_fstore_2               = 69;
+//  private static final int opc_fstore_3               = 70;
+//  private static final int opc_dstore_0               = 71;
+//  private static final int opc_dstore_1               = 72;
+//  private static final int opc_dstore_2               = 73;
+//  private static final int opc_dstore_3               = 74;
+    private static final int opc_astore_0               = 75;
+//  private static final int opc_astore_1               = 76;
+//  private static final int opc_astore_2               = 77;
+//  private static final int opc_astore_3               = 78;
+//  private static final int opc_iastore                = 79;
+//  private static final int opc_lastore                = 80;
+//  private static final int opc_fastore                = 81;
+//  private static final int opc_dastore                = 82;
+    private static final int opc_aastore                = 83;
+//  private static final int opc_bastore                = 84;
+//  private static final int opc_castore                = 85;
+//  private static final int opc_sastore                = 86;
+    private static final int opc_pop                    = 87;
+//  private static final int opc_pop2                   = 88;
+    private static final int opc_dup                    = 89;
+//  private static final int opc_dup_x1                 = 90;
+//  private static final int opc_dup_x2                 = 91;
+//  private static final int opc_dup2                   = 92;
+//  private static final int opc_dup2_x1                = 93;
+//  private static final int opc_dup2_x2                = 94;
+//  private static final int opc_swap                   = 95;
+//  private static final int opc_iadd                   = 96;
+//  private static final int opc_ladd                   = 97;
+//  private static final int opc_fadd                   = 98;
+//  private static final int opc_dadd                   = 99;
+//  private static final int opc_isub                   = 100;
+//  private static final int opc_lsub                   = 101;
+//  private static final int opc_fsub                   = 102;
+//  private static final int opc_dsub                   = 103;
+//  private static final int opc_imul                   = 104;
+//  private static final int opc_lmul                   = 105;
+//  private static final int opc_fmul                   = 106;
+//  private static final int opc_dmul                   = 107;
+//  private static final int opc_idiv                   = 108;
+//  private static final int opc_ldiv                   = 109;
+//  private static final int opc_fdiv                   = 110;
+//  private static final int opc_ddiv                   = 111;
+//  private static final int opc_irem                   = 112;
+//  private static final int opc_lrem                   = 113;
+//  private static final int opc_frem                   = 114;
+//  private static final int opc_drem                   = 115;
+//  private static final int opc_ineg                   = 116;
+//  private static final int opc_lneg                   = 117;
+//  private static final int opc_fneg                   = 118;
+//  private static final int opc_dneg                   = 119;
+//  private static final int opc_ishl                   = 120;
+//  private static final int opc_lshl                   = 121;
+//  private static final int opc_ishr                   = 122;
+//  private static final int opc_lshr                   = 123;
+//  private static final int opc_iushr                  = 124;
+//  private static final int opc_lushr                  = 125;
+//  private static final int opc_iand                   = 126;
+//  private static final int opc_land                   = 127;
+//  private static final int opc_ior                    = 128;
+//  private static final int opc_lor                    = 129;
+//  private static final int opc_ixor                   = 130;
+//  private static final int opc_lxor                   = 131;
+//  private static final int opc_iinc                   = 132;
+//  private static final int opc_i2l                    = 133;
+//  private static final int opc_i2f                    = 134;
+//  private static final int opc_i2d                    = 135;
+//  private static final int opc_l2i                    = 136;
+//  private static final int opc_l2f                    = 137;
+//  private static final int opc_l2d                    = 138;
+//  private static final int opc_f2i                    = 139;
+//  private static final int opc_f2l                    = 140;
+//  private static final int opc_f2d                    = 141;
+//  private static final int opc_d2i                    = 142;
+//  private static final int opc_d2l                    = 143;
+//  private static final int opc_d2f                    = 144;
+//  private static final int opc_i2b                    = 145;
+//  private static final int opc_i2c                    = 146;
+//  private static final int opc_i2s                    = 147;
+//  private static final int opc_lcmp                   = 148;
+//  private static final int opc_fcmpl                  = 149;
+//  private static final int opc_fcmpg                  = 150;
+//  private static final int opc_dcmpl                  = 151;
+//  private static final int opc_dcmpg                  = 152;
+//  private static final int opc_ifeq                   = 153;
+//  private static final int opc_ifne                   = 154;
+//  private static final int opc_iflt                   = 155;
+//  private static final int opc_ifge                   = 156;
+//  private static final int opc_ifgt                   = 157;
+//  private static final int opc_ifle                   = 158;
+//  private static final int opc_if_icmpeq              = 159;
+//  private static final int opc_if_icmpne              = 160;
+//  private static final int opc_if_icmplt              = 161;
+//  private static final int opc_if_icmpge              = 162;
+//  private static final int opc_if_icmpgt              = 163;
+//  private static final int opc_if_icmple              = 164;
+//  private static final int opc_if_acmpeq              = 165;
+//  private static final int opc_if_acmpne              = 166;
+//  private static final int opc_goto                   = 167;
+//  private static final int opc_jsr                    = 168;
+//  private static final int opc_ret                    = 169;
+//  private static final int opc_tableswitch            = 170;
+//  private static final int opc_lookupswitch           = 171;
+    private static final int opc_ireturn                = 172;
+    private static final int opc_lreturn                = 173;
+    private static final int opc_freturn                = 174;
+    private static final int opc_dreturn                = 175;
+    private static final int opc_areturn                = 176;
+    private static final int opc_return                 = 177;
+    private static final int opc_getstatic              = 178;
+    private static final int opc_putstatic              = 179;
+    private static final int opc_getfield               = 180;
+//  private static final int opc_putfield               = 181;
+    private static final int opc_invokevirtual          = 182;
+    private static final int opc_invokespecial          = 183;
+    private static final int opc_invokestatic           = 184;
+    private static final int opc_invokeinterface        = 185;
+    private static final int opc_new                    = 187;
+//  private static final int opc_newarray               = 188;
+    private static final int opc_anewarray              = 189;
+//  private static final int opc_arraylength            = 190;
+    private static final int opc_athrow                 = 191;
+    private static final int opc_checkcast              = 192;
+//  private static final int opc_instanceof             = 193;
+//  private static final int opc_monitorenter           = 194;
+//  private static final int opc_monitorexit            = 195;
+    private static final int opc_wide                   = 196;
+//  private static final int opc_multianewarray         = 197;
+//  private static final int opc_ifnull                 = 198;
+//  private static final int opc_ifnonnull              = 199;
+//  private static final int opc_goto_w                 = 200;
+//  private static final int opc_jsr_w                  = 201;
+
+    // end of constants copied from sun.tools.java.RuntimeConstants
+
+    /** name of the superclass of proxy classes */
+    private static final String superclassName = "java/lang/reflect/Proxy";
+
+    /** name of field for storing a proxy instance's invocation handler */
+    private static final String handlerFieldName = "h";
+
+    /** debugging flag for saving generated class files */
+    private static final boolean saveGeneratedFiles =
+        java.security.AccessController.doPrivileged(
+            new GetBooleanAction(
+                "jdk.proxy.ProxyGenerator.saveGeneratedFiles")).booleanValue();
+
+    /**
+     * Generate a public proxy class given a name and a list of proxy interfaces.
+     */
+    static byte[] generateProxyClass(final String name,
+                                     List<Class<?>> interfaces) {
+        return generateProxyClass(name, interfaces, (ACC_PUBLIC | ACC_FINAL | ACC_SUPER));
+    }
+
+    /**
+     * Generate a proxy class given a name and a list of proxy interfaces.
+     *
+     * @param name        the class name of the proxy class
+     * @param interfaces  proxy interfaces
+     * @param accessFlags access flags of the proxy class
+    */
+    static byte[] generateProxyClass(final String name,
+                                     List<Class<?>> interfaces,
+                                     int accessFlags)
+    {
+        ProxyGenerator_v49 gen = new ProxyGenerator_v49(name, interfaces, accessFlags);
+        final byte[] classFile = gen.generateClassFile();
+
+        if (saveGeneratedFiles) {
+            java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
+                    try {
+                        int i = name.lastIndexOf('.');
+                        Path path;
+                        if (i > 0) {
+                            Path dir = Path.of(name.substring(0, i).replace('.', File.separatorChar));
+                            Files.createDirectories(dir);
+                            path = dir.resolve(name.substring(i+1, name.length()) + ".class");
+                        } else {
+                            path = Path.of(name + ".class");
+                        }
+                        Files.write(path, classFile);
+                        return null;
+                    } catch (IOException e) {
+                        throw new InternalError(
+                            "I/O exception saving generated file: " + e);
+                    }
+                }
+            });
+        }
+
+        return classFile;
+    }
+
+    /* preloaded Method objects for methods in java.lang.Object */
+    private static Method hashCodeMethod;
+    private static Method equalsMethod;
+    private static Method toStringMethod;
+    static {
+        try {
+            hashCodeMethod = Object.class.getMethod("hashCode");
+            equalsMethod =
+                Object.class.getMethod("equals", new Class<?>[] { Object.class });
+            toStringMethod = Object.class.getMethod("toString");
+        } catch (NoSuchMethodException e) {
+            throw new NoSuchMethodError(e.getMessage());
+        }
+    }
+
+    /** name of proxy class */
+    private String className;
+
+    /** proxy interfaces */
+    private List<Class<?>> interfaces;
+
+    /** proxy class access flags */
+    private int accessFlags;
+
+    /** constant pool of class being generated */
+    private ConstantPool cp = new ConstantPool();
+
+    /** FieldInfo struct for each field of generated class */
+    private List<FieldInfo> fields = new ArrayList<>();
+
+    /** MethodInfo struct for each method of generated class */
+    private List<MethodInfo> methods = new ArrayList<>();
+
+    /**
+     * maps method signature string to list of ProxyMethod objects for
+     * proxy methods with that signature
+     */
+    private Map<String, List<ProxyMethod>> proxyMethods = new LinkedHashMap<>();
+
+    /** count of ProxyMethod objects added to proxyMethods */
+    private int proxyMethodCount = 0;
+
+    /**
+     * Construct a ProxyGenerator to generate a proxy class with the
+     * specified name and for the given interfaces.
+     *
+     * A ProxyGenerator object contains the state for the ongoing
+     * generation of a particular proxy class.
+     */
+    ProxyGenerator_v49(String className, List<Class<?>> interfaces, int accessFlags) {
+        this.className = className;
+        this.interfaces = interfaces;
+        this.accessFlags = accessFlags;
+    }
+
+    /**
+     * Generate a class file for the proxy class.  This method drives the
+     * class file generation process.
+     */
+    private byte[] generateClassFile() {
+
+        /* ============================================================
+         * Step 1: Assemble ProxyMethod objects for all methods to
+         * generate proxy dispatching code for.
+         */
+
+        /*
+         * Record that proxy methods are needed for the hashCode, equals,
+         * and toString methods of java.lang.Object.  This is done before
+         * the methods from the proxy interfaces so that the methods from
+         * java.lang.Object take precedence over duplicate methods in the
+         * proxy interfaces.
+         */
+        addProxyMethod(hashCodeMethod, Object.class);
+        addProxyMethod(equalsMethod, Object.class);
+        addProxyMethod(toStringMethod, Object.class);
+
+        /*
+         * Now record all of the methods from the proxy interfaces, giving
+         * earlier interfaces precedence over later ones with duplicate
+         * methods.
+         */
+        for (Class<?> intf : interfaces) {
+            for (Method m : intf.getMethods()) {
+                if (!Modifier.isStatic(m.getModifiers())) {
+                    addProxyMethod(m, intf);
+                }
+            }
+        }
+
+        /*
+         * For each set of proxy methods with the same signature,
+         * verify that the methods' return types are compatible.
+         */
+        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
+            checkReturnTypes(sigmethods);
+        }
+
+        /* ============================================================
+         * Step 2: Assemble FieldInfo and MethodInfo structs for all of
+         * fields and methods in the class we are generating.
+         */
+        try {
+            methods.add(generateConstructor());
+
+            for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
+                for (ProxyMethod pm : sigmethods) {
+
+                    // add static field for method's Method object
+                    fields.add(new FieldInfo(pm.methodFieldName,
+                        "Ljava/lang/reflect/Method;",
+                         ACC_PRIVATE | ACC_STATIC));
+
+                    // generate code for proxy method and add it
+                    methods.add(pm.generateMethod());
+                }
+            }
+
+            methods.add(generateStaticInitializer());
+
+        } catch (IOException e) {
+            throw new InternalError("unexpected I/O Exception", e);
+        }
+
+        if (methods.size() > 65535) {
+            throw new IllegalArgumentException("method limit exceeded");
+        }
+        if (fields.size() > 65535) {
+            throw new IllegalArgumentException("field limit exceeded");
+        }
+
+        /* ============================================================
+         * Step 3: Write the final class file.
+         */
+
+        /*
+         * Make sure that constant pool indexes are reserved for the
+         * following items before starting to write the final class file.
+         */
+        cp.getClass(dotToSlash(className));
+        cp.getClass(superclassName);
+        for (Class<?> intf: interfaces) {
+            cp.getClass(dotToSlash(intf.getName()));
+        }
+
+        /*
+         * Disallow new constant pool additions beyond this point, since
+         * we are about to write the final constant pool table.
+         */
+        cp.setReadOnly();
+
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        DataOutputStream dout = new DataOutputStream(bout);
+
+        try {
+            /*
+             * Write all the items of the "ClassFile" structure.
+             * See JVMS section 4.1.
+             */
+                                        // u4 magic;
+            dout.writeInt(0xCAFEBABE);
+                                        // u2 minor_version;
+            dout.writeShort(CLASSFILE_MINOR_VERSION);
+                                        // u2 major_version;
+            dout.writeShort(CLASSFILE_MAJOR_VERSION);
+
+            cp.write(dout);             // (write constant pool)
+
+                                        // u2 access_flags;
+            dout.writeShort(accessFlags);
+                                        // u2 this_class;
+            dout.writeShort(cp.getClass(dotToSlash(className)));
+                                        // u2 super_class;
+            dout.writeShort(cp.getClass(superclassName));
+
+                                        // u2 interfaces_count;
+            dout.writeShort(interfaces.size());
+                                        // u2 interfaces[interfaces_count];
+            for (Class<?> intf : interfaces) {
+                dout.writeShort(cp.getClass(
+                    dotToSlash(intf.getName())));
+            }
+
+                                        // u2 fields_count;
+            dout.writeShort(fields.size());
+                                        // field_info fields[fields_count];
+            for (FieldInfo f : fields) {
+                f.write(dout);
+            }
+
+                                        // u2 methods_count;
+            dout.writeShort(methods.size());
+                                        // method_info methods[methods_count];
+            for (MethodInfo m : methods) {
+                m.write(dout);
+            }
+
+                                         // u2 attributes_count;
+            dout.writeShort(0); // (no ClassFile attributes for proxy classes)
+
+        } catch (IOException e) {
+            throw new InternalError("unexpected I/O Exception", e);
+        }
+
+        return bout.toByteArray();
+    }
+
+    /**
+     * Add another method to be proxied, either by creating a new
+     * ProxyMethod object or augmenting an old one for a duplicate
+     * method.
+     *
+     * "fromClass" indicates the proxy interface that the method was
+     * found through, which may be different from (a subinterface of)
+     * the method's "declaring class".  Note that the first Method
+     * object passed for a given name and descriptor identifies the
+     * Method object (and thus the declaring class) that will be
+     * passed to the invocation handler's "invoke" method for a given
+     * set of duplicate methods.
+     */
+    private void addProxyMethod(Method m, Class<?> fromClass) {
+        String name = m.getName();
+        Class<?>[] parameterTypes = m.getParameterTypes();
+        Class<?> returnType = m.getReturnType();
+        Class<?>[] exceptionTypes = m.getExceptionTypes();
+
+        String sig = name + getParameterDescriptors(parameterTypes);
+        List<ProxyMethod> sigmethods = proxyMethods.get(sig);
+        if (sigmethods != null) {
+            for (ProxyMethod pm : sigmethods) {
+                if (returnType == pm.returnType) {
+                    /*
+                     * Found a match: reduce exception types to the
+                     * greatest set of exceptions that can thrown
+                     * compatibly with the throws clauses of both
+                     * overridden methods.
+                     */
+                    List<Class<?>> legalExceptions = new ArrayList<>();
+                    collectCompatibleTypes(
+                        exceptionTypes, pm.exceptionTypes, legalExceptions);
+                    collectCompatibleTypes(
+                        pm.exceptionTypes, exceptionTypes, legalExceptions);
+                    pm.exceptionTypes = new Class<?>[legalExceptions.size()];
+                    pm.exceptionTypes =
+                        legalExceptions.toArray(pm.exceptionTypes);
+                    return;
+                }
+            }
+        } else {
+            sigmethods = new ArrayList<>(3);
+            proxyMethods.put(sig, sigmethods);
+        }
+        sigmethods.add(new ProxyMethod(name, parameterTypes, returnType,
+                                       exceptionTypes, fromClass));
+    }
+
+    /**
+     * For a given set of proxy methods with the same signature, check
+     * that their return types are compatible according to the Proxy
+     * specification.
+     *
+     * Specifically, if there is more than one such method, then all
+     * of the return types must be reference types, and there must be
+     * one return type that is assignable to each of the rest of them.
+     */
+    private static void checkReturnTypes(List<ProxyMethod> methods) {
+        /*
+         * If there is only one method with a given signature, there
+         * cannot be a conflict.  This is the only case in which a
+         * primitive (or void) return type is allowed.
+         */
+        if (methods.size() < 2) {
+            return;
+        }
+
+        /*
+         * List of return types that are not yet known to be
+         * assignable from ("covered" by) any of the others.
+         */
+        LinkedList<Class<?>> uncoveredReturnTypes = new LinkedList<>();
+
+    nextNewReturnType:
+        for (ProxyMethod pm : methods) {
+            Class<?> newReturnType = pm.returnType;
+            if (newReturnType.isPrimitive()) {
+                throw new IllegalArgumentException(
+                    "methods with same signature " +
+                    getFriendlyMethodSignature(pm.methodName,
+                                               pm.parameterTypes) +
+                    " but incompatible return types: " +
+                    newReturnType.getName() + " and others");
+            }
+            boolean added = false;
+
+            /*
+             * Compare the new return type to the existing uncovered
+             * return types.
+             */
+            ListIterator<Class<?>> liter = uncoveredReturnTypes.listIterator();
+            while (liter.hasNext()) {
+                Class<?> uncoveredReturnType = liter.next();
+
+                /*
+                 * If an existing uncovered return type is assignable
+                 * to this new one, then we can forget the new one.
+                 */
+                if (newReturnType.isAssignableFrom(uncoveredReturnType)) {
+                    assert !added;
+                    continue nextNewReturnType;
+                }
+
+                /*
+                 * If the new return type is assignable to an existing
+                 * uncovered one, then should replace the existing one
+                 * with the new one (or just forget the existing one,
+                 * if the new one has already be put in the list).
+                 */
+                if (uncoveredReturnType.isAssignableFrom(newReturnType)) {
+                    // (we can assume that each return type is unique)
+                    if (!added) {
+                        liter.set(newReturnType);
+                        added = true;
+                    } else {
+                        liter.remove();
+                    }
+                }
+            }
+
+            /*
+             * If we got through the list of existing uncovered return
+             * types without an assignability relationship, then add
+             * the new return type to the list of uncovered ones.
+             */
+            if (!added) {
+                uncoveredReturnTypes.add(newReturnType);
+            }
+        }
+
+        /*
+         * We shouldn't end up with more than one return type that is
+         * not assignable from any of the others.
+         */
+        if (uncoveredReturnTypes.size() > 1) {
+            ProxyMethod pm = methods.get(0);
+            throw new IllegalArgumentException(
+                "methods with same signature " +
+                getFriendlyMethodSignature(pm.methodName, pm.parameterTypes) +
+                " but incompatible return types: " + uncoveredReturnTypes);
+        }
+    }
+
+    /**
+     * A FieldInfo object contains information about a particular field
+     * in the class being generated.  The class mirrors the data items of
+     * the "field_info" structure of the class file format (see JVMS 4.5).
+     */
+    private class FieldInfo {
+        public int accessFlags;
+        public String name;
+        public String descriptor;
+
+        public FieldInfo(String name, String descriptor, int accessFlags) {
+            this.name = name;
+            this.descriptor = descriptor;
+            this.accessFlags = accessFlags;
+
+            /*
+             * Make sure that constant pool indexes are reserved for the
+             * following items before starting to write the final class file.
+             */
+            cp.getUtf8(name);
+            cp.getUtf8(descriptor);
+        }
+
+        public void write(DataOutputStream out) throws IOException {
+            /*
+             * Write all the items of the "field_info" structure.
+             * See JVMS section 4.5.
+             */
+                                        // u2 access_flags;
+            out.writeShort(accessFlags);
+                                        // u2 name_index;
+            out.writeShort(cp.getUtf8(name));
+                                        // u2 descriptor_index;
+            out.writeShort(cp.getUtf8(descriptor));
+                                        // u2 attributes_count;
+            out.writeShort(0);  // (no field_info attributes for proxy classes)
+        }
+    }
+
+    /**
+     * An ExceptionTableEntry object holds values for the data items of
+     * an entry in the "exception_table" item of the "Code" attribute of
+     * "method_info" structures (see JVMS 4.7.3).
+     */
+    private static class ExceptionTableEntry {
+        public short startPc;
+        public short endPc;
+        public short handlerPc;
+        public short catchType;
+
+        public ExceptionTableEntry(short startPc, short endPc,
+                                   short handlerPc, short catchType)
+        {
+            this.startPc = startPc;
+            this.endPc = endPc;
+            this.handlerPc = handlerPc;
+            this.catchType = catchType;
+        }
+    };
+
+    /**
+     * A MethodInfo object contains information about a particular method
+     * in the class being generated.  This class mirrors the data items of
+     * the "method_info" structure of the class file format (see JVMS 4.6).
+     */
+    private class MethodInfo {
+        public int accessFlags;
+        public String name;
+        public String descriptor;
+        public short maxStack;
+        public short maxLocals;
+        public ByteArrayOutputStream code = new ByteArrayOutputStream();
+        public List<ExceptionTableEntry> exceptionTable =
+            new ArrayList<ExceptionTableEntry>();
+        public short[] declaredExceptions;
+
+        public MethodInfo(String name, String descriptor, int accessFlags) {
+            this.name = name;
+            this.descriptor = descriptor;
+            this.accessFlags = accessFlags;
+
+            /*
+             * Make sure that constant pool indexes are reserved for the
+             * following items before starting to write the final class file.
+             */
+            cp.getUtf8(name);
+            cp.getUtf8(descriptor);
+            cp.getUtf8("Code");
+            cp.getUtf8("Exceptions");
+        }
+
+        public void write(DataOutputStream out) throws IOException {
+            /*
+             * Write all the items of the "method_info" structure.
+             * See JVMS section 4.6.
+             */
+                                        // u2 access_flags;
+            out.writeShort(accessFlags);
+                                        // u2 name_index;
+            out.writeShort(cp.getUtf8(name));
+                                        // u2 descriptor_index;
+            out.writeShort(cp.getUtf8(descriptor));
+                                        // u2 attributes_count;
+            out.writeShort(2);  // (two method_info attributes:)
+
+            // Write "Code" attribute. See JVMS section 4.7.3.
+
+                                        // u2 attribute_name_index;
+            out.writeShort(cp.getUtf8("Code"));
+                                        // u4 attribute_length;
+            out.writeInt(12 + code.size() + 8 * exceptionTable.size());
+                                        // u2 max_stack;
+            out.writeShort(maxStack);
+                                        // u2 max_locals;
+            out.writeShort(maxLocals);
+                                        // u2 code_length;
+            out.writeInt(code.size());
+                                        // u1 code[code_length];
+            code.writeTo(out);
+                                        // u2 exception_table_length;
+            out.writeShort(exceptionTable.size());
+            for (ExceptionTableEntry e : exceptionTable) {
+                                        // u2 start_pc;
+                out.writeShort(e.startPc);
+                                        // u2 end_pc;
+                out.writeShort(e.endPc);
+                                        // u2 handler_pc;
+                out.writeShort(e.handlerPc);
+                                        // u2 catch_type;
+                out.writeShort(e.catchType);
+            }
+                                        // u2 attributes_count;
+            out.writeShort(0);
+
+            // write "Exceptions" attribute.  See JVMS section 4.7.4.
+
+                                        // u2 attribute_name_index;
+            out.writeShort(cp.getUtf8("Exceptions"));
+                                        // u4 attributes_length;
+            out.writeInt(2 + 2 * declaredExceptions.length);
+                                        // u2 number_of_exceptions;
+            out.writeShort(declaredExceptions.length);
+                        // u2 exception_index_table[number_of_exceptions];
+            for (short value : declaredExceptions) {
+                out.writeShort(value);
+            }
+        }
+
+    }
+
+    /**
+     * A ProxyMethod object represents a proxy method in the proxy class
+     * being generated: a method whose implementation will encode and
+     * dispatch invocations to the proxy instance's invocation handler.
+     */
+    private class ProxyMethod {
+
+        public String methodName;
+        public Class<?>[] parameterTypes;
+        public Class<?> returnType;
+        public Class<?>[] exceptionTypes;
+        public Class<?> fromClass;
+        public String methodFieldName;
+
+        private ProxyMethod(String methodName, Class<?>[] parameterTypes,
+                            Class<?> returnType, Class<?>[] exceptionTypes,
+                            Class<?> fromClass)
+        {
+            this.methodName = methodName;
+            this.parameterTypes = parameterTypes;
+            this.returnType = returnType;
+            this.exceptionTypes = exceptionTypes;
+            this.fromClass = fromClass;
+            this.methodFieldName = "m" + proxyMethodCount++;
+        }
+
+        /**
+         * Return a MethodInfo object for this method, including generating
+         * the code and exception table entry.
+         */
+        private MethodInfo generateMethod() throws IOException {
+            String desc = getMethodDescriptor(parameterTypes, returnType);
+            MethodInfo minfo = new MethodInfo(methodName, desc,
+                ACC_PUBLIC | ACC_FINAL);
+
+            int[] parameterSlot = new int[parameterTypes.length];
+            int nextSlot = 1;
+            for (int i = 0; i < parameterSlot.length; i++) {
+                parameterSlot[i] = nextSlot;
+                nextSlot += getWordsPerType(parameterTypes[i]);
+            }
+            int localSlot0 = nextSlot;
+            short pc, tryBegin = 0, tryEnd;
+
+            DataOutputStream out = new DataOutputStream(minfo.code);
+
+            code_aload(0, out);
+
+            out.writeByte(opc_getfield);
+            out.writeShort(cp.getFieldRef(
+                superclassName,
+                handlerFieldName, "Ljava/lang/reflect/InvocationHandler;"));
+
+            code_aload(0, out);
+
+            out.writeByte(opc_getstatic);
+            out.writeShort(cp.getFieldRef(
+                dotToSlash(className),
+                methodFieldName, "Ljava/lang/reflect/Method;"));
+
+            if (parameterTypes.length > 0) {
+
+                code_ipush(parameterTypes.length, out);
+
+                out.writeByte(opc_anewarray);
+                out.writeShort(cp.getClass("java/lang/Object"));
+
+                for (int i = 0; i < parameterTypes.length; i++) {
+
+                    out.writeByte(opc_dup);
+
+                    code_ipush(i, out);
+
+                    codeWrapArgument(parameterTypes[i], parameterSlot[i], out);
+
+                    out.writeByte(opc_aastore);
+                }
+            } else {
+
+                out.writeByte(opc_aconst_null);
+            }
+
+            out.writeByte(opc_invokeinterface);
+            out.writeShort(cp.getInterfaceMethodRef(
+                "java/lang/reflect/InvocationHandler",
+                "invoke",
+                "(Ljava/lang/Object;Ljava/lang/reflect/Method;" +
+                    "[Ljava/lang/Object;)Ljava/lang/Object;"));
+            out.writeByte(4);
+            out.writeByte(0);
+
+            if (returnType == void.class) {
+
+                out.writeByte(opc_pop);
+
+                out.writeByte(opc_return);
+
+            } else {
+
+                codeUnwrapReturnValue(returnType, out);
+            }
+
+            tryEnd = pc = (short) minfo.code.size();
+
+            List<Class<?>> catchList = computeUniqueCatchList(exceptionTypes);
+            if (catchList.size() > 0) {
+
+                for (Class<?> ex : catchList) {
+                    minfo.exceptionTable.add(new ExceptionTableEntry(
+                        tryBegin, tryEnd, pc,
+                        cp.getClass(dotToSlash(ex.getName()))));
+                }
+
+                out.writeByte(opc_athrow);
+
+                pc = (short) minfo.code.size();
+
+                minfo.exceptionTable.add(new ExceptionTableEntry(
+                    tryBegin, tryEnd, pc, cp.getClass("java/lang/Throwable")));
+
+                code_astore(localSlot0, out);
+
+                out.writeByte(opc_new);
+                out.writeShort(cp.getClass(
+                    "java/lang/reflect/UndeclaredThrowableException"));
+
+                out.writeByte(opc_dup);
+
+                code_aload(localSlot0, out);
+
+                out.writeByte(opc_invokespecial);
+
+                out.writeShort(cp.getMethodRef(
+                    "java/lang/reflect/UndeclaredThrowableException",
+                    "<init>", "(Ljava/lang/Throwable;)V"));
+
+                out.writeByte(opc_athrow);
+            }
+
+            if (minfo.code.size() > 65535) {
+                throw new IllegalArgumentException("code size limit exceeded");
+            }
+
+            minfo.maxStack = 10;
+            minfo.maxLocals = (short) (localSlot0 + 1);
+            minfo.declaredExceptions = new short[exceptionTypes.length];
+            for (int i = 0; i < exceptionTypes.length; i++) {
+                minfo.declaredExceptions[i] = cp.getClass(
+                    dotToSlash(exceptionTypes[i].getName()));
+            }
+
+            return minfo;
+        }
+
+        /**
+         * Generate code for wrapping an argument of the given type
+         * whose value can be found at the specified local variable
+         * index, in order for it to be passed (as an Object) to the
+         * invocation handler's "invoke" method.  The code is written
+         * to the supplied stream.
+         */
+        private void codeWrapArgument(Class<?> type, int slot,
+                                      DataOutputStream out)
+            throws IOException
+        {
+            if (type.isPrimitive()) {
+                PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
+
+                if (type == int.class ||
+                    type == boolean.class ||
+                    type == byte.class ||
+                    type == char.class ||
+                    type == short.class)
+                {
+                    code_iload(slot, out);
+                } else if (type == long.class) {
+                    code_lload(slot, out);
+                } else if (type == float.class) {
+                    code_fload(slot, out);
+                } else if (type == double.class) {
+                    code_dload(slot, out);
+                } else {
+                    throw new AssertionError();
+                }
+
+                out.writeByte(opc_invokestatic);
+                out.writeShort(cp.getMethodRef(
+                    prim.wrapperClassName,
+                    "valueOf", prim.wrapperValueOfDesc));
+
+            } else {
+
+                code_aload(slot, out);
+            }
+        }
+
+        /**
+         * Generate code for unwrapping a return value of the given
+         * type from the invocation handler's "invoke" method (as type
+         * Object) to its correct type.  The code is written to the
+         * supplied stream.
+         */
+        private void codeUnwrapReturnValue(Class<?> type, DataOutputStream out)
+            throws IOException
+        {
+            if (type.isPrimitive()) {
+                PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type);
+
+                out.writeByte(opc_checkcast);
+                out.writeShort(cp.getClass(prim.wrapperClassName));
+
+                out.writeByte(opc_invokevirtual);
+                out.writeShort(cp.getMethodRef(
+                    prim.wrapperClassName,
+                    prim.unwrapMethodName, prim.unwrapMethodDesc));
+
+                if (type == int.class ||
+                    type == boolean.class ||
+                    type == byte.class ||
+                    type == char.class ||
+                    type == short.class)
+                {
+                    out.writeByte(opc_ireturn);
+                } else if (type == long.class) {
+                    out.writeByte(opc_lreturn);
+                } else if (type == float.class) {
+                    out.writeByte(opc_freturn);
+                } else if (type == double.class) {
+                    out.writeByte(opc_dreturn);
+                } else {
+                    throw new AssertionError();
+                }
+
+            } else {
+
+                out.writeByte(opc_checkcast);
+                out.writeShort(cp.getClass(dotToSlash(type.getName())));
+
+                out.writeByte(opc_areturn);
+            }
+        }
+
+        /**
+         * Generate code for initializing the static field that stores
+         * the Method object for this proxy method.  The code is written
+         * to the supplied stream.
+         */
+        private void codeFieldInitialization(DataOutputStream out)
+            throws IOException
+        {
+            codeClassForName(fromClass, out);
+
+            code_ldc(cp.getString(methodName), out);
+
+            code_ipush(parameterTypes.length, out);
+
+            out.writeByte(opc_anewarray);
+            out.writeShort(cp.getClass("java/lang/Class"));
+
+            for (int i = 0; i < parameterTypes.length; i++) {
+
+                out.writeByte(opc_dup);
+
+                code_ipush(i, out);
+
+                if (parameterTypes[i].isPrimitive()) {
+                    PrimitiveTypeInfo prim =
+                        PrimitiveTypeInfo.get(parameterTypes[i]);
+
+                    out.writeByte(opc_getstatic);
+                    out.writeShort(cp.getFieldRef(
+                        prim.wrapperClassName, "TYPE", "Ljava/lang/Class;"));
+
+                } else {
+                    codeClassForName(parameterTypes[i], out);
+                }
+
+                out.writeByte(opc_aastore);
+            }
+
+            out.writeByte(opc_invokevirtual);
+            out.writeShort(cp.getMethodRef(
+                "java/lang/Class",
+                "getMethod",
+                "(Ljava/lang/String;[Ljava/lang/Class;)" +
+                "Ljava/lang/reflect/Method;"));
+
+            out.writeByte(opc_putstatic);
+            out.writeShort(cp.getFieldRef(
+                dotToSlash(className),
+                methodFieldName, "Ljava/lang/reflect/Method;"));
+        }
+    }
+
+    /**
+     * Generate the constructor method for the proxy class.
+     */
+    private MethodInfo generateConstructor() throws IOException {
+        MethodInfo minfo = new MethodInfo(
+            "<init>", "(Ljava/lang/reflect/InvocationHandler;)V",
+            ACC_PUBLIC);
+
+        DataOutputStream out = new DataOutputStream(minfo.code);
+
+        code_aload(0, out);
+
+        code_aload(1, out);
+
+        out.writeByte(opc_invokespecial);
+        out.writeShort(cp.getMethodRef(
+            superclassName,
+            "<init>", "(Ljava/lang/reflect/InvocationHandler;)V"));
+
+        out.writeByte(opc_return);
+
+        minfo.maxStack = 10;
+        minfo.maxLocals = 2;
+        minfo.declaredExceptions = new short[0];
+
+        return minfo;
+    }
+
+    /**
+     * Generate the static initializer method for the proxy class.
+     */
+    private MethodInfo generateStaticInitializer() throws IOException {
+        MethodInfo minfo = new MethodInfo(
+            "<clinit>", "()V", ACC_STATIC);
+
+        int localSlot0 = 1;
+        short pc, tryBegin = 0, tryEnd;
+
+        DataOutputStream out = new DataOutputStream(minfo.code);
+
+        for (List<ProxyMethod> sigmethods : proxyMethods.values()) {
+            for (ProxyMethod pm : sigmethods) {
+                pm.codeFieldInitialization(out);
+            }
+        }
+
+        out.writeByte(opc_return);
+
+        tryEnd = pc = (short) minfo.code.size();
+
+        minfo.exceptionTable.add(new ExceptionTableEntry(
+            tryBegin, tryEnd, pc,
+            cp.getClass("java/lang/NoSuchMethodException")));
+
+        code_astore(localSlot0, out);
+
+        out.writeByte(opc_new);
+        out.writeShort(cp.getClass("java/lang/NoSuchMethodError"));
+
+        out.writeByte(opc_dup);
+
+        code_aload(localSlot0, out);
+
+        out.writeByte(opc_invokevirtual);
+        out.writeShort(cp.getMethodRef(
+            "java/lang/Throwable", "getMessage", "()Ljava/lang/String;"));
+
+        out.writeByte(opc_invokespecial);
+        out.writeShort(cp.getMethodRef(
+            "java/lang/NoSuchMethodError", "<init>", "(Ljava/lang/String;)V"));
+
+        out.writeByte(opc_athrow);
+
+        pc = (short) minfo.code.size();
+
+        minfo.exceptionTable.add(new ExceptionTableEntry(
+            tryBegin, tryEnd, pc,
+            cp.getClass("java/lang/ClassNotFoundException")));
+
+        code_astore(localSlot0, out);
+
+        out.writeByte(opc_new);
+        out.writeShort(cp.getClass("java/lang/NoClassDefFoundError"));
+
+        out.writeByte(opc_dup);
+
+        code_aload(localSlot0, out);
+
+        out.writeByte(opc_invokevirtual);
+        out.writeShort(cp.getMethodRef(
+            "java/lang/Throwable", "getMessage", "()Ljava/lang/String;"));
+
+        out.writeByte(opc_invokespecial);
+        out.writeShort(cp.getMethodRef(
+            "java/lang/NoClassDefFoundError",
+            "<init>", "(Ljava/lang/String;)V"));
+
+        out.writeByte(opc_athrow);
+
+        if (minfo.code.size() > 65535) {
+            throw new IllegalArgumentException("code size limit exceeded");
+        }
+
+        minfo.maxStack = 10;
+        minfo.maxLocals = (short) (localSlot0 + 1);
+        minfo.declaredExceptions = new short[0];
+
+        return minfo;
+    }
+
+
+    /*
+     * =============== Code Generation Utility Methods ===============
+     */
+
+    /*
+     * The following methods generate code for the load or store operation
+     * indicated by their name for the given local variable.  The code is
+     * written to the supplied stream.
+     */
+
+    private void code_iload(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_iload, opc_iload_0, out);
+    }
+
+    private void code_lload(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_lload, opc_lload_0, out);
+    }
+
+    private void code_fload(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_fload, opc_fload_0, out);
+    }
+
+    private void code_dload(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_dload, opc_dload_0, out);
+    }
+
+    private void code_aload(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_aload, opc_aload_0, out);
+    }
+
+//  private void code_istore(int lvar, DataOutputStream out)
+//      throws IOException
+//  {
+//      codeLocalLoadStore(lvar, opc_istore, opc_istore_0, out);
+//  }
+
+//  private void code_lstore(int lvar, DataOutputStream out)
+//      throws IOException
+//  {
+//      codeLocalLoadStore(lvar, opc_lstore, opc_lstore_0, out);
+//  }
+
+//  private void code_fstore(int lvar, DataOutputStream out)
+//      throws IOException
+//  {
+//      codeLocalLoadStore(lvar, opc_fstore, opc_fstore_0, out);
+//  }
+
+//  private void code_dstore(int lvar, DataOutputStream out)
+//      throws IOException
+//  {
+//      codeLocalLoadStore(lvar, opc_dstore, opc_dstore_0, out);
+//  }
+
+    private void code_astore(int lvar, DataOutputStream out)
+        throws IOException
+    {
+        codeLocalLoadStore(lvar, opc_astore, opc_astore_0, out);
+    }
+
+    /**
+     * Generate code for a load or store instruction for the given local
+     * variable.  The code is written to the supplied stream.
+     *
+     * "opcode" indicates the opcode form of the desired load or store
+     * instruction that takes an explicit local variable index, and
+     * "opcode_0" indicates the corresponding form of the instruction
+     * with the implicit index 0.
+     */
+    private void codeLocalLoadStore(int lvar, int opcode, int opcode_0,
+                                    DataOutputStream out)
+        throws IOException
+    {
+        assert lvar >= 0 && lvar <= 0xFFFF;
+        if (lvar <= 3) {
+            out.writeByte(opcode_0 + lvar);
+        } else if (lvar <= 0xFF) {
+            out.writeByte(opcode);
+            out.writeByte(lvar & 0xFF);
+        } else {
+            /*
+             * Use the "wide" instruction modifier for local variable
+             * indexes that do not fit into an unsigned byte.
+             */
+            out.writeByte(opc_wide);
+            out.writeByte(opcode);
+            out.writeShort(lvar & 0xFFFF);
+        }
+    }
+
+    /**
+     * Generate code for an "ldc" instruction for the given constant pool
+     * index (the "ldc_w" instruction is used if the index does not fit
+     * into an unsigned byte).  The code is written to the supplied stream.
+     */
+    private void code_ldc(int index, DataOutputStream out)
+        throws IOException
+    {
+        assert index >= 0 && index <= 0xFFFF;
+        if (index <= 0xFF) {
+            out.writeByte(opc_ldc);
+            out.writeByte(index & 0xFF);
+        } else {
+            out.writeByte(opc_ldc_w);
+            out.writeShort(index & 0xFFFF);
+        }
+    }
+
+    /**
+     * Generate code to push a constant integer value on to the operand
+     * stack, using the "iconst_<i>", "bipush", or "sipush" instructions
+     * depending on the size of the value.  The code is written to the
+     * supplied stream.
+     */
+    private void code_ipush(int value, DataOutputStream out)
+        throws IOException
+    {
+        if (value >= -1 && value <= 5) {
+            out.writeByte(opc_iconst_0 + value);
+        } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
+            out.writeByte(opc_bipush);
+            out.writeByte(value & 0xFF);
+        } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
+            out.writeByte(opc_sipush);
+            out.writeShort(value & 0xFFFF);
+        } else {
+            throw new AssertionError();
+        }
+    }
+
+    /**
+     * Generate code to invoke the Class.forName with the name of the given
+     * class to get its Class object at runtime.  The code is written to
+     * the supplied stream.  Note that the code generated by this method
+     * may cause the checked ClassNotFoundException to be thrown.
+     */
+    private void codeClassForName(Class<?> cl, DataOutputStream out)
+        throws IOException
+    {
+        code_ldc(cp.getString(cl.getName()), out);
+
+        out.writeByte(opc_invokestatic);
+        out.writeShort(cp.getMethodRef(
+            "java/lang/Class",
+            "forName", "(Ljava/lang/String;)Ljava/lang/Class;"));
+    }
+
+
+    /*
+     * ==================== General Utility Methods ====================
+     */
+
+    /**
+     * Convert a fully qualified class name that uses '.' as the package
+     * separator, the external representation used by the Java language
+     * and APIs, to a fully qualified class name that uses '/' as the
+     * package separator, the representation used in the class file
+     * format (see JVMS section 4.2).
+     */
+    private static String dotToSlash(String name) {
+        return name.replace('.', '/');
+    }
+
+    /**
+     * Return the "method descriptor" string for a method with the given
+     * parameter types and return type.  See JVMS section 4.3.3.
+     */
+    private static String getMethodDescriptor(Class<?>[] parameterTypes,
+                                              Class<?> returnType)
+    {
+        return getParameterDescriptors(parameterTypes) +
+            ((returnType == void.class) ? "V" : getFieldType(returnType));
+    }
+
+    /**
+     * Return the list of "parameter descriptor" strings enclosed in
+     * parentheses corresponding to the given parameter types (in other
+     * words, a method descriptor without a return descriptor).  This
+     * string is useful for constructing string keys for methods without
+     * regard to their return type.
+     */
+    private static String getParameterDescriptors(Class<?>[] parameterTypes) {
+        StringBuilder desc = new StringBuilder("(");
+        for (int i = 0; i < parameterTypes.length; i++) {
+            desc.append(getFieldType(parameterTypes[i]));
+        }
+        desc.append(')');
+        return desc.toString();
+    }
+
+    /**
+     * Return the "field type" string for the given type, appropriate for
+     * a field descriptor, a parameter descriptor, or a return descriptor
+     * other than "void".  See JVMS section 4.3.2.
+     */
+    private static String getFieldType(Class<?> type) {
+        if (type.isPrimitive()) {
+            return PrimitiveTypeInfo.get(type).baseTypeString;
+        } else if (type.isArray()) {
+            /*
+             * According to JLS 20.3.2, the getName() method on Class does
+             * return the VM type descriptor format for array classes (only);
+             * using that should be quicker than the otherwise obvious code:
+             *
+             *     return "[" + getTypeDescriptor(type.getComponentType());
+             */
+            return type.getName().replace('.', '/');
+        } else {
+            return "L" + dotToSlash(type.getName()) + ";";
+        }
+    }
+
+    /**
+     * Returns a human-readable string representing the signature of a
+     * method with the given name and parameter types.
+     */
+    private static String getFriendlyMethodSignature(String name,
+                                                     Class<?>[] parameterTypes)
+    {
+        StringBuilder sig = new StringBuilder(name);
+        sig.append('(');
+        for (int i = 0; i < parameterTypes.length; i++) {
+            if (i > 0) {
+                sig.append(',');
+            }
+            Class<?> parameterType = parameterTypes[i];
+            int dimensions = 0;
+            while (parameterType.isArray()) {
+                parameterType = parameterType.getComponentType();
+                dimensions++;
+            }
+            sig.append(parameterType.getName());
+            while (dimensions-- > 0) {
+                sig.append("[]");
+            }
+        }
+        sig.append(')');
+        return sig.toString();
+    }
+
+    /**
+     * Return the number of abstract "words", or consecutive local variable
+     * indexes, required to contain a value of the given type.  See JVMS
+     * section 3.6.1.
+     *
+     * Note that the original version of the JVMS contained a definition of
+     * this abstract notion of a "word" in section 3.4, but that definition
+     * was removed for the second edition.
+     */
+    private static int getWordsPerType(Class<?> type) {
+        if (type == long.class || type == double.class) {
+            return 2;
+        } else {
+            return 1;
+        }
+    }
+
+    /**
+     * Add to the given list all of the types in the "from" array that
+     * are not already contained in the list and are assignable to at
+     * least one of the types in the "with" array.
+     *
+     * This method is useful for computing the greatest common set of
+     * declared exceptions from duplicate methods inherited from
+     * different interfaces.
+     */
+    private static void collectCompatibleTypes(Class<?>[] from,
+                                               Class<?>[] with,
+                                               List<Class<?>> list)
+    {
+        for (Class<?> fc: from) {
+            if (!list.contains(fc)) {
+                for (Class<?> wc: with) {
+                    if (wc.isAssignableFrom(fc)) {
+                        list.add(fc);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Given the exceptions declared in the throws clause of a proxy method,
+     * compute the exceptions that need to be caught from the invocation
+     * handler's invoke method and rethrown intact in the method's
+     * implementation before catching other Throwables and wrapping them
+     * in UndeclaredThrowableExceptions.
+     *
+     * The exceptions to be caught are returned in a List object.  Each
+     * exception in the returned list is guaranteed to not be a subclass of
+     * any of the other exceptions in the list, so the catch blocks for
+     * these exceptions may be generated in any order relative to each other.
+     *
+     * Error and RuntimeException are each always contained by the returned
+     * list (if none of their superclasses are contained), since those
+     * unchecked exceptions should always be rethrown intact, and thus their
+     * subclasses will never appear in the returned list.
+     *
+     * The returned List will be empty if java.lang.Throwable is in the
+     * given list of declared exceptions, indicating that no exceptions
+     * need to be caught.
+     */
+    private static List<Class<?>> computeUniqueCatchList(Class<?>[] exceptions) {
+        List<Class<?>> uniqueList = new ArrayList<>();
+                                                // unique exceptions to catch
+
+        uniqueList.add(Error.class);            // always catch/rethrow these
+        uniqueList.add(RuntimeException.class);
+
+    nextException:
+        for (Class<?> ex: exceptions) {
+            if (ex.isAssignableFrom(Throwable.class)) {
+                /*
+                 * If Throwable is declared to be thrown by the proxy method,
+                 * then no catch blocks are necessary, because the invoke
+                 * can, at most, throw Throwable anyway.
+                 */
+                uniqueList.clear();
+                break;
+            } else if (!Throwable.class.isAssignableFrom(ex)) {
+                /*
+                 * Ignore types that cannot be thrown by the invoke method.
+                 */
+                continue;
+            }
+            /*
+             * Compare this exception against the current list of
+             * exceptions that need to be caught:
+             */
+            for (int j = 0; j < uniqueList.size();) {
+                Class<?> ex2 = uniqueList.get(j);
+                if (ex2.isAssignableFrom(ex)) {
+                    /*
+                     * if a superclass of this exception is already on
+                     * the list to catch, then ignore this one and continue;
+                     */
+                    continue nextException;
+                } else if (ex.isAssignableFrom(ex2)) {
+                    /*
+                     * if a subclass of this exception is on the list
+                     * to catch, then remove it;
+                     */
+                    uniqueList.remove(j);
+                } else {
+                    j++;        // else continue comparing.
+                }
+            }
+            // This exception is unique (so far): add it to the list to catch.
+            uniqueList.add(ex);
+        }
+        return uniqueList;
+    }
+
+    /**
+     * A PrimitiveTypeInfo object contains assorted information about
+     * a primitive type in its public fields.  The struct for a particular
+     * primitive type can be obtained using the static "get" method.
+     */
+    private static class PrimitiveTypeInfo {
+
+        /** "base type" used in various descriptors (see JVMS section 4.3.2) */
+        public String baseTypeString;
+
+        /** name of corresponding wrapper class */
+        public String wrapperClassName;
+
+        /** method descriptor for wrapper class "valueOf" factory method */
+        public String wrapperValueOfDesc;
+
+        /** name of wrapper class method for retrieving primitive value */
+        public String unwrapMethodName;
+
+        /** descriptor of same method */
+        public String unwrapMethodDesc;
+
+        private static Map<Class<?>,PrimitiveTypeInfo> table = new HashMap<>();
+        static {
+            add(byte.class, Byte.class);
+            add(char.class, Character.class);
+            add(double.class, Double.class);
+            add(float.class, Float.class);
+            add(int.class, Integer.class);
+            add(long.class, Long.class);
+            add(short.class, Short.class);
+            add(boolean.class, Boolean.class);
+        }
+
+        private static void add(Class<?> primitiveClass, Class<?> wrapperClass) {
+            table.put(primitiveClass,
+                      new PrimitiveTypeInfo(primitiveClass, wrapperClass));
+        }
+
+        private PrimitiveTypeInfo(Class<?> primitiveClass, Class<?> wrapperClass) {
+            assert primitiveClass.isPrimitive();
+
+            baseTypeString =
+                Array.newInstance(primitiveClass, 0)
+                .getClass().getName().substring(1);
+            wrapperClassName = dotToSlash(wrapperClass.getName());
+            wrapperValueOfDesc =
+                "(" + baseTypeString + ")L" + wrapperClassName + ";";
+            unwrapMethodName = primitiveClass.getName() + "Value";
+            unwrapMethodDesc = "()" + baseTypeString;
+        }
+
+        public static PrimitiveTypeInfo get(Class<?> cl) {
+            return table.get(cl);
+        }
+    }
+
+
+    /**
+     * A ConstantPool object represents the constant pool of a class file
+     * being generated.  This representation of a constant pool is designed
+     * specifically for use by ProxyGenerator; in particular, it assumes
+     * that constant pool entries will not need to be resorted (for example,
+     * by their type, as the Java compiler does), so that the final index
+     * value can be assigned and used when an entry is first created.
+     *
+     * Note that new entries cannot be created after the constant pool has
+     * been written to a class file.  To prevent such logic errors, a
+     * ConstantPool instance can be marked "read only", so that further
+     * attempts to add new entries will fail with a runtime exception.
+     *
+     * See JVMS section 4.4 for more information about the constant pool
+     * of a class file.
+     */
+    private static class ConstantPool {
+
+        /**
+         * list of constant pool entries, in constant pool index order.
+         *
+         * This list is used when writing the constant pool to a stream
+         * and for assigning the next index value.  Note that element 0
+         * of this list corresponds to constant pool index 1.
+         */
+        private List<Entry> pool = new ArrayList<>(32);
+
+        /**
+         * maps constant pool data of all types to constant pool indexes.
+         *
+         * This map is used to look up the index of an existing entry for
+         * values of all types.
+         */
+        private Map<Object,Integer> map = new HashMap<>(16);
+
+        /** true if no new constant pool entries may be added */
+        private boolean readOnly = false;
+
+        /**
+         * Get or assign the index for a CONSTANT_Utf8 entry.
+         */
+        public short getUtf8(String s) {
+            if (s == null) {
+                throw new NullPointerException();
+            }
+            return getValue(s);
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_Integer entry.
+         */
+        public short getInteger(int i) {
+            return getValue(i);
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_Float entry.
+         */
+        public short getFloat(float f) {
+            return getValue(f);
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_Class entry.
+         */
+        public short getClass(String name) {
+            short utf8Index = getUtf8(name);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_CLASS, utf8Index));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_String entry.
+         */
+        public short getString(String s) {
+            short utf8Index = getUtf8(s);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_STRING, utf8Index));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_FieldRef entry.
+         */
+        public short getFieldRef(String className,
+                                 String name, String descriptor)
+        {
+            short classIndex = getClass(className);
+            short nameAndTypeIndex = getNameAndType(name, descriptor);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_FIELD, classIndex, nameAndTypeIndex));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_MethodRef entry.
+         */
+        public short getMethodRef(String className,
+                                  String name, String descriptor)
+        {
+            short classIndex = getClass(className);
+            short nameAndTypeIndex = getNameAndType(name, descriptor);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_METHOD, classIndex, nameAndTypeIndex));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_InterfaceMethodRef entry.
+         */
+        public short getInterfaceMethodRef(String className, String name,
+                                           String descriptor)
+        {
+            short classIndex = getClass(className);
+            short nameAndTypeIndex = getNameAndType(name, descriptor);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_INTERFACEMETHOD, classIndex, nameAndTypeIndex));
+        }
+
+        /**
+         * Get or assign the index for a CONSTANT_NameAndType entry.
+         */
+        public short getNameAndType(String name, String descriptor) {
+            short nameIndex = getUtf8(name);
+            short descriptorIndex = getUtf8(descriptor);
+            return getIndirect(new IndirectEntry(
+                CONSTANT_NAMEANDTYPE, nameIndex, descriptorIndex));
+        }
+
+        /**
+         * Set this ConstantPool instance to be "read only".
+         *
+         * After this method has been called, further requests to get
+         * an index for a non-existent entry will cause an InternalError
+         * to be thrown instead of creating of the entry.
+         */
+        public void setReadOnly() {
+            readOnly = true;
+        }
+
+        /**
+         * Write this constant pool to a stream as part of
+         * the class file format.
+         *
+         * This consists of writing the "constant_pool_count" and
+         * "constant_pool[]" items of the "ClassFile" structure, as
+         * described in JVMS section 4.1.
+         */
+        public void write(OutputStream out) throws IOException {
+            DataOutputStream dataOut = new DataOutputStream(out);
+
+            // constant_pool_count: number of entries plus one
+            dataOut.writeShort(pool.size() + 1);
+
+            for (Entry e : pool) {
+                e.write(dataOut);
+            }
+        }
+
+        /**
+         * Add a new constant pool entry and return its index.
+         */
+        private short addEntry(Entry entry) {
+            pool.add(entry);
+            /*
+             * Note that this way of determining the index of the
+             * added entry is wrong if this pool supports
+             * CONSTANT_Long or CONSTANT_Double entries.
+             */
+            if (pool.size() >= 65535) {
+                throw new IllegalArgumentException(
+                    "constant pool size limit exceeded");
+            }
+            return (short) pool.size();
+        }
+
+        /**
+         * Get or assign the index for an entry of a type that contains
+         * a direct value.  The type of the given object determines the
+         * type of the desired entry as follows:
+         *
+         *      java.lang.String        CONSTANT_Utf8
+         *      java.lang.Integer       CONSTANT_Integer
+         *      java.lang.Float         CONSTANT_Float
+         *      java.lang.Long          CONSTANT_Long
+         *      java.lang.Double        CONSTANT_DOUBLE
+         */
+        private short getValue(Object key) {
+            Integer index = map.get(key);
+            if (index != null) {
+                return index.shortValue();
+            } else {
+                if (readOnly) {
+                    throw new InternalError(
+                        "late constant pool addition: " + key);
+                }
+                short i = addEntry(new ValueEntry(key));
+                map.put(key, (int)i);
+                return i;
+            }
+        }
+
+        /**
+         * Get or assign the index for an entry of a type that contains
+         * references to other constant pool entries.
+         */
+        private short getIndirect(IndirectEntry e) {
+            Integer index = map.get(e);
+            if (index != null) {
+                return index.shortValue();
+            } else {
+                if (readOnly) {
+                    throw new InternalError("late constant pool addition");
+                }
+                short i = addEntry(e);
+                map.put(e, (int)i);
+                return i;
+            }
+        }
+
+        /**
+         * Entry is the abstact superclass of all constant pool entry types
+         * that can be stored in the "pool" list; its purpose is to define a
+         * common method for writing constant pool entries to a class file.
+         */
+        private abstract static class Entry {
+            public abstract void write(DataOutputStream out)
+                throws IOException;
+        }
+
+        /**
+         * ValueEntry represents a constant pool entry of a type that
+         * contains a direct value (see the comments for the "getValue"
+         * method for a list of such types).
+         *
+         * ValueEntry objects are not used as keys for their entries in the
+         * Map "map", so no useful hashCode or equals methods are defined.
+         */
+        private static class ValueEntry extends Entry {
+            private Object value;
+
+            public ValueEntry(Object value) {
+                this.value = value;
+            }
+
+            public void write(DataOutputStream out) throws IOException {
+                if (value instanceof String) {
+                    out.writeByte(CONSTANT_UTF8);
+                    out.writeUTF((String) value);
+                } else if (value instanceof Integer) {
+                    out.writeByte(CONSTANT_INTEGER);
+                    out.writeInt(((Integer) value).intValue());
+                } else if (value instanceof Float) {
+                    out.writeByte(CONSTANT_FLOAT);
+                    out.writeFloat(((Float) value).floatValue());
+                } else if (value instanceof Long) {
+                    out.writeByte(CONSTANT_LONG);
+                    out.writeLong(((Long) value).longValue());
+                } else if (value instanceof Double) {
+                    out.writeDouble(CONSTANT_DOUBLE);
+                    out.writeDouble(((Double) value).doubleValue());
+                } else {
+                    throw new InternalError("bogus value entry: " + value);
+                }
+            }
+        }
+
+        /**
+         * IndirectEntry represents a constant pool entry of a type that
+         * references other constant pool entries, i.e., the following types:
+         *
+         *      CONSTANT_Class, CONSTANT_String, CONSTANT_Fieldref,
+         *      CONSTANT_Methodref, CONSTANT_InterfaceMethodref, and
+         *      CONSTANT_NameAndType.
+         *
+         * Each of these entry types contains either one or two indexes of
+         * other constant pool entries.
+         *
+         * IndirectEntry objects are used as the keys for their entries in
+         * the Map "map", so the hashCode and equals methods are overridden
+         * to allow matching.
+         */
+        private static class IndirectEntry extends Entry {
+            private int tag;
+            private short index0;
+            private short index1;
+
+            /**
+             * Construct an IndirectEntry for a constant pool entry type
+             * that contains one index of another entry.
+             */
+            public IndirectEntry(int tag, short index) {
+                this.tag = tag;
+                this.index0 = index;
+                this.index1 = 0;
+            }
+
+            /**
+             * Construct an IndirectEntry for a constant pool entry type
+             * that contains two indexes for other entries.
+             */
+            public IndirectEntry(int tag, short index0, short index1) {
+                this.tag = tag;
+                this.index0 = index0;
+                this.index1 = index1;
+            }
+
+            public void write(DataOutputStream out) throws IOException {
+                out.writeByte(tag);
+                out.writeShort(index0);
+                /*
+                 * If this entry type contains two indexes, write
+                 * out the second, too.
+                 */
+                if (tag == CONSTANT_FIELD ||
+                    tag == CONSTANT_METHOD ||
+                    tag == CONSTANT_INTERFACEMETHOD ||
+                    tag == CONSTANT_NAMEANDTYPE)
+                {
+                    out.writeShort(index1);
+                }
+            }
+
+            public int hashCode() {
+                return tag + index0 + index1;
+            }
+
+            public boolean equals(Object obj) {
+                if (obj instanceof IndirectEntry) {
+                    IndirectEntry other = (IndirectEntry) obj;
+                    if (tag == other.tag &&
+                        index0 == other.index0 && index1 == other.index1)
+                    {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        }
+    }
+}
--- a/src/java.base/share/classes/java/net/InterfaceAddress.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/net/InterfaceAddress.java	Wed Aug 28 11:58:56 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
@@ -25,6 +25,8 @@
 
 package java.net;
 
+import java.util.Objects;
+
 /**
  * This class represents a Network Interface address. In short it's an
  * IP address, a subnet mask and a broadcast address when the address is
@@ -99,17 +101,17 @@
      * @see     java.net.InterfaceAddress#hashCode()
      */
     public boolean equals(Object obj) {
-        if (!(obj instanceof InterfaceAddress)) {
-            return false;
+        if (obj instanceof InterfaceAddress) {
+            InterfaceAddress cmp = (InterfaceAddress) obj;
+
+            if (Objects.equals(address, cmp.address) &&
+                Objects.equals(broadcast, cmp.broadcast) &&
+                maskLength == cmp.maskLength)
+            {
+                return true;
+            }
         }
-        InterfaceAddress cmp = (InterfaceAddress) obj;
-        if ( !(address == null ? cmp.address == null : address.equals(cmp.address)) )
-            return false;
-        if ( !(broadcast  == null ? cmp.broadcast == null : broadcast.equals(cmp.broadcast)) )
-            return false;
-        if (maskLength != cmp.maskLength)
-            return false;
-        return true;
+        return false;
     }
 
     /**
--- a/src/java.base/share/classes/java/net/ProxySelector.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/net/ProxySelector.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, 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
@@ -143,7 +143,9 @@
      *          contain one element of type
      *          {@link java.net.Proxy Proxy}
      *          that represents a direct connection.
-     * @throws IllegalArgumentException if the argument is null
+     * @throws IllegalArgumentException if the argument is null or if
+     *         the protocol or host cannot be determined from the provided
+     *         {@code uri}
      */
     public abstract List<Proxy> select(URI uri);
 
--- a/src/java.base/share/classes/java/net/ServerSocket.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/net/ServerSocket.java	Wed Aug 28 11:58:56 2019 -0400
@@ -710,6 +710,10 @@
 
     /**
      * Returns the binding state of the ServerSocket.
+     * <p>
+     * If the socket was bound prior to being {@linkplain #close closed},
+     * then this method will continue to return {@code true}
+     * after the socket is closed.
      *
      * @return true if the ServerSocket successfully bound to an address
      * @since 1.4
--- a/src/java.base/share/classes/java/net/URLStreamHandler.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/net/URLStreamHandler.java	Wed Aug 28 11:58:56 2019 -0400
@@ -30,6 +30,7 @@
 import java.io.File;
 import java.io.OutputStream;
 import java.util.Hashtable;
+import java.util.Objects;
 import sun.net.util.IPAddressUtil;
 import sun.net.www.ParseUtil;
 
@@ -343,10 +344,7 @@
      * @since 1.3
      */
     protected boolean equals(URL u1, URL u2) {
-        String ref1 = u1.getRef();
-        String ref2 = u2.getRef();
-        return (ref1 == ref2 || (ref1 != null && ref1.equals(ref2))) &&
-               sameFile(u1, u2);
+        return Objects.equals(u1.getRef(), u2.getRef()) && sameFile(u1, u2);
     }
 
     /**
--- a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template	Wed Aug 28 11:58:56 2019 -0400
@@ -168,15 +168,16 @@
     //
     protected Direct$Type$Buffer$RW$(int cap, long addr,
                                      FileDescriptor fd,
-                                     Runnable unmapper)
+                                     Runnable unmapper,
+                                     boolean isSync)
     {
 #if[rw]
-        super(-1, 0, cap, cap, fd);
+        super(-1, 0, cap, cap, fd, isSync);
         address = addr;
         cleaner = Cleaner.create(this, unmapper);
         att = null;
 #else[rw]
-        super(cap, addr, fd, unmapper);
+        super(cap, addr, fd, unmapper, isSync);
         this.isReadOnly = true;
 #end[rw]
     }
--- a/src/java.base/share/classes/java/nio/MappedByteBuffer.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/nio/MappedByteBuffer.java	Wed Aug 28 11:58:56 2019 -0400
@@ -78,18 +78,33 @@
     // operations if valid; null if the buffer is not mapped.
     private final FileDescriptor fd;
 
+    // A flag true if this buffer is mapped against non-volatile
+    // memory using one of the extended FileChannel.MapMode modes,
+    // MapMode.READ_ONLY_SYNC or MapMode.READ_WRITE_SYNC and false if
+    // it is mapped using any of the other modes. This flag only
+    // determines the behavior of force operations.
+    private final boolean isSync;
+
     // This should only be invoked by the DirectByteBuffer constructors
     //
     MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
-                     FileDescriptor fd)
-    {
+                     FileDescriptor fd, boolean isSync) {
         super(mark, pos, lim, cap);
         this.fd = fd;
+        this.isSync = isSync;
+    }
+
+    MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
+                     boolean isSync) {
+        super(mark, pos, lim, cap);
+        this.fd = null;
+        this.isSync = isSync;
     }
 
     MappedByteBuffer(int mark, int pos, int lim, int cap) { // package-private
         super(mark, pos, lim, cap);
         this.fd = null;
+        this.isSync = false;
     }
 
     // Returns the distance (in bytes) of the buffer start from the
@@ -147,6 +162,23 @@
     }
 
     /**
+     * Tells whether this buffer was mapped against a non-volatile
+     * memory device by passing one of the sync map modes {@link
+     * jdk.nio.mapmode.ExtendedMapMode#READ_ONLY_SYNC
+     * ExtendedMapModeMapMode#READ_ONLY_SYNC} or {@link
+     * jdk.nio.mapmode.ExtendedMapMode#READ_ONLY_SYNC
+     * ExtendedMapMode#READ_WRITE_SYNC} in the call to {@link
+     * java.nio.channels.FileChannel#map FileChannel.map} or was
+     * mapped by passing one of the other map modes.
+     *
+     * @return true if the file was mapped using one of the sync map
+     * modes, otherwise false.
+     */
+    private boolean isSync() {
+        return isSync;
+    }
+
+    /**
      * Tells whether or not this buffer's content is resident in physical
      * memory.
      *
@@ -168,6 +200,10 @@
         if (fd == null) {
             return true;
         }
+        // a sync mapped buffer is always loaded
+        if (isSync()) {
+            return true;
+        }
         if ((address == 0) || (capacity() == 0))
             return true;
         long offset = mappingOffset();
@@ -192,6 +228,10 @@
         if (fd == null) {
             return this;
         }
+        // no need to load a sync mapped buffer
+        if (isSync()) {
+            return this;
+        }
         if ((address == 0) || (capacity() == 0))
             return this;
         long offset = mappingOffset();
@@ -247,6 +287,9 @@
         if (fd == null) {
             return this;
         }
+        if (isSync) {
+            return force(0, limit());
+        }
         if ((address != 0) && (capacity() != 0)) {
             long offset = mappingOffset();
             force0(fd, mappingAddress(offset), mappingLength(offset));
@@ -303,8 +346,14 @@
         if ((address != 0) && (limit() != 0)) {
             // check inputs
             Objects.checkFromIndexSize(index, length, limit());
-            long offset = mappingOffset(index);
-            force0(fd, mappingAddress(offset, index), mappingLength(offset, length));
+            if (isSync) {
+                // simply force writeback of associated cache lines
+                Unsafe.getUnsafe().writebackMemory(address + index, length);
+            } else {
+                // force writeback via file descriptor
+                long offset = mappingOffset(index);
+                force0(fd, mappingAddress(offset, index), mappingLength(offset, length));
+            }
         }
         return this;
     }
--- a/src/java.base/share/classes/java/text/AttributedString.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/text/AttributedString.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, 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
@@ -1100,8 +1100,7 @@
             return false;
         }
         AttributeEntry other = (AttributeEntry) o;
-        return other.key.equals(key) &&
-            (value == null ? other.value == null : other.value.equals(value));
+        return other.key.equals(key) && Objects.equals(other.value, value);
     }
 
     public Attribute getKey() {
--- a/src/java.base/share/classes/java/util/TreeMap.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/TreeMap.java	Wed Aug 28 11:58:56 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
@@ -311,8 +311,7 @@
     public void putAll(Map<? extends K, ? extends V> map) {
         int mapSize = map.size();
         if (size==0 && mapSize!=0 && map instanceof SortedMap) {
-            Comparator<?> c = ((SortedMap<?,?>)map).comparator();
-            if (c == comparator || (c != null && c.equals(comparator))) {
+            if (Objects.equals(comparator, ((SortedMap<?,?>)map).comparator())) {
                 ++modCount;
                 try {
                     buildFromSorted(mapSize, map.entrySet().iterator(),
--- a/src/java.base/share/classes/java/util/TreeSet.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/java/util/TreeSet.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -302,9 +302,7 @@
             m instanceof TreeMap) {
             SortedSet<? extends E> set = (SortedSet<? extends E>) c;
             TreeMap<E,Object> map = (TreeMap<E, Object>) m;
-            Comparator<?> cc = set.comparator();
-            Comparator<? super E> mc = map.comparator();
-            if (cc==mc || (cc != null && cc.equals(mc))) {
+            if (Objects.equals(set.comparator(), map.comparator())) {
                 map.addAllForTreeSet(set, PRESENT);
                 return true;
             }
--- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java	Wed Aug 28 11:58:56 2019 -0400
@@ -699,7 +699,7 @@
     /*
      * Nested class used to represent a Loader of resources from a JAR URL.
      */
-    static class JarLoader extends Loader {
+    private static class JarLoader extends Loader {
         private JarFile jar;
         private final URL csu;
         private JarIndex index;
@@ -714,9 +714,9 @@
          * Creates a new JarLoader for the specified URL referring to
          * a JAR file.
          */
-        JarLoader(URL url, URLStreamHandler jarHandler,
-                  HashMap<String, Loader> loaderMap,
-                  AccessControlContext acc)
+        private JarLoader(URL url, URLStreamHandler jarHandler,
+                          HashMap<String, Loader> loaderMap,
+                          AccessControlContext acc)
             throws IOException
         {
             super(new URL("jar", "", -1, url + "!/", jarHandler));
@@ -1193,11 +1193,11 @@
         /* Canonicalized File */
         private File dir;
 
-        FileLoader(URL url) throws IOException {
+        /*
+         * Creates a new FileLoader for the specified URL with a file protocol.
+         */
+        private FileLoader(URL url) throws IOException {
             super(url);
-            if (!"file".equals(url.getProtocol())) {
-                throw new IllegalArgumentException("url");
-            }
             String path = url.getFile().replace('/', File.separatorChar);
             path = ParseUtil.decode(path);
             dir = (new File(path)).getCanonicalFile();
--- a/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java	Wed Aug 28 11:58:56 2019 -0400
@@ -24,6 +24,8 @@
  */
 package jdk.internal.math;
 
+import jdk.internal.misc.VM;
+
 import java.math.BigInteger;
 import java.util.Arrays;
 //@ model import org.jmlspecs.models.JMLMath;
@@ -64,52 +66,9 @@
     @ }
     @*/
 
-    static final int[] SMALL_5_POW = {
-            1,
-            5,
-            5 * 5,
-            5 * 5 * 5,
-            5 * 5 * 5 * 5,
-            5 * 5 * 5 * 5 * 5,
-            5 * 5 * 5 * 5 * 5 * 5,
-            5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5
-    };
+    static final int[] SMALL_5_POW;
 
-    static final long[] LONG_5_POW = {
-            1L,
-            5L,
-            5L * 5,
-            5L * 5 * 5,
-            5L * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-            5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
-    };
+    static final long[] LONG_5_POW;
 
     // Maximum size of cache of powers of 5 as FDBigIntegers.
     private static final int MAX_FIVE_POW = 340;
@@ -117,30 +76,84 @@
     // Cache of big powers of 5 as FDBigIntegers.
     private static final FDBigInteger POW_5_CACHE[];
 
+    // Zero as an FDBigInteger.
+    public static final FDBigInteger ZERO;
+
+    // Archive proxy
+    private static Object[] archivedCaches;
+
     // Initialize FDBigInteger cache of powers of 5.
     static {
-        POW_5_CACHE = new FDBigInteger[MAX_FIVE_POW];
-        int i = 0;
-        while (i < SMALL_5_POW.length) {
-            FDBigInteger pow5 = new FDBigInteger(new int[]{SMALL_5_POW[i]}, 0);
-            pow5.makeImmutable();
-            POW_5_CACHE[i] = pow5;
-            i++;
+        VM.initializeFromArchive(FDBigInteger.class);
+        Object[] caches = archivedCaches;
+        if (caches == null) {
+            long[] long5pow = {
+                    1L,
+                    5L,
+                    5L * 5,
+                    5L * 5 * 5,
+                    5L * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                };
+            int[] small5pow = {
+                    1,
+                    5,
+                    5 * 5,
+                    5 * 5 * 5,
+                    5 * 5 * 5 * 5,
+                    5 * 5 * 5 * 5 * 5,
+                    5 * 5 * 5 * 5 * 5 * 5,
+                    5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5,
+                    5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5
+                };
+            FDBigInteger[] pow5cache = new FDBigInteger[MAX_FIVE_POW];
+            int i = 0;
+            while (i < small5pow.length) {
+                FDBigInteger pow5 = new FDBigInteger(new int[] { small5pow[i] }, 0);
+                pow5.makeImmutable();
+                pow5cache[i] = pow5;
+                i++;
+            }
+            FDBigInteger prev = pow5cache[i - 1];
+            while (i < MAX_FIVE_POW) {
+                pow5cache[i] = prev = prev.mult(5);
+                prev.makeImmutable();
+                i++;
+            }
+            FDBigInteger zero = new FDBigInteger(new int[0], 0);
+            zero.makeImmutable();
+            archivedCaches = caches = new Object[] {small5pow, long5pow, pow5cache, zero};
         }
-        FDBigInteger prev = POW_5_CACHE[i - 1];
-        while (i < MAX_FIVE_POW) {
-            POW_5_CACHE[i] = prev = prev.mult(5);
-            prev.makeImmutable();
-            i++;
-        }
-    }
-
-    // Zero as an FDBigInteger.
-    public static final FDBigInteger ZERO = new FDBigInteger(new int[0], 0);
-
-    // Ensure ZERO is immutable.
-    static {
-        ZERO.makeImmutable();
+        SMALL_5_POW = (int[])caches[0];
+        LONG_5_POW = (long[])caches[1];
+        POW_5_CACHE = (FDBigInteger[])caches[2];
+        ZERO = (FDBigInteger)caches[3];
     }
 
     // Constant for casting an int to a long via bitwise AND.
--- a/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java	Wed Aug 28 11:58:56 2019 -0400
@@ -131,32 +131,32 @@
          * Converts a floating point value into an ASCII <code>String</code>.
          * @return The value converted to a <code>String</code>.
          */
-        public String toJavaFormatString();
+        String toJavaFormatString();
 
         /**
          * Appends a floating point value to an <code>Appendable</code>.
          * @param buf The <code>Appendable</code> to receive the value.
          */
-        public void appendTo(Appendable buf);
+        void appendTo(Appendable buf);
 
         /**
          * Retrieves the decimal exponent most closely corresponding to this value.
          * @return The decimal exponent.
          */
-        public int getDecimalExponent();
+        int getDecimalExponent();
 
         /**
          * Retrieves the value as an array of digits.
          * @param digits The digit array.
          * @return The number of valid digits copied into the array.
          */
-        public int getDigits(char[] digits);
+        int getDigits(char[] digits);
 
         /**
          * Indicates the sign of the value.
          * @return {@code value < 0.0}.
          */
-        public boolean isNegative();
+        boolean isNegative();
 
         /**
          * Indicates whether the value is either infinite or not a number.
@@ -164,7 +164,7 @@
          * @return <code>true</code> if and only if the value is <code>NaN</code>
          * or infinite.
          */
-        public boolean isExceptional();
+        boolean isExceptional();
 
         /**
          * Indicates whether the value was rounded up during the binary to ASCII
@@ -172,14 +172,14 @@
          *
          * @return <code>true</code> if and only if the value was rounded up.
          */
-        public boolean digitsRoundedUp();
+        boolean digitsRoundedUp();
 
         /**
          * Indicates whether the binary to ASCII conversion was exact.
          *
          * @return <code>true</code> if any only if the conversion was exact.
          */
-        public boolean decimalDigitsExact();
+        boolean decimalDigitsExact();
     }
 
     /**
@@ -321,7 +321,7 @@
 
         @Override
         public int getDigits(char[] digits) {
-            System.arraycopy(this.digits,firstDigitIndex,digits,0,this.nDigits);
+            System.arraycopy(this.digits, firstDigitIndex, digits, 0, this.nDigits);
             return this.nDigits;
         }
 
@@ -849,7 +849,7 @@
          * </pre>
          */
         private static int insignificantDigitsForPow2(int p2) {
-            if(p2>1 && p2 < insignificantDigitsNumber.length) {
+            if (p2 > 1 && p2 < insignificantDigitsNumber.length) {
                 return insignificantDigitsNumber[p2];
             }
             return 0;
@@ -862,7 +862,7 @@
          *  for ( i = 0; insignificant >= 10L; i++ )
          *         insignificant /= 10L;
          */
-        private static int[] insignificantDigitsNumber = {
+        private static final int[] insignificantDigitsNumber = {
             0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3,
             4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
             8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11,
@@ -1873,11 +1873,11 @@
             }  // look for and process decimal floating-point string
 
             char[] digits = new char[ len ];
-            int    nDigits= 0;
             boolean decSeen = false;
+            int nDigits = 0;
             int decPt = 0;
             int nLeadZero = 0;
-            int nTrailZero= 0;
+            int nTrailZero = 0;
 
         skipLeadingZerosLoop:
             while (i < len) {
@@ -2137,9 +2137,9 @@
                 // signed zero.
                 //
 
-                String significandString = null;
-                int signifLength = 0;
-                int exponentAdjust = 0;
+                String significandString;
+                int signifLength;
+                int exponentAdjust;
                 {
                     int leftDigits = 0; // number of meaningful digits to
                     // left of "decimal" point
@@ -2246,7 +2246,7 @@
 
                 boolean round = false;
                 boolean sticky = false;
-                int nextShift = 0;
+                int nextShift;
                 long significand = 0L;
                 // First iteration is different, since we only copy
                 // from the leading significand bit; one more exponent
@@ -2525,7 +2525,6 @@
      * Returns <code>s</code> with any leading zeros removed.
      */
     static String stripLeadingZeros(String s) {
-//        return  s.replaceFirst("^0+", "");
         if(!s.isEmpty() && s.charAt(0)=='0') {
             for(int i=1; i<s.length(); i++) {
                 if(s.charAt(i)!='0') {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/jdk/internal/misc/ExtendedMapMode.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  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 jdk.internal.misc;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.nio.channels.FileChannel.MapMode;
+
+/**
+ * JDK-specific map modes implemented in java.base.
+ */
+public class ExtendedMapMode {
+
+    static final MethodHandle MAP_MODE_CONSTRUCTOR;
+
+    static {
+        try {
+            var lookup = MethodHandles.privateLookupIn(MapMode.class, MethodHandles.lookup());
+            var methodType = MethodType.methodType(void.class, String.class);
+            MAP_MODE_CONSTRUCTOR = lookup.findConstructor(MapMode.class, methodType);
+        } catch (Exception e) {
+            throw new InternalError(e);
+        }
+    }
+
+    public static final MapMode READ_ONLY_SYNC = newMapMode("READ_ONLY_SYNC");
+
+    public static final MapMode READ_WRITE_SYNC = newMapMode("READ_WRITE_SYNC");
+
+    private static MapMode newMapMode(String name) {
+        try {
+            return (MapMode) MAP_MODE_CONSTRUCTOR.invoke(name);
+        } catch (Throwable e) {
+            throw new InternalError(e);
+        }
+    }
+
+    private ExtendedMapMode() { }
+}
--- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java	Wed Aug 28 11:58:56 2019 -0400
@@ -921,6 +921,101 @@
         checkPointer(null, address);
     }
 
+    /**
+     * Ensure writeback of a specified virtual memory address range
+     * from cache to physical memory. All bytes in the address range
+     * are guaranteed to have been written back to physical memory on
+     * return from this call i.e. subsequently executed store
+     * instructions are guaranteed not to be visible before the
+     * writeback is completed.
+     *
+     * @param address
+     *        the lowest byte address that must be guaranteed written
+     *        back to memory. bytes at lower addresses may also be
+     *        written back.
+     *
+     * @param length
+     *        the length in bytes of the region starting at address
+     *        that must be guaranteed written back to memory.
+     *
+     * @throws RuntimeException if memory writeback is not supported
+     *         on the current hardware of if the arguments are invalid.
+     *         (<em>Note:</em> after optimization, invalid inputs may
+     *         go undetected, which will lead to unpredictable
+     *         behavior)
+     *
+     * @since 14
+     */
+
+    public void writebackMemory(long address, long length) {
+        checkWritebackEnabled();
+        checkWritebackMemory(address, length);
+
+        // perform any required pre-writeback barrier
+        writebackPreSync0();
+
+        // write back one cache line at a time
+        long line = dataCacheLineAlignDown(address);
+        long end = address + length;
+        while (line < end) {
+            writeback0(line);
+            line += dataCacheLineFlushSize();
+        }
+
+        // perform any required post-writeback barrier
+        writebackPostSync0();
+    }
+
+    /**
+     * Validate the arguments to writebackMemory
+     *
+     * @throws RuntimeException if the arguments are invalid
+     *         (<em>Note:</em> after optimization, invalid inputs may
+     *         go undetected, which will lead to unpredictable
+     *         behavior)
+     */
+    private void checkWritebackMemory(long address, long length) {
+        checkNativeAddress(address);
+        checkSize(length);
+    }
+
+    /**
+     * Validate that the current hardware supports memory writeback.
+     * (<em>Note:</em> this is a belt and braces check.  Clients are
+     * expected to test whether writeback is enabled by calling
+     * ({@link isWritebackEnabled #isWritebackEnabled} and avoid
+     * calling method {@link writeback #writeback} if it is disabled).
+     *
+     *
+     * @throws RuntimeException if memory writeback is not supported
+     */
+    private void checkWritebackEnabled() {
+        if (!isWritebackEnabled()) {
+            throw new RuntimeException("writebackMemory not enabled!");
+        }
+    }
+
+    /**
+     * force writeback of an individual cache line.
+     *
+     * @param address
+     *        the start address of the cache line to be written back
+     */
+    @HotSpotIntrinsicCandidate
+    private native void writeback0(long address);
+
+     /**
+      * Serialize writeback operations relative to preceding memory writes.
+      */
+    @HotSpotIntrinsicCandidate
+    private native void writebackPreSync0();
+
+     /**
+      * Serialize writeback operations relative to following memory writes.
+      */
+    @HotSpotIntrinsicCandidate
+    private native void writebackPostSync0();
+
     /// random queries
 
     /**
@@ -1175,6 +1270,27 @@
      */
     public int pageSize() { return PAGE_SIZE; }
 
+    /**
+     * Reports the size in bytes of a data cache line written back by
+     * the hardware cache line flush operation available to the JVM or
+     * 0 if data cache line flushing is not enabled.
+     */
+    public int dataCacheLineFlushSize() { return DATA_CACHE_LINE_FLUSH_SIZE; }
+
+    /**
+     * Rounds down address to a data cache line boundary as
+     * determined by {@link #dataCacheLineFlushSize}
+     * @return the rounded down address
+     */
+    public long dataCacheLineAlignDown(long address) {
+        return (address & ~(DATA_CACHE_LINE_FLUSH_SIZE - 1));
+    }
+
+    /**
+     * Returns true if data cache line writeback
+     */
+    public static boolean isWritebackEnabled() { return DATA_CACHE_LINE_FLUSH_SIZE != 0; }
+
     /// random trusted operations from JNI:
 
     /**
--- a/src/java.base/share/classes/jdk/internal/misc/UnsafeConstants.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/jdk/internal/misc/UnsafeConstants.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2019, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -94,10 +95,28 @@
 
     static final boolean UNALIGNED_ACCESS;
 
+    /**
+     * The size of an L1 data cache line which will be either a power
+     * of two or zero.
+     *
+     * <p>A non-zero value indicates that writeback to memory is
+     * enabled for the current processor. The value defines the
+     * natural alignment and size of any data cache line committed to
+     * memory by a single writeback operation. If data cache line
+     * writeback is not enabled for the current hardware the field
+     * will have value 0.
+     *
+     * @implNote
+     * The actual value for this field is injected by the JVM.
+     */
+
+    static final int DATA_CACHE_LINE_FLUSH_SIZE;
+
     static {
         ADDRESS_SIZE0 = 0;
         PAGE_SIZE = 0;
         BIG_ENDIAN = false;
         UNALIGNED_ACCESS = false;
+        DATA_CACHE_LINE_FLUSH_SIZE = 0;
     }
 }
--- a/src/java.base/share/classes/module-info.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/module-info.java	Wed Aug 28 11:58:56 2019 -0400
@@ -192,6 +192,7 @@
         jdk.compiler,
         jdk.jfr,
         jdk.jshell,
+        jdk.nio.mapmode,
         jdk.scripting.nashorn,
         jdk.scripting.nashorn.shell,
         jdk.unsupported,
--- a/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java	Wed Aug 28 11:58:56 2019 -0400
@@ -44,6 +44,7 @@
 import java.net.URI;
 import java.net.Proxy;
 import java.net.ProxySelector;
+import java.util.List;
 import java.util.StringTokenizer;
 import java.util.Iterator;
 import java.security.Permission;
@@ -242,7 +243,13 @@
                     });
             if (sel != null) {
                 URI uri = sun.net.www.ParseUtil.toURI(url);
-                Iterator<Proxy> it = sel.select(uri).iterator();
+                final List<Proxy> proxies;
+                try {
+                    proxies = sel.select(uri);
+                } catch (IllegalArgumentException iae) {
+                    throw new IOException("Failed to select a proxy", iae);
+                }
+                final Iterator<Proxy> it = proxies.iterator();
                 while (it.hasNext()) {
                     p = it.next();
                     if (p == null || p == Proxy.NO_PROXY ||
--- a/src/java.base/share/classes/sun/net/www/protocol/ftp/Handler.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/sun/net/www/protocol/ftp/Handler.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2003, 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
@@ -23,7 +23,7 @@
  * questions.
  */
 
-/*-
+/*
  *      FTP stream opener
  */
 
@@ -34,6 +34,7 @@
 import java.net.Proxy;
 import java.util.Map;
 import java.util.HashMap;
+import java.util.Objects;
 import sun.net.ftp.FtpClient;
 import sun.net.www.protocol.http.HttpURLConnection;
 
@@ -47,8 +48,7 @@
     protected boolean equals(URL u1, URL u2) {
         String userInfo1 = u1.getUserInfo();
         String userInfo2 = u2.getUserInfo();
-        return super.equals(u1, u2) &&
-            (userInfo1 == null? userInfo2 == null: userInfo1.equals(userInfo2));
+        return super.equals(u1, u2) && Objects.equals(userInfo1, userInfo2);
     }
 
     protected java.net.URLConnection openConnection(URL u)
--- a/src/java.base/share/classes/sun/net/www/protocol/http/BasicAuthentication.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/BasicAuthentication.java	Wed Aug 28 11:58:56 2019 -0400
@@ -29,11 +29,17 @@
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.PasswordAuthentication;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.Charset;
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Arrays;
 import java.util.Base64;
 import java.util.Objects;
 import sun.net.www.HeaderParser;
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
 
 /**
  * BasicAuthentication: Encapsulate an http server authentication using
@@ -49,37 +55,18 @@
 
     /** The authentication string for this host, port, and realm.  This is
         a simple BASE64 encoding of "login:password".    */
-    String auth;
+    final String auth;
 
     /**
      * Create a BasicAuthentication
      */
     public BasicAuthentication(boolean isProxy, String host, int port,
                                String realm, PasswordAuthentication pw,
-                               String authenticatorKey) {
+                               boolean isUTF8, String authenticatorKey) {
         super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
               AuthScheme.BASIC, host, port, realm,
               Objects.requireNonNull(authenticatorKey));
-        String plain = pw.getUserName() + ":";
-        byte[] nameBytes = null;
-        try {
-            nameBytes = plain.getBytes("ISO-8859-1");
-        } catch (java.io.UnsupportedEncodingException uee) {
-            assert false;
-        }
-
-        // get password bytes
-        char[] passwd = pw.getPassword();
-        byte[] passwdBytes = new byte[passwd.length];
-        for (int i=0; i<passwd.length; i++)
-            passwdBytes[i] = (byte)passwd[i];
-
-        // concatenate user name and password bytes and encode them
-        byte[] concat = new byte[nameBytes.length + passwdBytes.length];
-        System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
-        System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
-                         passwdBytes.length);
-        this.auth = "Basic " + Base64.getEncoder().encodeToString(concat);
+        this.auth = authValueFrom(pw, isUTF8);
         this.pw = pw;
     }
 
@@ -99,32 +86,28 @@
      * Create a BasicAuthentication
      */
     public BasicAuthentication(boolean isProxy, URL url, String realm,
-                               PasswordAuthentication pw,
+                               PasswordAuthentication pw, boolean isUTF8,
                                String authenticatorKey) {
         super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
               AuthScheme.BASIC, url, realm,
               Objects.requireNonNull(authenticatorKey));
-        String plain = pw.getUserName() + ":";
-        byte[] nameBytes = null;
-        try {
-            nameBytes = plain.getBytes("ISO-8859-1");
-        } catch (java.io.UnsupportedEncodingException uee) {
-            assert false;
-        }
+        this.auth = authValueFrom(pw, isUTF8);
+        this.pw = pw;
+    }
 
-        // get password bytes
-        char[] passwd = pw.getPassword();
-        byte[] passwdBytes = new byte[passwd.length];
-        for (int i=0; i<passwd.length; i++)
-            passwdBytes[i] = (byte)passwd[i];
-
-        // concatenate user name and password bytes and encode them
-        byte[] concat = new byte[nameBytes.length + passwdBytes.length];
-        System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
-        System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
-                         passwdBytes.length);
-        this.auth = "Basic " + Base64.getEncoder().encodeToString(concat);
-        this.pw = pw;
+    private static String authValueFrom(PasswordAuthentication pw, boolean isUTF8) {
+        String plain = pw.getUserName() + ":";
+        char[] password = pw.getPassword();
+        CharBuffer cbuf = CharBuffer.allocate(plain.length() + password.length);
+        cbuf.put(plain).put(password).flip();
+        Charset charset = isUTF8 ? UTF_8 : ISO_8859_1;
+        ByteBuffer buf = charset.encode(cbuf);
+        ByteBuffer enc = Base64.getEncoder().encode(buf);
+        String ret = "Basic " + new String(enc.array(), enc.position(), enc.remaining(), ISO_8859_1);
+        Arrays.fill(buf.array(), (byte) 0);
+        Arrays.fill(enc.array(), (byte) 0);
+        Arrays.fill(cbuf.array(), (char) 0);
+        return ret;
     }
 
     /**
--- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1178,7 +1178,13 @@
                     if (logger.isLoggable(PlatformLogger.Level.FINEST)) {
                         logger.finest("ProxySelector Request for " + uri);
                     }
-                    Iterator<Proxy> it = sel.select(uri).iterator();
+                    final List<Proxy> proxies;
+                    try {
+                        proxies = sel.select(uri);
+                    } catch (IllegalArgumentException iae) {
+                        throw new IOException("Failed to select a proxy", iae);
+                    }
+                    final Iterator<Proxy> it = proxies.iterator();
                     Proxy p;
                     while (it.hasNext()) {
                         p = it.next();
@@ -2265,6 +2271,8 @@
         if (host != null && authhdr.isPresent()) {
             HeaderParser p = authhdr.headerParser();
             String realm = p.findValue("realm");
+            String charset = p.findValue("charset");
+            boolean isUTF8 = (charset != null && charset.equalsIgnoreCase("UTF-8"));
             String scheme = authhdr.scheme();
             AuthScheme authScheme = UNKNOWN;
             if ("basic".equalsIgnoreCase(scheme)) {
@@ -2310,7 +2318,7 @@
                                     realm, scheme, url, RequestorType.PROXY);
                     if (a != null) {
                         ret = new BasicAuthentication(true, host, port, realm, a,
-                                             getAuthenticatorKey());
+                                             isUTF8, getAuthenticatorKey());
                     }
                     break;
                 case DIGEST:
@@ -2428,6 +2436,8 @@
             HeaderParser p = authhdr.headerParser();
             String realm = p.findValue("realm");
             String scheme = authhdr.scheme();
+            String charset = p.findValue("charset");
+            boolean isUTF8 = (charset != null && charset.equalsIgnoreCase("UTF-8"));
             AuthScheme authScheme = UNKNOWN;
             if ("basic".equalsIgnoreCase(scheme)) {
                 authScheme = BASIC;
@@ -2479,7 +2489,7 @@
                             realm, scheme, url, RequestorType.SERVER);
                     if (a != null) {
                         ret = new BasicAuthentication(false, url, realm, a,
-                                    getAuthenticatorKey());
+                                    isUTF8, getAuthenticatorKey());
                     }
                     break;
                 case DIGEST:
--- a/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/sun/nio/ch/FileChannelImpl.java	Wed Aug 28 11:58:56 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
@@ -46,6 +46,8 @@
 import jdk.internal.access.JavaIOFileDescriptorAccess;
 import jdk.internal.access.JavaNioAccess;
 import jdk.internal.access.SharedSecrets;
+import jdk.internal.misc.ExtendedMapMode;
+import jdk.internal.misc.Unsafe;
 import jdk.internal.ref.Cleaner;
 import jdk.internal.ref.CleanerFactory;
 
@@ -860,20 +862,15 @@
 
     // -- Memory-mapped buffers --
 
-    private static class Unmapper
+    private static abstract class Unmapper
         implements Runnable
     {
         // may be required to close file
         private static final NativeDispatcher nd = new FileDispatcherImpl();
 
-        // keep track of mapped buffer usage
-        static volatile int count;
-        static volatile long totalSize;
-        static volatile long totalCapacity;
-
         private volatile long address;
-        private final long size;
-        private final int cap;
+        protected final long size;
+        protected final int cap;
         private final FileDescriptor fd;
 
         private Unmapper(long address, long size, int cap,
@@ -884,12 +881,6 @@
             this.size = size;
             this.cap = cap;
             this.fd = fd;
-
-            synchronized (Unmapper.class) {
-                count++;
-                totalSize += size;
-                totalCapacity += cap;
-            }
         }
 
         public void run() {
@@ -907,7 +898,63 @@
                 }
             }
 
-            synchronized (Unmapper.class) {
+            decrementStats();
+        }
+        protected abstract void incrementStats();
+        protected abstract void decrementStats();
+    }
+
+    private static class DefaultUnmapper extends Unmapper {
+
+        // keep track of non-sync mapped buffer usage
+        static volatile int count;
+        static volatile long totalSize;
+        static volatile long totalCapacity;
+
+        public DefaultUnmapper(long address, long size, int cap,
+                                     FileDescriptor fd) {
+            super(address, size, cap, fd);
+            incrementStats();
+        }
+
+        protected void incrementStats() {
+            synchronized (DefaultUnmapper.class) {
+                count++;
+                totalSize += size;
+                totalCapacity += cap;
+            }
+        }
+        protected void decrementStats() {
+            synchronized (DefaultUnmapper.class) {
+                count--;
+                totalSize -= size;
+                totalCapacity -= cap;
+            }
+        }
+    }
+
+    private static class SyncUnmapper extends Unmapper {
+
+        // keep track of mapped buffer usage
+        static volatile int count;
+        static volatile long totalSize;
+        static volatile long totalCapacity;
+
+        public SyncUnmapper(long address, long size, int cap,
+                                  FileDescriptor fd) {
+            super(address, size, cap, fd);
+            incrementStats();
+        }
+
+        protected void incrementStats() {
+            synchronized (SyncUnmapper.class) {
+                count++;
+                totalSize += size;
+                totalCapacity += cap;
+            }
+        }
+        protected void decrementStats() {
+            synchronized (SyncUnmapper.class) {
                 count--;
                 totalSize -= size;
                 totalCapacity -= cap;
@@ -941,18 +988,30 @@
             throw new IllegalArgumentException("Size exceeds Integer.MAX_VALUE");
 
         int imode;
+        boolean isSync = false;
         if (mode == MapMode.READ_ONLY)
             imode = MAP_RO;
         else if (mode == MapMode.READ_WRITE)
             imode = MAP_RW;
         else if (mode == MapMode.PRIVATE)
             imode = MAP_PV;
-        else
+        else if (mode == ExtendedMapMode.READ_ONLY_SYNC) {
+            imode = MAP_RO;
+            isSync = true;
+        } else if (mode == ExtendedMapMode.READ_WRITE_SYNC) {
+            imode = MAP_RW;
+            isSync = true;
+        } else {
             throw new UnsupportedOperationException();
-        if ((mode != MapMode.READ_ONLY) && !writable)
+        }
+        if ((mode != MapMode.READ_ONLY) && mode != ExtendedMapMode.READ_ONLY_SYNC && !writable)
             throw new NonWritableChannelException();
         if (!readable)
             throw new NonReadableChannelException();
+        // reject SYNC request if writeback is not enabled for this platform
+        if (isSync && !Unsafe.isWritebackEnabled()) {
+            throw new UnsupportedOperationException();
+        }
 
         long addr = -1;
         int ti = -1;
@@ -990,9 +1049,9 @@
                     // a valid file descriptor is not required
                     FileDescriptor dummy = new FileDescriptor();
                     if ((!writable) || (imode == MAP_RO))
-                        return Util.newMappedByteBufferR(0, 0, dummy, null);
+                        return Util.newMappedByteBufferR(0, 0, dummy, null, isSync);
                     else
-                        return Util.newMappedByteBuffer(0, 0, dummy, null);
+                        return Util.newMappedByteBuffer(0, 0, dummy, null, isSync);
                 }
 
                 pagePosition = (int)(position % allocationGranularity);
@@ -1000,7 +1059,7 @@
                 mapSize = size + pagePosition;
                 try {
                     // If map0 did not throw an exception, the address is valid
-                    addr = map0(imode, mapPosition, mapSize);
+                    addr = map0(imode, mapPosition, mapSize, isSync);
                 } catch (OutOfMemoryError x) {
                     // An OutOfMemoryError may indicate that we've exhausted
                     // memory so force gc and re-attempt map
@@ -1011,7 +1070,7 @@
                         Thread.currentThread().interrupt();
                     }
                     try {
-                        addr = map0(imode, mapPosition, mapSize);
+                        addr = map0(imode, mapPosition, mapSize, isSync);
                     } catch (OutOfMemoryError y) {
                         // After a second OOME, fail
                         throw new IOException("Map failed", y);
@@ -1032,17 +1091,21 @@
             assert (IOStatus.checkAll(addr));
             assert (addr % allocationGranularity == 0);
             int isize = (int)size;
-            Unmapper um = new Unmapper(addr, mapSize, isize, mfd);
+            Unmapper um = (isSync
+                           ? new SyncUnmapper(addr, mapSize, isize, mfd)
+                           : new DefaultUnmapper(addr, mapSize, isize, mfd));
             if ((!writable) || (imode == MAP_RO)) {
                 return Util.newMappedByteBufferR(isize,
                                                  addr + pagePosition,
                                                  mfd,
-                                                 um);
+                                                 um,
+                                                 isSync);
             } else {
                 return Util.newMappedByteBuffer(isize,
                                                 addr + pagePosition,
                                                 mfd,
-                                                um);
+                                                um,
+                                                isSync);
             }
         } finally {
             threads.remove(ti);
@@ -1062,15 +1125,40 @@
             }
             @Override
             public long getCount() {
-                return Unmapper.count;
+                return DefaultUnmapper.count;
             }
             @Override
             public long getTotalCapacity() {
-                return Unmapper.totalCapacity;
+                return DefaultUnmapper.totalCapacity;
             }
             @Override
             public long getMemoryUsed() {
-                return Unmapper.totalSize;
+                return DefaultUnmapper.totalSize;
+            }
+        };
+    }
+
+    /**
+     * Invoked by sun.management.ManagementFactoryHelper to create the management
+     * interface for sync mapped buffers.
+     */
+    public static JavaNioAccess.BufferPool getSyncMappedBufferPool() {
+        return new JavaNioAccess.BufferPool() {
+            @Override
+            public String getName() {
+                return "mapped - 'non-volatile memory'";
+            }
+            @Override
+            public long getCount() {
+                return SyncUnmapper.count;
+            }
+            @Override
+            public long getTotalCapacity() {
+                return SyncUnmapper.totalCapacity;
+            }
+            @Override
+            public long getMemoryUsed() {
+                return SyncUnmapper.totalSize;
             }
         };
     }
@@ -1196,7 +1284,7 @@
     // -- Native methods --
 
     // Creates a new mapping
-    private native long map0(int prot, long position, long length)
+    private native long map0(int prot, long position, long length, boolean isSync)
         throws IOException;
 
     // Removes an existing mapping
--- a/src/java.base/share/classes/sun/nio/ch/SocketOptionRegistry.java.template	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/sun/nio/ch/SocketOptionRegistry.java.template	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
  *
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -41,9 +41,9 @@
 #if !defined(SO_REUSEPORT)
 #ifdef _WIN32
 #define SO_REUSEPORT 0
-#elif __linux__
+#elif defined(__linux__)
 #define SO_REUSEPORT 15
-#elif __solaris__
+#elif defined(__solaris__)
 #define SO_REUSEPORT 0x100e
 #elif defined(AIX) || defined(MACOSX)
 #define SO_REUSEPORT 0x0200
--- a/src/java.base/share/classes/sun/nio/ch/Util.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/sun/nio/ch/Util.java	Wed Aug 28 11:58:56 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
@@ -415,7 +415,8 @@
                             new Class<?>[] { int.class,
                                              long.class,
                                              FileDescriptor.class,
-                                             Runnable.class });
+                                             Runnable.class,
+                                             boolean.class });
                         ctor.setAccessible(true);
                         directByteBufferConstructor = ctor;
                     } catch (ClassNotFoundException   |
@@ -430,7 +431,8 @@
 
     static MappedByteBuffer newMappedByteBuffer(int size, long addr,
                                                 FileDescriptor fd,
-                                                Runnable unmapper)
+                                                Runnable unmapper,
+                                                boolean isSync)
     {
         MappedByteBuffer dbb;
         if (directByteBufferConstructor == null)
@@ -440,7 +442,8 @@
               new Object[] { size,
                              addr,
                              fd,
-                             unmapper });
+                             unmapper,
+                             isSync});
         } catch (InstantiationException |
                  IllegalAccessException |
                  InvocationTargetException e) {
@@ -460,7 +463,8 @@
                             new Class<?>[] { int.class,
                                              long.class,
                                              FileDescriptor.class,
-                                             Runnable.class });
+                                             Runnable.class,
+                                             boolean.class });
                         ctor.setAccessible(true);
                         directByteBufferRConstructor = ctor;
                     } catch (ClassNotFoundException |
@@ -475,7 +479,8 @@
 
     static MappedByteBuffer newMappedByteBufferR(int size, long addr,
                                                  FileDescriptor fd,
-                                                 Runnable unmapper)
+                                                 Runnable unmapper,
+                                                 boolean isSync)
     {
         MappedByteBuffer dbb;
         if (directByteBufferRConstructor == null)
@@ -485,7 +490,8 @@
               new Object[] { size,
                              addr,
                              fd,
-                             unmapper });
+                             unmapper,
+                             isSync});
         } catch (InstantiationException |
                  IllegalAccessException |
                  InvocationTargetException e) {
--- a/src/java.base/share/classes/sun/security/validator/PKIXValidator.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/validator/PKIXValidator.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -143,6 +143,7 @@
         return subjectMap;
     }
 
+    @Override
     public Collection<X509Certificate> getTrustedCertificates() {
         return trustedCerts;
     }
@@ -399,55 +400,67 @@
      */
     private static void addResponses(PKIXBuilderParameters pkixParams,
             X509Certificate[] chain, List<byte[]> responseList) {
+        try {
+            boolean createdRevChk = false;
 
-        if (pkixParams.isRevocationEnabled()) {
-            try {
-                // Make a modifiable copy of the CertPathChecker list
-                PKIXRevocationChecker revChecker = null;
-                List<PKIXCertPathChecker> checkerList =
-                        new ArrayList<>(pkixParams.getCertPathCheckers());
+            // Obtain the current CertPathChecker list
+            PKIXRevocationChecker revChecker = null;
+            List<PKIXCertPathChecker> checkerList =
+                    pkixParams.getCertPathCheckers();
 
-                // Find the first PKIXRevocationChecker in the list
-                for (PKIXCertPathChecker checker : checkerList) {
-                    if (checker instanceof PKIXRevocationChecker) {
-                        revChecker = (PKIXRevocationChecker)checker;
-                        break;
-                    }
+            // Find the first PKIXRevocationChecker in the list
+            for (PKIXCertPathChecker checker : checkerList) {
+                if (checker instanceof PKIXRevocationChecker) {
+                    revChecker = (PKIXRevocationChecker)checker;
+                    break;
                 }
+            }
 
-                // If we still haven't found one, make one
-                if (revChecker == null) {
+            // If we still haven't found one, make one, unless revocation
+            // is disabled - then there's no point adding OCSP responses.
+            // If a PKIXRevocationChecker was added externally, then we
+            // must add the responses since revocation checking is performed
+            // independent of the revocation flag (per the
+            // PKIXRevocationChecker spec).
+            if (revChecker == null) {
+                if (pkixParams.isRevocationEnabled()) {
                     revChecker = (PKIXRevocationChecker)CertPathValidator.
                             getInstance("PKIX").getRevocationChecker();
-                    checkerList.add(revChecker);
+                    createdRevChk = true;
+                } else {
+                    return;
                 }
+            }
 
-                // Each response in the list should be in parallel with
-                // the certificate list.  If there is a zero-length response
-                // treat it as being absent.  If the user has provided their
-                // own PKIXRevocationChecker with pre-populated responses, do
-                // not overwrite them with the ones from the handshake.
-                Map<X509Certificate, byte[]> responseMap =
-                        revChecker.getOcspResponses();
-                int limit = Integer.min(chain.length, responseList.size());
-                for (int idx = 0; idx < limit; idx++) {
-                    byte[] respBytes = responseList.get(idx);
-                    if (respBytes != null && respBytes.length > 0 &&
-                            !responseMap.containsKey(chain[idx])) {
-                        responseMap.put(chain[idx], respBytes);
-                    }
+            // Each response in the list should be in parallel with
+            // the certificate list.  If there is a zero-length response
+            // treat it as being absent.  If the user has provided their
+            // own PKIXRevocationChecker with pre-populated responses, do
+            // not overwrite them with the ones from the handshake.
+            Map<X509Certificate, byte[]> responseMap =
+                    revChecker.getOcspResponses();
+            int limit = Integer.min(chain.length, responseList.size());
+            for (int idx = 0; idx < limit; idx++) {
+                byte[] respBytes = responseList.get(idx);
+                if (respBytes != null && respBytes.length > 0 &&
+                        !responseMap.containsKey(chain[idx])) {
+                    responseMap.put(chain[idx], respBytes);
                 }
+            }
+            revChecker.setOcspResponses(responseMap);
 
-                // Add the responses and push it all back into the
-                // PKIXBuilderParameters
-                revChecker.setOcspResponses(responseMap);
+            // Add the responses and push it all back into the
+            // PKIXBuilderParameters
+            if (createdRevChk) {
+                pkixParams.addCertPathChecker(revChecker);
+            } else {
                 pkixParams.setCertPathCheckers(checkerList);
-            } catch (NoSuchAlgorithmException exc) {
-                // This should not occur, but if it does happen then
-                // stapled OCSP responses won't be part of revocation checking.
-                // Clients can still fall back to other means of revocation
-                // checking.
             }
+        } catch (NoSuchAlgorithmException exc) {
+            // This should not occur, but if it does happen then
+            // stapled OCSP responses won't be part of revocation checking.
+            // Clients can still fall back to other means of revocation
+            // checking.
         }
     }
 }
--- a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java	Wed Aug 28 11:58:56 2019 -0400
@@ -274,8 +274,7 @@
      * with the same parameters.
      */
     public boolean equals(AlgorithmId other) {
-        boolean paramsEqual =
-          (params == null ? other.params == null : params.equals(other.params));
+        boolean paramsEqual = Objects.equals(other.params, params);
         return (algid.equals((Object)other.algid) && paramsEqual);
     }
 
--- a/src/java.base/share/classes/sun/text/CompactByteArray.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/classes/sun/text/CompactByteArray.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -244,7 +244,7 @@
     /** For internal use only.  Do not modify the result, the behavior of
       * modified results are undefined.
       */
-    public short getIndexArray()[]
+    public short[] getIndexArray()
     {
         return indices;
     }
@@ -252,7 +252,7 @@
     /** For internal use only.  Do not modify the result, the behavior of
       * modified results are undefined.
       */
-    public byte getStringArray()[]
+    public byte[] getStringArray()
     {
         return values;
     }
--- a/src/java.base/share/native/libfdlibm/fdlibm.h	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/native/libfdlibm/fdlibm.h	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 
 #ifdef _ALLBSD_SOURCE
 #include <machine/endian.h>
-#elif __linux__
+#elif defined(__linux__)
 #define __USE_BSD 1
 #include <endian.h>
 #endif
--- a/src/java.base/share/native/libjava/jni_util.c	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/native/libjava/jni_util.c	Wed Aug 28 11:58:56 2019 -0400
@@ -1096,7 +1096,7 @@
 }
 
 JNIEXPORT jint JNICALL
-JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char* classname)
+JNU_IsInstanceOfByName(JNIEnv *env, jobject object, const char* classname)
 {
     jclass cls;
     if ((*env)->EnsureLocalCapacity(env, 1) < 0)
--- a/src/java.base/share/native/libjava/jni_util.h	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/share/native/libjava/jni_util.h	Wed Aug 28 11:58:56 2019 -0400
@@ -208,7 +208,7 @@
  * has been thrown.
  */
 JNIEXPORT jint JNICALL
-JNU_IsInstanceOfByName(JNIEnv *env, jobject object, char *classname);
+JNU_IsInstanceOfByName(JNIEnv *env, jobject object, const char *classname);
 
 
 /* Get or set class and instance fields.
--- a/src/java.base/unix/native/libnio/ch/FileChannelImpl.c	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/unix/native/libnio/ch/FileChannelImpl.c	Wed Aug 28 11:58:56 2019 -0400
@@ -48,6 +48,7 @@
 #include "nio_util.h"
 #include "sun_nio_ch_FileChannelImpl.h"
 #include "java_lang_Integer.h"
+#include <assert.h>
 
 static jfieldID chan_fd;        /* jobject 'fd' in sun.nio.ch.FileChannelImpl */
 
@@ -73,7 +74,7 @@
 
 JNIEXPORT jlong JNICALL
 Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
-                                     jint prot, jlong off, jlong len)
+                                     jint prot, jlong off, jlong len, jboolean map_sync)
 {
     void *mapAddress = 0;
     jobject fdo = (*env)->GetObjectField(env, this, chan_fd);
@@ -81,6 +82,9 @@
     int protections = 0;
     int flags = 0;
 
+    // should never be called with map_sync and prot == PRIVATE
+    assert((prot != sun_nio_ch_FileChannelImpl_MAP_PV) || !map_sync);
+
     if (prot == sun_nio_ch_FileChannelImpl_MAP_RO) {
         protections = PROT_READ;
         flags = MAP_SHARED;
@@ -92,6 +96,33 @@
         flags = MAP_PRIVATE;
     }
 
+    // if MAP_SYNC and MAP_SHARED_VALIDATE are not defined then it is
+    // best to define them here. This ensures the code compiles on old
+    // OS releases which do not provide the relevant headers. If run
+    // on the same machine then it will work if the kernel contains
+    // the necessary support otherwise mmap should fail with an
+    // invalid argument error
+
+#ifndef MAP_SYNC
+#define MAP_SYNC 0x80000
+#endif
+#ifndef MAP_SHARED_VALIDATE
+#define MAP_SHARED_VALIDATE 0x03
+#endif
+
+    if (map_sync) {
+        // ensure
+        //  1) this is Linux on AArch64 or x86_64
+        //  2) the mmap APIs are available/ at compile time
+#if !defined(LINUX) || ! (defined(aarch64) || (defined(amd64) && defined(_LP64)))
+        // TODO - implement for solaris/AIX/BSD/WINDOWS and for 32 bit
+        JNU_ThrowInternalError(env, "should never call map on platform where MAP_SYNC is unimplemented");
+        return IOS_THROWN;
+#else
+        flags |= MAP_SYNC | MAP_SHARED_VALIDATE;
+#endif
+    }
+
     mapAddress = mmap64(
         0,                    /* Let OS decide location */
         len,                  /* Number of bytes to map */
@@ -101,6 +132,11 @@
         off);                 /* Offset into file */
 
     if (mapAddress == MAP_FAILED) {
+        if (map_sync && errno == ENOTSUP) {
+            JNU_ThrowIOExceptionWithLastError(env, "map with mode MAP_SYNC unsupported");
+            return IOS_THROWN;
+        }
+
         if (errno == ENOMEM) {
             JNU_ThrowOutOfMemoryError(env, "Map failed");
             return IOS_THROWN;
--- a/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/unix/native/libnio/ch/FileDispatcherImpl.c	Wed Aug 28 11:58:56 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
@@ -342,13 +342,13 @@
         JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");
         return result;
     }
-#elif F_NOCACHE
+#elif defined(F_NOCACHE)
     result = fcntl(fd, F_NOCACHE, 1);
     if (result == -1) {
         JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");
         return result;
     }
-#elif DIRECTIO_ON
+#elif defined(DIRECTIO_ON)
     result = directio(fd, DIRECTIO_ON);
     if (result == -1) {
         JNU_ThrowIOExceptionWithLastError(env, "DirectIO setup failed");
--- a/src/java.base/windows/native/libjava/java_props_md.c	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/windows/native/libjava/java_props_md.c	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -564,9 +564,9 @@
         }
         sprintf(buf, "%d.%d", majorVersion, minorVersion);
         sprops.os_version = _strdup(buf);
-#if _M_AMD64
+#if defined(_M_AMD64)
         sprops.os_arch = "amd64";
-#elif _X86_
+#elif defined(_X86_)
         sprops.os_arch = "x86";
 #else
         sprops.os_arch = "unknown";
--- a/src/java.base/windows/native/libnio/ch/FileChannelImpl.c	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.base/windows/native/libnio/ch/FileChannelImpl.c	Wed Aug 28 11:58:56 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
@@ -60,7 +60,7 @@
 
 JNIEXPORT jlong JNICALL
 Java_sun_nio_ch_FileChannelImpl_map0(JNIEnv *env, jobject this,
-                               jint prot, jlong off, jlong len)
+                                     jint prot, jlong off, jlong len, jboolean map_sync)
 {
     void *mapAddress = 0;
     jint lowOffset = (jint)off;
@@ -87,6 +87,11 @@
         mapAccess = FILE_MAP_COPY;
     }
 
+    if (map_sync) {
+        JNU_ThrowInternalError(env, "should never call map on platform where MAP_SYNC is unimplemented");
+        return IOS_THROWN;
+    }
+
     mapping = CreateFileMapping(
         fileHandle,      /* Handle of file */
         NULL,            /* Not inheritable */
--- a/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java	Wed Aug 28 11:58:56 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
@@ -345,6 +345,8 @@
                 .getDirectBufferPool()));
             bufferPools.add(createBufferPoolMXBean(sun.nio.ch.FileChannelImpl
                 .getMappedBufferPool()));
+            bufferPools.add(createBufferPoolMXBean(sun.nio.ch.FileChannelImpl
+                .getSyncMappedBufferPool()));
         }
         return bufferPools;
     }
--- a/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.net.http/share/classes/jdk/internal/net/http/AuthenticationFilter.java	Wed Aug 28 11:58:56 2019 -0400
@@ -32,6 +32,7 @@
 import java.net.InetSocketAddress;
 import java.net.URISyntaxException;
 import java.net.URL;
+import java.nio.charset.Charset;
 import java.util.Base64;
 import java.util.LinkedList;
 import java.util.List;
@@ -43,6 +44,7 @@
 import static java.net.Authenticator.RequestorType.PROXY;
 import static java.net.Authenticator.RequestorType.SERVER;
 import static java.nio.charset.StandardCharsets.ISO_8859_1;
+import static java.nio.charset.StandardCharsets.UTF_8;
 
 /**
  * Implementation of Http Basic authentication.
@@ -155,8 +157,8 @@
             if (proxyURI != null) {
                 CacheEntry ca = cache.get(proxyURI, true);
                 if (ca != null) {
-                    exchange.proxyauth = new AuthInfo(true, ca.scheme, null, ca);
-                    addBasicCredentials(r, true, ca.value);
+                    exchange.proxyauth = new AuthInfo(true, ca.scheme, null, ca, ca.isUTF8);
+                    addBasicCredentials(r, true, ca.value, ca.isUTF8);
                 }
             }
         }
@@ -165,8 +167,8 @@
         if (exchange.serverauth == null) {
             CacheEntry ca = cache.get(r.uri(), false);
             if (ca != null) {
-                exchange.serverauth = new AuthInfo(true, ca.scheme, null, ca);
-                addBasicCredentials(r, false, ca.value);
+                exchange.serverauth = new AuthInfo(true, ca.scheme, null, ca, ca.isUTF8);
+                addBasicCredentials(r, false, ca.value, ca.isUTF8);
             }
         }
     }
@@ -174,11 +176,13 @@
     // TODO: refactor into per auth scheme class
     private static void addBasicCredentials(HttpRequestImpl r,
                                             boolean proxy,
-                                            PasswordAuthentication pw) {
+                                            PasswordAuthentication pw,
+                                            boolean isUTF8) {
         String hdrname = proxy ? "Proxy-Authorization" : "Authorization";
         StringBuilder sb = new StringBuilder(128);
         sb.append(pw.getUserName()).append(':').append(pw.getPassword());
-        String s = encoder.encodeToString(sb.toString().getBytes(ISO_8859_1));
+        var charset = isUTF8 ? UTF_8 : ISO_8859_1;
+        String s = encoder.encodeToString(sb.toString().getBytes(charset));
         String value = "Basic " + s;
         if (proxy) {
             if (r.isConnect()) {
@@ -203,35 +207,36 @@
         int retries;
         PasswordAuthentication credentials; // used in request
         CacheEntry cacheEntry; // if used
+        final boolean isUTF8; //
 
         AuthInfo(boolean fromcache,
                  String scheme,
-                 PasswordAuthentication credentials) {
+                 PasswordAuthentication credentials, boolean isUTF8) {
             this.fromcache = fromcache;
             this.scheme = scheme;
             this.credentials = credentials;
             this.retries = 1;
+            this.isUTF8 = isUTF8;
         }
 
         AuthInfo(boolean fromcache,
                  String scheme,
                  PasswordAuthentication credentials,
-                 CacheEntry ca) {
-            this(fromcache, scheme, credentials);
+                 CacheEntry ca, boolean isUTF8) {
+            this(fromcache, scheme, credentials, isUTF8);
             assert credentials == null || (ca != null && ca.value == null);
             cacheEntry = ca;
         }
 
-        AuthInfo retryWithCredentials(PasswordAuthentication pw) {
+        AuthInfo retryWithCredentials(PasswordAuthentication pw, boolean isUTF8) {
             // If the info was already in the cache we need to create a new
             // instance with fromCache==false so that it's put back in the
             // cache if authentication succeeds
-            AuthInfo res = fromcache ? new AuthInfo(false, scheme, pw) : this;
+            AuthInfo res = fromcache ? new AuthInfo(false, scheme, pw, isUTF8) : this;
             res.credentials = Objects.requireNonNull(pw);
             res.retries = retries;
             return res;
         }
-
     }
 
     @Override
@@ -245,13 +250,13 @@
             // check if any authentication succeeded for first time
             if (exchange.serverauth != null && !exchange.serverauth.fromcache) {
                 AuthInfo au = exchange.serverauth;
-                cache.store(au.scheme, req.uri(), false, au.credentials);
+                cache.store(au.scheme, req.uri(), false, au.credentials, au.isUTF8);
             }
             if (exchange.proxyauth != null && !exchange.proxyauth.fromcache) {
                 AuthInfo au = exchange.proxyauth;
                 URI proxyURI = getProxyURI(req);
                 if (proxyURI != null) {
-                    cache.store(au.scheme, proxyURI, true, au.credentials);
+                    cache.store(au.scheme, proxyURI, true, au.credentials, au.isUTF8);
                 }
             }
             return null;
@@ -264,11 +269,14 @@
             throw new IOException(authname + " header missing for response code " + status);
         }
         String authval = null;
+        boolean isUTF8 = false;
         for (String aval : authvals) {
             HeaderParser parser = new HeaderParser(aval);
             String scheme = parser.findKey(0);
             if (scheme.equalsIgnoreCase("Basic")) {
                 authval = aval;
+                var charset = parser.findValue("charset");
+                isUTF8 = (charset != null && charset.equalsIgnoreCase("UTF-8"));
                 break;
             }
         }
@@ -302,14 +310,14 @@
                 throw new IOException("No credentials provided");
             }
             // No authentication in request. Get credentials from user
-            au = new AuthInfo(false, "Basic", pw);
+            au = new AuthInfo(false, "Basic", pw, isUTF8);
             if (proxy) {
                 exchange.proxyauth = au;
             } else {
                 exchange.serverauth = au;
             }
             req = HttpRequestImpl.newInstanceForAuthentication(req);
-            addBasicCredentials(req, proxy, pw);
+            addBasicCredentials(req, proxy, pw, isUTF8);
             return req;
         } else if (au.retries > retry_limit) {
             throw new IOException("too many authentication attempts. Limit: " +
@@ -328,14 +336,14 @@
             if (pw == null) {
                 throw new IOException("No credentials provided");
             }
-            au = au.retryWithCredentials(pw);
+            au = au.retryWithCredentials(pw, isUTF8);
             if (proxy) {
                 exchange.proxyauth = au;
             } else {
                 exchange.serverauth = au;
             }
             req = HttpRequestImpl.newInstanceForAuthentication(req);
-            addBasicCredentials(req, proxy, au.credentials);
+            addBasicCredentials(req, proxy, au.credentials, isUTF8);
             au.retries++;
             return req;
         }
@@ -387,9 +395,9 @@
         synchronized void store(String authscheme,
                                 URI domain,
                                 boolean proxy,
-                                PasswordAuthentication value) {
+                                PasswordAuthentication value, boolean isUTF8) {
             remove(authscheme, domain, proxy);
-            entries.add(new CacheEntry(authscheme, domain, proxy, value));
+            entries.add(new CacheEntry(authscheme, domain, proxy, value, isUTF8));
         }
     }
 
@@ -417,15 +425,17 @@
         final String scheme;
         final boolean proxy;
         final PasswordAuthentication value;
+        final boolean isUTF8;
 
         CacheEntry(String authscheme,
                    URI uri,
                    boolean proxy,
-                   PasswordAuthentication value) {
+                   PasswordAuthentication value, boolean isUTF8) {
             this.scheme = authscheme;
             this.root = normalize(uri, true).toString(); // remove extraneous components
             this.proxy = proxy;
             this.value = value;
+            this.isUTF8 = isUTF8;
         }
 
         public PasswordAuthentication value() {
--- a/src/java.rmi/share/classes/sun/rmi/runtime/Log.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.rmi/share/classes/sun/rmi/runtime/Log.java	Wed Aug 28 11:58:56 2019 -0400
@@ -28,8 +28,10 @@
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.io.OutputStream;
+import java.lang.StackWalker.StackFrame;
 import java.rmi.server.LogStream;
 import java.security.PrivilegedAction;
+import java.util.Set;
 import java.util.logging.Handler;
 import java.util.logging.SimpleFormatter;
 import java.util.logging.Level;
@@ -62,6 +64,8 @@
     public static final Level BRIEF = Level.FINE;
     public static final Level VERBOSE = Level.FINER;
 
+    private static final StackWalker WALKER = StackWalker.getInstance(Set.of(), 4);
+
     /* selects log implementation */
     private static final LogFactory logFactory;
     static {
@@ -217,16 +221,16 @@
 
         public void log(Level level, String message) {
             if (isLoggable(level)) {
-                String[] source = getSource();
-                logger.logp(level, source[0], source[1],
+                StackFrame sourceFrame = getSource();
+                logger.logp(level, sourceFrame.getClassName(), sourceFrame.getMethodName(),
                            Thread.currentThread().getName() + ": " + message);
             }
         }
 
         public void log(Level level, String message, Throwable thrown) {
             if (isLoggable(level)) {
-                String[] source = getSource();
-                logger.logp(level, source[0], source[1],
+                StackFrame sourceFrame = getSource();
+                logger.logp(level, sourceFrame.getClassName(), sourceFrame.getMethodName(),
                     Thread.currentThread().getName() + ": " +
                            message, thrown);
             }
@@ -390,9 +394,9 @@
 
         public void log(Level messageLevel, String message) {
             if (isLoggable(messageLevel)) {
-                String[] source = getSource();
-                stream.println(unqualifiedName(source[0]) +
-                               "." + source[1] + ": " + message);
+                StackFrame sourceFrame = getSource();
+                stream.println(unqualifiedName(sourceFrame.getClassName()) +
+                               "." + sourceFrame.getMethodName() + ": " + message);
             }
         }
 
@@ -403,9 +407,9 @@
                  * RemoteServer.getLog
                  */
                 synchronized (stream) {
-                    String[] source = getSource();
-                    stream.println(unqualifiedName(source[0]) + "." +
-                                   source[1] + ": " + message);
+                    StackFrame sourceFrame = getSource();
+                    stream.println(unqualifiedName(sourceFrame.getClassName()) + "." +
+                                    sourceFrame.getMethodName() + ": " + message);
                     thrown.printStackTrace(stream);
                 }
             }
@@ -441,13 +445,12 @@
     }
 
     /**
-     * Obtain class and method names of code calling a log method.
+     * Obtain stack frame of code calling a log method.
      */
-    private static String[] getSource() {
-        StackTraceElement[] trace = (new Exception()).getStackTrace();
-        return new String[] {
-            trace[3].getClassName(),
-            trace[3].getMethodName()
-        };
+    private static StackFrame getSource() {
+        return WALKER.walk(s -> s
+                                 .skip(3)
+                                 .findFirst()
+                                 .get());
     }
 }
--- a/src/java.security.jgss/share/native/libj2gss/gssapi.h	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.security.jgss/share/native/libj2gss/gssapi.h	Wed Aug 28 11:58:56 2019 -0400
@@ -43,7 +43,7 @@
 extern "C" {
 #endif /* __cplusplus */
 
-#if TARGET_OS_MAC
+#if defined(TARGET_OS_MAC)
 #    pragma pack(push,2)
 #endif
 
@@ -695,7 +695,7 @@
         gss_name_t *            /* output_name */
 );
 
-#if TARGET_OS_MAC
+#if defined(TARGET_OS_MAC)
 #    pragma pack(pop)
 #endif
 
--- a/src/java.xml/share/classes/org/xml/sax/ContentHandler.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.xml/share/classes/org/xml/sax/ContentHandler.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2005, 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
@@ -130,19 +130,15 @@
     /**
      * Receive notification of the end of a document.
      *
-     * <p><strong>There is an apparent contradiction between the
-     * documentation for this method and the documentation for {@link
-     * org.xml.sax.ErrorHandler#fatalError}.  Until this ambiguity is
-     * resolved in a future major release, clients should make no
-     * assumptions about whether endDocument() will or will not be
-     * invoked when the parser has reported a fatalError() or thrown
-     * an exception.</strong></p>
+     * <p>
+     * This method is invoked by the parser to signal it has reached the end of
+     * the document after successfully completing the parsing process.
+     * After the event, the parser will return the control to the application.
      *
-     * <p>The SAX parser will invoke this method only once, and it will
-     * be the last method invoked during the parse.  The parser shall
-     * not invoke this method until it has either abandoned parsing
-     * (because of an unrecoverable error) or reached the end of
-     * input.</p>
+     * @apiNote In case of a fatal error, the parser may choose to stop the
+     * parsing process with a {@link SAXException}, in which case, this method
+     * will never be called. Refer to
+     * {@link ErrorHandler#fatalError(org.xml.sax.SAXParseException)}.
      *
      * @throws org.xml.sax.SAXException any SAX exception, possibly
      *            wrapping another exception
--- a/src/java.xml/share/classes/org/xml/sax/ErrorHandler.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/java.xml/share/classes/org/xml/sax/ErrorHandler.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2005, 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
@@ -128,32 +128,30 @@
 
 
     /**
-     * Receive notification of a non-recoverable error.
+     * Receive notification of a non-recoverable, fatal error.
      *
-     * <p><strong>There is an apparent contradiction between the
-     * documentation for this method and the documentation for {@link
-     * org.xml.sax.ContentHandler#endDocument}.  Until this ambiguity
-     * is resolved in a future major release, clients should make no
-     * assumptions about whether endDocument() will or will not be
-     * invoked when the parser has reported a fatalError() or thrown
-     * an exception.</strong></p>
+     * <p>
+     * As defined in section 1.2 of the W3C XML 1.0 Recommendation, fatal errors
+     * are those that would make it impossible for a parser to continue normal
+     * processing. These include violation of a well-formedness constraint,
+     * invalid encoding, and forbidden structural errors as described in the
+     * W3C XML 1.0 Recommendation.
      *
-     * <p>This corresponds to the definition of "fatal error" in
-     * section 1.2 of the W3C XML 1.0 Recommendation.  For example, a
-     * parser would use this callback to report the violation of a
-     * well-formedness constraint.</p>
+     * @apiNote An application must assume that the parser can no longer perform
+     * normal processing after reporting a fatal error and may stop by throwing
+     * a {@link SAXException} without calling {@link ContentHandler#endDocument()}.
+     * In addition, the parser cannot be expected to be able to return accurate
+     * information about the logical structure on the rest of the document even
+     * if it may be able to resume parsing.
      *
-     * <p>The application must assume that the document is unusable
-     * after the parser has invoked this method, and should continue
-     * (if at all) only for the sake of collecting additional error
-     * messages: in fact, SAX parsers are free to stop reporting any
-     * other events once this method has been invoked.</p>
+     * @implNote After invoking this method, the parser may stop processing by
+     * throwing a {@link SAXException}, or implement a feature that can direct
+     * it to continue after a fatal error. In the later case, it may report
+     * events on the rest of the document without any guarantee of correctness.
      *
      * @param exception The error information encapsulated in a
-     *                  SAX parse exception.
-     * @exception org.xml.sax.SAXException Any SAX exception, possibly
-     *            wrapping another exception.
-     * @see org.xml.sax.SAXParseException
+     *                  {@link SAXParseException}.
+     * @throws SAXException if the application chooses to discontinue the parsing
      */
     public abstract void fatalError (SAXParseException exception)
         throws SAXException;
--- a/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java	Wed Aug 28 11:58:56 2019 -0400
@@ -58,8 +58,11 @@
         int pid;
         try {
             pid = Integer.parseInt(vmid);
+            if (pid < 1) {
+                throw new NumberFormatException();
+            }
         } catch (NumberFormatException x) {
-            throw new AttachNotSupportedException("Invalid process identifier");
+            throw new AttachNotSupportedException("Invalid process identifier: " + vmid);
         }
 
         // Find the socket file. If not found then we attempt to start the
--- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java	Wed Aug 28 11:58:56 2019 -0400
@@ -60,8 +60,11 @@
         int pid;
         try {
             pid = Integer.parseInt(vmid);
+            if (pid < 1) {
+                throw new NumberFormatException();
+            }
         } catch (NumberFormatException x) {
-            throw new AttachNotSupportedException("Invalid process identifier");
+            throw new AttachNotSupportedException("Invalid process identifier: " + vmid);
         }
 
         // Try to resolve to the "inner most" pid namespace
--- a/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java	Wed Aug 28 11:58:56 2019 -0400
@@ -59,8 +59,11 @@
         int pid;
         try {
             pid = Integer.parseInt(vmid);
+            if (pid < 1) {
+                throw new NumberFormatException();
+            }
         } catch (NumberFormatException x) {
-            throw new AttachNotSupportedException("Invalid process identifier");
+            throw new AttachNotSupportedException("Invalid process identifier: " + vmid);
         }
 
         // Find the socket file. If not found then we attempt to start the
--- a/src/jdk.attach/solaris/classes/sun/tools/attach/VirtualMachineImpl.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.attach/solaris/classes/sun/tools/attach/VirtualMachineImpl.java	Wed Aug 28 11:58:56 2019 -0400
@@ -60,8 +60,11 @@
         int pid;
         try {
             pid = Integer.parseInt(vmid);
+            if (pid < 1) {
+                throw new NumberFormatException();
+            }
         } catch (NumberFormatException x) {
-            throw new AttachNotSupportedException("Invalid process identifier");
+            throw new AttachNotSupportedException("Invalid process identifier: " + vmid);
         }
 
         // Opens the door file to the target VM. If the file is not
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectMonitor.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectMonitor.java	Wed Aug 28 11:58:56 2019 -0400
@@ -48,8 +48,8 @@
     objectFieldOffset = f.getOffset();
     f = type.getField("_owner");
     ownerFieldOffset = f.getOffset();
-    f = type.getField("FreeNext");
-    FreeNextFieldOffset = f.getOffset();
+    f = type.getField("_next_om");
+    nextOMFieldOffset = f.getOffset();
     contentionsField  = type.getJIntField("_contentions");
     waitersField = type.getJIntField("_waiters");
     recursionsField = type.getCIntegerField("_recursions");
@@ -83,7 +83,7 @@
 
   public int    waiters() { return waitersField.getValue(addr); }
 
-  public Address freeNext() { return addr.getAddressAt(FreeNextFieldOffset); }
+  public Address nextOM() { return addr.getAddressAt(nextOMFieldOffset); }
   // FIXME
   //  void      set_queue(void* owner);
 
@@ -108,7 +108,7 @@
   private static long          headerFieldOffset;
   private static long          objectFieldOffset;
   private static long          ownerFieldOffset;
-  private static long          FreeNextFieldOffset;
+  private static long          nextOMFieldOffset;
   private static JIntField     contentionsField;
   private static JIntField     waitersField;
   private static CIntegerField recursionsField;
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectSynchronizer.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectSynchronizer.java	Wed Aug 28 11:58:56 2019 -0400
@@ -44,7 +44,7 @@
     Type type;
     try {
       type = db.lookupType("ObjectSynchronizer");
-      gBlockList = type.getAddressField("gBlockList").getValue();
+      gBlockList = type.getAddressField("g_block_list").getValue();
       blockSize = db.lookupIntConstant("ObjectSynchronizer::_BLOCKSIZE").intValue();
       defaultCacheLineSize = db.lookupIntConstant("DEFAULT_CACHE_LINE_SIZE").intValue();
     } catch (RuntimeException e) { }
@@ -101,14 +101,14 @@
     }
 
     public boolean hasNext() {
-      return (index > 0 || block.freeNext() != null);
+      return (index > 0 || block.nextOM() != null);
     }
 
     public Object next() {
       Address addr;
       if (index == 0) {
         // advance to next block
-        blockAddr = block.freeNext();
+        blockAddr = block.nextOM();
         if (blockAddr == null) {
           throw new NoSuchElementException();
         }
--- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/BasicAuthenticator.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/BasicAuthenticator.java	Wed Aug 28 11:58:56 2019 -0400
@@ -25,7 +25,11 @@
 
 package com.sun.net.httpserver;
 
+import java.nio.charset.Charset;
 import java.util.Base64;
+import java.util.Objects;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
 
 /**
  * BasicAuthenticator provides an implementation of HTTP Basic
@@ -35,15 +39,44 @@
  */
 public abstract class BasicAuthenticator extends Authenticator {
 
-    protected String realm;
+    protected final String realm;
+    protected final Charset charset;
+    private final boolean isUTF8;
+
+    /**
+     * Creates a BasicAuthenticator for the given HTTP realm.
+     * The Basic authentication credentials (username and password) are decoded
+     * using the platform's {@link Charset#defaultCharset() default character set}.
+     *
+     * @param realm The HTTP Basic authentication realm
+     * @throws NullPointerException if realm is {@code null}
+     * @throws IllegalArgumentException if realm is an empty string
+     */
+    public BasicAuthenticator (String realm) {
+        this(realm, Charset.defaultCharset());
+    }
 
     /**
-     * Creates a BasicAuthenticator for the given HTTP realm
+     * Creates a BasicAuthenticator for the given HTTP realm and using the
+     * given {@link Charset} to decode the Basic authentication credentials
+     * (username and password).
+     *
+     * @apiNote {@code UTF-8} is the recommended charset because its usage is
+     * communicated to the client, and therefore more likely to be used also
+     * by the client.
+     *
      * @param realm The HTTP Basic authentication realm
-     * @throws NullPointerException if the realm is an empty string
+     * @param charset The Charset to decode incoming credentials from the client
+     * @throws NullPointerException if realm or charset are {@code null}
+     * @throws IllegalArgumentException if realm is an empty string
      */
-    public BasicAuthenticator (String realm) {
+    public BasicAuthenticator (String realm, Charset charset) {
+        Objects.requireNonNull(charset);
+        if (realm.isEmpty()) // implicit NPE check
+            throw new IllegalArgumentException("realm must not be empty");
         this.realm = realm;
+        this.charset = charset;
+        this.isUTF8 = charset.equals(UTF_8);
     }
 
     /**
@@ -63,7 +96,9 @@
         String auth = rmap.getFirst ("Authorization");
         if (auth == null) {
             Headers map = t.getResponseHeaders();
-            map.set ("WWW-Authenticate", "Basic realm=" + "\""+realm+"\"");
+            var authString = "Basic realm=" + "\"" + realm + "\"" +
+                (isUTF8 ? " charset=\"UTF-8\"" : "");
+            map.set ("WWW-Authenticate", authString);
             return new Authenticator.Retry (401);
         }
         int sp = auth.indexOf (' ');
@@ -71,7 +106,7 @@
             return new Authenticator.Failure (401);
         }
         byte[] b = Base64.getDecoder().decode(auth.substring(sp+1));
-        String userpass = new String (b);
+        String userpass = new String (b, charset);
         int colon = userpass.indexOf (':');
         String uname = userpass.substring (0, colon);
         String pass = userpass.substring (colon+1);
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot.test/src/org/graalvm/compiler/hotspot/test/CheckGraalIntrinsics.java	Wed Aug 28 11:58:56 2019 -0400
@@ -409,6 +409,16 @@
                             "java/lang/Math.max(FF)F",
                             "java/lang/Math.min(DD)D",
                             "java/lang/Math.min(FF)F");
+            add(toBeInvestigated,
+                            "jdk/internal/misc/Unsafe.writeback0(J)V",
+                            "jdk/internal/misc/Unsafe.writebackPostSync0()V",
+                            "jdk/internal/misc/Unsafe.writebackPreSync0()V");
+        }
+
+        if (isJDK14OrHigher()) {
+            add(toBeInvestigated,
+                            "com/sun/crypto/provider/ElectronicCodeBook.implECBDecrypt([BII[BI)I",
+                            "com/sun/crypto/provider/ElectronicCodeBook.implECBEncrypt([BII[BI)I");
         }
 
         if (!config.inlineNotify()) {
@@ -583,6 +593,10 @@
         return JavaVersionUtil.JAVA_SPEC >= 13;
     }
 
+    private static boolean isJDK14OrHigher() {
+        return JavaVersionUtil.JAVA_SPEC >= 14;
+    }
+
     public interface Refiner {
         void refine(CheckGraalIntrinsics checker);
     }
--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/replacements/MonitorSnippets.java	Wed Aug 28 11:58:56 2019 -0400
@@ -149,7 +149,7 @@
  * atomic operations with biased locking and bulk rebiasing</a> by Kenneth Russell and David
  * Detlefs.
  *
- * Comment below is reproduced from {@code markOop.hpp} for convenience:
+ * Comment below is reproduced from {@code markWord.hpp} for convenience:
  *
  * <pre>
  *  Bit-format of an object header (most significant first, big endian layout below):
--- a/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java	Wed Aug 28 11:58:56 2019 -0400
@@ -300,7 +300,7 @@
                 sb.append("$DIR/java $JLINK_VM_OPTIONS -m ")
                         .append(module).append('/')
                         .append(mainClassName)
-                        .append(" $@\n");
+                        .append(" \"$@\"\n");
 
                 try (BufferedWriter writer = Files.newBufferedWriter(cmd,
                         StandardCharsets.ISO_8859_1,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.nio.mapmode/share/classes/jdk/nio/mapmode/ExtendedMapMode.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+package jdk.nio.mapmode;
+
+import java.nio.channels.FileChannel.MapMode;
+
+/**
+ * JDK-specific map modes.
+ *
+ * @since 14
+ * @see java.nio.channels.FileChannel#map
+ */
+public class ExtendedMapMode {
+    private ExtendedMapMode() { }
+
+    /**
+     * File mapping mode for a read-only mapping of a file backed by
+     * non-volatile RAM.
+     *
+     * <p> The {@linkplain FileChannel#map map} method throws
+     * {@linkplain UnsupportedOperationException} when this map mode
+     * is used on an implementation that does not support it.
+     *
+     * @implNote On Linux, the {@code MAP_SYNC} and {@code
+     * MAP_SHARED_VALIDATE} flags are specified to {@code mmap} when
+     * mapping the file into memory.
+     */
+    public static final MapMode READ_ONLY_SYNC = jdk.internal.misc.ExtendedMapMode.READ_ONLY_SYNC;
+
+    /**
+     * File mapping mode for a read-write mapping of a file backed by
+     * non-volatile RAM. {@linkplain MappedByteBufefr#force force}
+     * operations on a buffer created with this mode will be performed
+     * using cache line writeback rather than proceeding via a file
+     * device flush.
+     *
+     * <p> The {@linkplain FileChannel#map map} method throws
+     * {@linkplain UnsupportedOperationException} when this map mode
+     * is used on an implementation that does not support it.
+     *
+     * @implNote On Linux, the {@code MAP_SYNC} and {@code
+     * MAP_SHARED_VALIDATE} flags are specified to {@code mmap} when
+     * mapping the file into memory.
+     */
+    public static final MapMode READ_WRITE_SYNC = jdk.internal.misc.ExtendedMapMode.READ_WRITE_SYNC;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.nio.mapmode/share/classes/module-info.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/**
+ * Defines JDK-specific file mapping modes.
+ *
+ * @moduleGraph
+ * @since 14
+ */
+
+module jdk.nio.mapmode {
+    exports jdk.nio.mapmode;
+}
--- a/src/jdk.rmic/share/classes/sun/tools/java/BinaryAttribute.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.rmic/share/classes/sun/tools/java/BinaryAttribute.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2003, 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
@@ -105,7 +105,7 @@
 
     public Identifier getName() { return name; }
 
-    public byte getData()[] { return data; }
+    public byte[] getData() { return data; }
 
     public BinaryAttribute getNextAttribute() { return next; }
 
--- a/src/jdk.rmic/share/classes/sun/tools/java/BinaryClass.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.rmic/share/classes/sun/tools/java/BinaryClass.java	Wed Aug 28 11:58:56 2019 -0400
@@ -531,7 +531,7 @@
     /**
      * Get a class attribute
      */
-    public byte getAttribute(Identifier name)[] {
+    public byte[] getAttribute(Identifier name) {
         for (BinaryAttribute att = atts ; att != null ; att = att.next) {
             if (att.name.equals(name)) {
                 return att.data;
--- a/src/jdk.rmic/share/classes/sun/tools/java/BinaryCode.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.rmic/share/classes/sun/tools/java/BinaryCode.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -88,11 +88,11 @@
      * Accessors
      */
 
-    public BinaryExceptionHandler getExceptionHandlers()[] {
+    public BinaryExceptionHandler[] getExceptionHandlers() {
         return exceptionHandlers;
     }
 
-    public byte getCode()[] { return code; }
+    public byte[] getCode() { return code; }
 
     public int getMaxStack() { return maxStack; }
 
--- a/src/jdk.rmic/share/classes/sun/tools/java/ClassDefinition.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.rmic/share/classes/sun/tools/java/ClassDefinition.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -224,7 +224,7 @@
     /**
      * Get the class' interfaces
      */
-    public final ClassDeclaration getInterfaces()[] {
+    public final ClassDeclaration[] getInterfaces() {
         if (interfaces == null)  throw new CompilerError("getInterfaces");
         return interfaces;
     }
--- a/src/jdk.rmic/share/classes/sun/tools/java/MethodType.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.rmic/share/classes/sun/tools/java/MethodType.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2003, 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
@@ -62,7 +62,7 @@
         return returnType;
     }
 
-    public Type getArgumentTypes()[] {
+    public Type[] getArgumentTypes() {
         return argTypes;
     }
 
--- a/src/jdk.rmic/share/classes/sun/tools/java/Parser.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.rmic/share/classes/sun/tools/java/Parser.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2004, 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
@@ -282,13 +282,13 @@
         }
         args[argIndex++] = n;
     }
-    protected final Expression exprArgs(int index)[] {
+    protected final Expression[] exprArgs(int index) {
         Expression e[] = new Expression[argIndex - index];
         System.arraycopy(args, index, e, 0, argIndex - index);
         argIndex = index;
         return e;
     }
-    protected final Statement statArgs(int index)[] {
+    protected final Statement[] statArgs(int index) {
         Statement s[] = new Statement[argIndex - index];
         System.arraycopy(args, index, s, 0, argIndex - index);
         argIndex = index;
--- a/src/jdk.rmic/share/classes/sun/tools/java/Type.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.rmic/share/classes/sun/tools/java/Type.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2003, 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
@@ -300,7 +300,7 @@
     /**
      * Return the argument types. Only works for method types.
      */
-    public Type getArgumentTypes()[] {
+    public Type[] getArgumentTypes() {
         throw new CompilerError("getArgumentTypes");
     }
 
--- a/src/jdk.sctp/unix/native/libsctp/SctpNet.c	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.sctp/unix/native/libsctp/SctpNet.c	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2016, 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
@@ -400,7 +400,7 @@
     int i, addrCount;
     jobjectArray isaa;
 
-#if __solaris__
+#if defined(__solaris__)
     if ((addrCount = nio_sctp_getpaddrs(fd, id, (void **)&addr_buf)) == -1) {
 #else /* __linux__ */
     if ((addrCount = nio_sctp_getpaddrs(fd, id, (struct sockaddr **)&addr_buf)) == -1) {
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1458,7 +1458,7 @@
             return 0;
 
         long written = 0;
-        if (e.csize > 0 && (e.crc != 0 || e.size == 0)) {
+        if (e.method != METHOD_STORED && e.csize > 0 && (e.crc != 0 || e.size == 0)) {
             // pre-compressed entry, write directly to output stream
             writeTo(e, os);
         } else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/gtest/gc/shared/test_oopStorageSet.cpp	Wed Aug 28 11:58:56 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc/shared/oopStorage.hpp"
+#include "gc/shared/oopStorageSet.hpp"
+#include "memory/allocation.inline.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/macros.hpp"
+#include "unittest.hpp"
+
+// GTEST assertions may introduce ODR-uses.  Dodge them.
+template<typename T> static T no_odr(T x) { return x; }
+
+static void fill_strong(OopStorage** storages, size_t size) {
+  ASSERT_EQ(size, no_odr(OopStorageSet::strong_count));
+  STATIC_ASSERT(2 == OopStorageSet::strong_count);
+  storages[0] = OopStorageSet::jni_global();
+  storages[1] = OopStorageSet::vm_global();
+}
+
+static void fill_weak(OopStorage** storages, size_t size) {
+  ASSERT_EQ(size, no_odr(OopStorageSet::weak_count));
+  STATIC_ASSERT(4 == OopStorageSet::weak_count);
+  storages[0] = OopStorageSet::jni_weak();
+  storages[1] = OopStorageSet::vm_weak();
+  storages[2] = OopStorageSet::string_table_weak();
+  storages[3] = OopStorageSet::resolved_method_table_weak();
+}
+
+static void fill_all(OopStorage** storages, size_t size) {
+  ASSERT_EQ(size, no_odr(OopStorageSet::all_count));
+  const uint strong_count = OopStorageSet::strong_count;
+  fill_strong(storages, strong_count);
+  fill_weak(storages + strong_count, size - strong_count);
+}
+
+// Returns index of s in storages, or size if not found.
+static size_t find_storage(OopStorage* s, OopStorage** storages, size_t size) {
+  for (uint i = 0; i < size; ++i) {
+    if (s == storages[i]) {
+      return i;
+    }
+  }
+  return size;
+}
+
+static void check_iterator(OopStorageSet::Iterator it,
+                           OopStorage** storages,
+                           size_t size) {
+  OopStorageSet::Iterator start = it;
+  ASSERT_EQ(start, it);
+  for ( ; !it.is_end(); ++it) {
+    size_t index = find_storage(*it, storages, size);
+    ASSERT_LT(index, size);
+    storages[index] = NULL;
+  }
+  ASSERT_NE(start, it);
+  const OopStorage* null_storage = NULL;
+  for (uint i = 0; i < size; ++i) {
+    ASSERT_EQ(null_storage, storages[i]);
+  }
+}
+
+static void test_iterator(uint count,
+                          OopStorageSet::Iterator iterator,
+                          void (*fill)(OopStorage**, size_t)) {
+  OopStorage** storages = NEW_C_HEAP_ARRAY(OopStorage*, count, mtGC);
+  fill(storages, count);
+  check_iterator(iterator, storages, count);
+  FREE_C_HEAP_ARRAY(OopStorage*, storages);
+}
+
+#define TEST_ITERATOR(kind)                                             \
+  TEST_VM(OopStorageSetTest, PASTE_TOKENS(kind, _iterator)) {           \
+    test_iterator(OopStorageSet::PASTE_TOKENS(kind, _count),            \
+                  OopStorageSet::PASTE_TOKENS(kind, _iterator)(),       \
+                  &PASTE_TOKENS(fill_, kind));                          \
+  }
+
+TEST_ITERATOR(strong);
+TEST_ITERATOR(weak)
+TEST_ITERATOR(all)
--- a/test/hotspot/gtest/oops/test_markOop.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/gtest/oops/test_markOop.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -98,9 +98,10 @@
   // Lock using biased locking.
   BasicObjectLock lock;
   lock.set_obj(obj);
-  markWord mark = obj->mark().incr_bias_epoch();
-  obj->set_mark(mark);
-  ObjectSynchronizer::fast_enter(h_obj, lock.lock(), true, THREAD);
+  markWord prototype_header = obj->klass()->prototype_header();
+  markWord mark = obj->mark();
+  markWord biased_mark = markWord::encode((JavaThread*) THREAD, mark.age(), prototype_header.bias_epoch());
+  obj->set_mark(biased_mark);
   // Look for the biased_locker in markWord, not prototype_header.
 #ifdef _LP64
   assert_not_test_pattern(h_obj, "mark(is_biased biased_locker=0x0000000000000000");
--- a/test/hotspot/gtest/runtime/test_os_linux.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/gtest/runtime/test_os_linux.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -27,7 +27,9 @@
 
 #include <sys/mman.h>
 
+#include "runtime/globals.hpp"
 #include "runtime/os.hpp"
+#include "utilities/align.hpp"
 #include "unittest.hpp"
 
 namespace {
--- a/test/hotspot/gtest/runtime/test_synchronizer.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/gtest/runtime/test_synchronizer.cpp	Wed Aug 28 11:58:56 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
@@ -30,9 +30,9 @@
 class SynchronizerTest : public ::testing::Test {
   public:
     static u_char* get_gvars_addr() { return ObjectSynchronizer::get_gvars_addr(); }
-    static u_char* get_gvars_hcSequence_addr() { return ObjectSynchronizer::get_gvars_hcSequence_addr(); }
+    static u_char* get_gvars_hc_sequence_addr() { return ObjectSynchronizer::get_gvars_hc_sequence_addr(); }
     static size_t get_gvars_size() { return ObjectSynchronizer::get_gvars_size(); }
-    static u_char* get_gvars_stwRandom_addr() { return ObjectSynchronizer::get_gvars_stwRandom_addr(); }
+    static u_char* get_gvars_stw_random_addr() { return ObjectSynchronizer::get_gvars_stw_random_addr(); }
 };
 
 TEST_VM(SynchronizerTest, sanity) {
@@ -42,27 +42,27 @@
     // do some cache line specific sanity checks
 
     u_char *addr_begin = SynchronizerTest::get_gvars_addr();
-    u_char *addr_stwRandom = SynchronizerTest::get_gvars_stwRandom_addr();
-    u_char *addr_hcSequence = SynchronizerTest::get_gvars_hcSequence_addr();
+    u_char *addr_stw_random = SynchronizerTest::get_gvars_stw_random_addr();
+    u_char *addr_hc_sequence = SynchronizerTest::get_gvars_hc_sequence_addr();
     size_t gvars_size = SynchronizerTest::get_gvars_size();
 
-    uint offset_stwRandom = (uint) (addr_stwRandom - addr_begin);
-    uint offset_hcSequence = (uint) (addr_hcSequence - addr_begin);
-    uint offset_hcSequence_stwRandom = offset_hcSequence - offset_stwRandom;
-    uint offset_hcSequence_struct_end = (uint) gvars_size - offset_hcSequence;
+    uint offset_stw_random = (uint) (addr_stw_random - addr_begin);
+    uint offset_hc_sequence = (uint) (addr_hc_sequence - addr_begin);
+    uint offset_hc_sequence_stw_random = offset_hc_sequence - offset_stw_random;
+    uint offset_hc_sequence_struct_end = (uint) gvars_size - offset_hc_sequence;
 
-    EXPECT_GE(offset_stwRandom, cache_line_size)
-            << "the SharedGlobals.stwRandom field is closer "
+    EXPECT_GE(offset_stw_random, cache_line_size)
+            << "the SharedGlobals.stw_random field is closer "
             << "to the struct beginning than a cache line which permits "
             << "false sharing.";
 
-    EXPECT_GE(offset_hcSequence_stwRandom, cache_line_size)
-            << "the SharedGlobals.stwRandom and "
-            << "SharedGlobals.hcSequence fields are closer than a cache "
+    EXPECT_GE(offset_hc_sequence_stw_random, cache_line_size)
+            << "the SharedGlobals.stw_random and "
+            << "SharedGlobals.hc_sequence fields are closer than a cache "
             << "line which permits false sharing.";
 
-    EXPECT_GE(offset_hcSequence_struct_end, cache_line_size)
-            << "the SharedGlobals.hcSequence field is closer "
+    EXPECT_GE(offset_hc_sequence_struct_end, cache_line_size)
+            << "the SharedGlobals.hc_sequence field is closer "
             << "to the struct end than a cache line which permits false "
             << "sharing.";
   }
--- a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp	Wed Aug 28 11:58:56 2019 -0400
@@ -24,6 +24,7 @@
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
 #include "unittest.hpp"
+#include "utilities/align.hpp"
 #include "utilities/globalDefinitions.hpp"
 
 static ::testing::AssertionResult testPageAddress(
--- a/test/hotspot/jtreg/ProblemList.txt	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/ProblemList.txt	Wed Aug 28 11:58:56 2019 -0400
@@ -49,9 +49,8 @@
 compiler/jvmci/compilerToVM/InvalidateInstalledCodeTest.java 8163894 generic-all
 compiler/tiered/LevelTransitionTest.java 8067651 generic-all
 
-compiler/types/correctness/CorrectnessTest.java 8225620 solaris-sparcv9
-compiler/types/correctness/OffTest.java         8225620 solaris-sparcv9
-compiler/unsafe/UnsafeGetConstantField.java     8229446 solaris-sparcv9
+compiler/types/correctness/CorrectnessTest.java 8230019,8225620 generic-all,solaris-sparcv9
+compiler/types/correctness/OffTest.java         8230019,8225620 generic-all,solaris-sparcv9
 
 compiler/c2/Test6852078.java 8194310 generic-all
 compiler/c2/Test8004741.java 8214904 generic-all
--- a/test/hotspot/jtreg/TEST.groups	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/TEST.groups	Wed Aug 28 11:58:56 2019 -0400
@@ -278,6 +278,7 @@
  -runtime/ErrorHandling/CreateCoredumpOnCrash.java \
  -runtime/ErrorHandling/ErrorHandler.java \
  -runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryError.java \
+ -runtime/ErrorHandling/TestHeapDumpOnOutOfMemoryErrorInMetaspace.java \
  -runtime/ErrorHandling/TimeoutInErrorHandlingTest.java \
  -runtime/InvocationTests \
  -runtime/logging/MonitorMismatchTest.java \
--- a/test/hotspot/jtreg/compiler/loopopts/LoopUnswitchingBadNodeBudget.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/compiler/loopopts/LoopUnswitchingBadNodeBudget.java	Wed Aug 28 11:58:56 2019 -0400
@@ -32,7 +32,7 @@
  * @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation
  *      -XX:-UseOnStackReplacement -XX:CompileOnly=LoopUnswitchingBadNodeBudget::test
  *      -XX:CompileCommand=dontinline,LoopUnswitchingBadNodeBudget::helper
- *      -XX:+UnlockExperimentalVMOptions -XX:-UseSwitchProfiling LoopUnswitchingBadNodeBudget
+ *      -XX:+UnlockDiagnosticVMOptions -XX:-UseSwitchProfiling LoopUnswitchingBadNodeBudget
  *
  */
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/StrangeControl.jasm	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+super public class compiler/loopopts/StrangeControl
+  version 51:0
+{
+
+static Field field:"I";
+
+public static Method test:"(I)V"
+  stack 2 locals 2
+{
+    iconst_0;
+    istore 1;
+  L1: stack_frame_type append;
+    locals_map int;
+    iinc  1, 1;
+    iload 1;
+    iconst_2;
+    if_icmple L1;
+  L2: stack_frame_type same;
+    iload_0;
+    putstatic Field field:"I";
+    goto L1;
+}
+
+} // end Class StrangeControl
--- a/test/hotspot/jtreg/compiler/loopopts/TestOverunrolling.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/compiler/loopopts/TestOverunrolling.java	Wed Aug 28 11:58:56 2019 -0400
@@ -26,7 +26,7 @@
  * @bug 8159016 8202949 8203915
  * @summary Tests correct dominator information after over-unrolling a loop.
  * @requires vm.gc == "Parallel" | vm.gc == "null"
- * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockExperimentalVMOptions
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
  *                   -Xcomp -XX:-TieredCompilation -XX:-UseSwitchProfiling
  *                   -XX:-UseCountedLoopSafepoints -XX:LoopUnrollLimit=250
  *                   -XX:-UseG1GC -XX:+UseParallelGC compiler.loopopts.TestOverunrolling
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/loopopts/TestStrangeControl.java	Wed Aug 28 11:58:56 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.
+ *
+ */
+
+/*
+ * @test
+ * @bug 8228888
+ * @summary Test PhaseIdealLoop::has_local_phi_input() with phi input with non-dominating control.
+ * @compile StrangeControl.jasm
+ * @run main/othervm -Xbatch -XX:CompileCommand=inline,compiler.loopopts.StrangeControl::test
+ *                   compiler.loopopts.TestStrangeControl
+ */
+
+package compiler.loopopts;
+
+public class TestStrangeControl {
+
+    public static void main(String[] args) throws Exception {
+        Thread thread = new Thread() {
+            public void run() {
+                // Run this in an own thread because it's basically an endless loop
+                StrangeControl.test(42);
+            }
+        };
+        thread.start();
+        // Give thread executing strange control loop enough time to trigger OSR compilation
+        Thread.sleep(4000);
+    }
+}
--- a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java	Wed Aug 28 11:58:56 2019 -0400
@@ -159,9 +159,10 @@
         new LogMessageWithLevel("Reference Processing", Level.DEBUG),
         // VM internal reference processing
         new LogMessageWithLevel("Weak Processing", Level.DEBUG),
-        new LogMessageWithLevel("JNI weak processing", Level.DEBUG),
-        new LogMessageWithLevel("StringTable weak processing", Level.DEBUG),
-        new LogMessageWithLevel("VM weak processing", Level.DEBUG),
+        new LogMessageWithLevel("JNI weak", Level.DEBUG),
+        new LogMessageWithLevel("StringTable weak", Level.DEBUG),
+        new LogMessageWithLevel("ResolvedMethodTable weak", Level.DEBUG),
+        new LogMessageWithLevel("VM weak", Level.DEBUG),
 
         new LogMessageWithLevelC2OrJVMCIOnly("DerivedPointerTable Update", Level.DEBUG),
         new LogMessageWithLevel("Start New Collection Set", Level.DEBUG),
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestHeuristicsUnlock.java	Wed Aug 28 11:58:56 2019 -0400
@@ -48,7 +48,7 @@
         testWith("-XX:ShenandoahGCHeuristics=static", Mode.PRODUCT);
         testWith("-XX:ShenandoahGCHeuristics=compact", Mode.PRODUCT);
 
-        testWith("-XX:ShenandoahGCMode=traversal", Mode.EXPERIMENTAL);
+        testWith("-XX:ShenandoahGCMode=traversal", Mode.PRODUCT);
 
         testWith("-XX:ShenandoahGCHeuristics=aggressive", Mode.DIAGNOSTIC);
         testWith("-XX:ShenandoahGCHeuristics=passive", Mode.DIAGNOSTIC);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/LoadLibrary/TestSunBootLibraryPath.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestSunBootLibraryPath.java
+ * @bug 8227021
+ * @summary Confirm using too-long paths in sun.boot.library.path causes failure and useful error message.
+ * @author afarley
+ * @library /test/lib
+ * @build jdk.test.lib.process.ProcessTools
+ * @run driver TestSunBootLibraryPath
+ */
+
+import jdk.test.lib.process.ProcessTools;
+
+public class TestSunBootLibraryPath {
+    static String expectedErrorMessage = "The VM tried to use a path that exceeds the maximum path length for this system.";
+
+    public static void main(String[] args) throws Exception {
+        // Allows us to re-use this class as a do-nothing test class simply by passing a "Do-Nothing" argument.
+        if (args.length == 0) {
+            // Grab any path.
+            String tooLongPath = System.getProperty("sun.boot.library.path");
+            // Add enough characters to make it "too long".
+            tooLongPath += "a".repeat(5000);
+            // Start a java process with this property set, and check that:
+            // 1) The process failed and
+            // 2) The error message was correct.
+            ProcessTools.executeTestJvm("-Dsun.boot.library.path=" + tooLongPath,
+                                        "TestSunBootLibraryPath",
+                                        "'Do-Nothing'")
+                                        .shouldNotHaveExitValue(0)
+                                        .stdoutShouldContain(expectedErrorMessage);
+        } else if (!args[0].equals("Do-Nothing")) {
+            // Fail, to prevent accidental args from causing accidental test passing.
+            throw new IllegalArgumentException("Test was launched with an invalid argument.");
+        }
+    }
+}
--- a/test/hotspot/jtreg/runtime/cds/appcds/AppendClasspath.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/runtime/cds/appcds/AppendClasspath.java	Wed Aug 28 11:58:56 2019 -0400
@@ -95,19 +95,5 @@
         "-cp", appJar2 + File.pathSeparator + appJar,
         "HelloMore")
         .assertAbnormalExit(errorMessage1, errorMessage2);
-
-    // FAIL: 4) non-existing jar during dump time but jar exists during runtime
-    TestCommon.testDump(classPath, TestCommon.list("Hello"));
-
-    Files.copy(Paths.get(classDir, "hello.jar"),
-        Paths.get(classDir, newFile),
-        StandardCopyOption.REPLACE_EXISTING);
-
-    TestCommon.run(
-        "-cp", classPath,
-        "-Xlog:class+path=trace",
-        "Hello")
-        .assertAbnormalExit(errorMessage1, errorMessage2);
-
     }
 }
--- a/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java	Wed Aug 28 11:58:56 2019 -0400
@@ -42,6 +42,11 @@
 public class ClassPathAttr {
 
   public static void main(String[] args) throws Exception {
+    testNormalOps();
+    testNonExistentJars();
+  }
+
+  static void testNormalOps() throws Exception {
     buildCpAttr("cpattr1", "cpattr1.mf", "CpAttr1", "CpAttr1");
     buildCpAttr("cpattr1_long", "cpattr1_long.mf", "CpAttr1", "CpAttr1");
     buildCpAttr("cpattr2", "cpattr2.mf", "CpAttr2", "CpAttr2");
@@ -93,6 +98,37 @@
     }
   }
 
+  static void testNonExistentJars() throws Exception {
+    buildCpAttr("cpattr6", "cpattr6.mf", "CpAttr6", "CpAttr6");
+
+    String cp = TestCommon.getTestJar("cpattr6.jar");
+    String nonExistPath = System.getProperty("test.classes") + File.separator + "cpattrX.jar";
+    (new File(nonExistPath)).delete();
+
+    TestCommon.testDump(cp, TestCommon.list("CpAttr6"),
+        "-Xlog:class+path");
+
+    TestCommon.run(
+        "-Xlog:class+path",
+        "-cp", cp,
+        "CpAttr6")
+      .assertNormalExit(output -> {
+          output.shouldMatch("should be non-existent: .*cpattrX.jar");
+        });
+
+    // Now make nonExistPath exist. CDS still loads, but archived non-system classes will not be used.
+    Files.copy(Paths.get(cp), Paths.get(nonExistPath),
+               StandardCopyOption.REPLACE_EXISTING);
+
+    TestCommon.run(
+        "-Xlog:class+path",
+        "-cp", cp,
+        "CpAttr6")
+      .assertNormalExit(output -> {
+          output.shouldMatch("Archived non-system classes are disabled because the file .*cpattrX.jar exists");
+        });
+  }
+
   private static void buildCpAttr(String jarName, String manifest, String enclosingClassName, String ...testClassNames) throws Exception {
     String jarClassesDir = System.getProperty("test.classes") + File.separator + jarName + "_classes";
     try { Files.createDirectory(Paths.get(jarClassesDir)); } catch (FileAlreadyExistsException e) { }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/cds/appcds/NonExistClasspath.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @summary Handling of non-existent classpath elements during dump time and run time
+ * @requires vm.cds
+ * @library /test/lib
+ * @modules jdk.jartool/sun.tools.jar
+ * @compile test-classes/Hello.java
+ * @compile test-classes/HelloMore.java
+ * @run driver NonExistClasspath
+ */
+
+import java.io.File;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class NonExistClasspath {
+    public static void main(String[] args) throws Exception {
+        String appJar = JarBuilder.getOrCreateHelloJar();
+        doTest(appJar, false);
+        doTest(appJar, true);
+    }
+
+    static void doTest(String appJar, boolean bootcp) throws Exception {
+        String classDir = System.getProperty("test.classes");
+        String newFile = "non-exist.jar";
+        String nonExistPath = classDir + File.separator + newFile;
+        final String errorMessage1 = "Unable to use shared archive";
+        final String errorMessage2 = "shared class paths mismatch";
+        final String errorMessage3 = (bootcp ? "BOOT" : "APP") + " classpath mismatch";
+
+        (new File(nonExistPath)).delete();
+
+        String classPath = nonExistPath + File.pathSeparator + appJar;
+        TestCommon.testDump("foobar", TestCommon.list("Hello"), make_args(bootcp, classPath));
+
+        // The nonExistPath doesn't exist yet, so we should be able to run without problem
+        TestCommon.run(make_args(bootcp,
+                                 classPath,
+                                 "-Xlog:class+path=trace",
+                                 "Hello"))
+            .assertNormalExit();
+
+        // Replace nonExistPath with another non-existent file in the CP, it should still work
+        TestCommon.run(make_args(bootcp,
+                                 nonExistPath + ".duh"  + File.pathSeparator + appJar,
+                                 "-Xlog:class+path=trace",
+                                 "Hello"))
+            .assertNormalExit();
+
+        // Add a few more non-existent files in the CP, it should still work
+        TestCommon.run(make_args(bootcp,
+                                 nonExistPath + ".duh"  + File.pathSeparator +
+                                 nonExistPath + ".daa"  + File.pathSeparator +
+                                 nonExistPath + ".boo"  + File.pathSeparator +
+                                 appJar,
+                                 "-Xlog:class+path=trace",
+                                 "Hello"))
+            .assertNormalExit();
+
+        // Or, remove all non-existent paths from the CP, it should still work
+        TestCommon.run(make_args(bootcp,
+                                 appJar,
+                                 "-Xlog:class+path=trace",
+                                 "Hello"))
+            .assertNormalExit();
+
+        // Now make nonExistPath exist. CDS will fail to load.
+        Files.copy(Paths.get(classDir, "hello.jar"),
+                   Paths.get(classDir, newFile),
+                   StandardCopyOption.REPLACE_EXISTING);
+
+        TestCommon.run(make_args(bootcp,
+                                 classPath,
+                                 "-Xlog:class+path=trace",
+                                 "Hello"))
+            .assertAbnormalExit(errorMessage1, errorMessage2, errorMessage3);
+    }
+
+    static String[] make_args(boolean bootcp, String cp, String... suffix) {
+        String args[];
+        if (bootcp) {
+            args = TestCommon.concat("-Xbootclasspath/a:" + cp);
+        } else {
+            args = TestCommon.concat("-cp", cp);
+        }
+
+        return TestCommon.concat(args, suffix);
+    }
+}
--- a/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/runtime/cds/appcds/SharedArchiveConsistency.java	Wed Aug 28 11:58:56 2019 -0400
@@ -61,7 +61,6 @@
     public static int offset_version;   // CDSFileMapHeaderBase::_version
     public static int offset_jvm_ident; // FileMapHeader::_jvm_ident
     public static int sp_offset_crc;    // CDSFileMapRegion::_crc
-    public static int offset_paths_misc_info_size;
     public static int file_header_size = -1;// total size of header, variant, need calculation
     public static int CDSFileMapRegion_size; // size of CDSFileMapRegion
     public static int sp_offset;       // offset of CDSFileMapRegion
@@ -117,12 +116,6 @@
         // this is not real header size, it is struct size
         int_size = wb.getOffsetForName("int_size");
         file_header_size = wb.getOffsetForName("file_header_size");
-        offset_paths_misc_info_size = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") -
-            offset_magic;
-        int path_misc_info_size   = (int)readInt(fc, offset_paths_misc_info_size, int_size);
-        file_header_size += path_misc_info_size;
-        System.out.println("offset_paths_misc_info_size = " + offset_paths_misc_info_size);
-        System.out.println("path_misc_info_size   = " + path_misc_info_size);
         System.out.println("file_header_size      = " + file_header_size);
         file_header_size = (int)align_up_page(file_header_size);
         System.out.println("file_header_size (aligned to page) = " + file_header_size);
@@ -405,10 +398,9 @@
         output.shouldNotContain("Checksum verification failed");
 
         copyFile(orgJsaFile, jsa);
-        // modify _jvm_ident and _paths_misc_info_size, test should fail
-        System.out.println("\n2a. Corrupt _jvm_ident and _paths_misc_info_size, should fail\n");
+        // modify _jvm_ident, test should fail
+        System.out.println("\n2a. Corrupt _jvm_ident, should fail\n");
         modifyJvmIdent();
-        modifyHeaderIntField(offset_paths_misc_info_size, Integer.MAX_VALUE);
         output = TestCommon.execCommon(execArgs);
         output.shouldContain("The shared archive file was created by a different version or build of HotSpot");
         output.shouldNotContain("Checksum verification failed");
@@ -422,19 +414,17 @@
         output.shouldContain("Hello World");
 
         copyFile(orgJsaFile, jsa);
-        // modify _magic and _paths_misc_info_size, test should fail
-        System.out.println("\n2c. Corrupt _magic and _paths_misc_info_size, should fail\n");
+        // modify _magic, test should fail
+        System.out.println("\n2c. Corrupt _magic, should fail\n");
         modifyHeaderIntField(offset_magic, 0x00000000);
-        modifyHeaderIntField(offset_paths_misc_info_size, Integer.MAX_VALUE);
         output = TestCommon.execCommon(execArgs);
         output.shouldContain("The shared archive file has a bad magic number");
         output.shouldNotContain("Checksum verification failed");
 
         copyFile(orgJsaFile, jsa);
-        // modify _version and _paths_misc_info_size, test should fail
-        System.out.println("\n2d. Corrupt _version and _paths_misc_info_size, should fail\n");
+        // modify _version, test should fail
+        System.out.println("\n2d. Corrupt _version, should fail\n");
         modifyHeaderIntField(offset_version, 0x00000000);
-        modifyHeaderIntField(offset_paths_misc_info_size, Integer.MAX_VALUE);
         output = TestCommon.execCommon(execArgs);
         output.shouldContain("The shared archive file has the wrong version");
         output.shouldNotContain("Checksum verification failed");
--- a/test/hotspot/jtreg/runtime/cds/appcds/TraceLongClasspath.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/runtime/cds/appcds/TraceLongClasspath.java	Wed Aug 28 11:58:56 2019 -0400
@@ -24,7 +24,7 @@
 
 /*
  * @test
- * @summary ensure -XX:+TraceClassPaths showing entire expecting app classpath
+ * @summary ensure -Xlog:class+path showing entire expecting app classpath
  * @requires vm.cds
  * @library /test/lib
  * @modules jdk.jartool/sun.tools.jar
@@ -85,22 +85,23 @@
             "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/jdk/lib/tools.jar" + ps +
             "/scratch/xxxx/yyyy/ZZZZZZ/aaaaaaaaaa/xx/foobar_common/modules/foobar.ooo_12.1.3/ooo-manifest.jar";
 
-        String myCP = longClassPath + ps + appJar;
+        String dumpCP = longClassPath + ps + appJar;
         // Dump an archive with a specified JAR file in -classpath
-        TestCommon.testDump(myCP, TestCommon.list("Hello"));
+        TestCommon.testDump(dumpCP, TestCommon.list("Hello"));
 
-        // Then try to execute the archive with a different classpath and with -XX:+TraceClassPaths.
-        // The diagnosis "expecting" app classpath trace should show the entire classpath.
+        // Then try to execute the archive with a different classpath and with -Xlog:class+path.
+        // The diagnostic "expecting" app classpath trace should show the entire classpath (excluding any non-existent dump-time paths).
+        String recordedCP = dummyJar + ps + appJar;
         TestCommon.run(
-            "-XX:+TraceClassPaths", "-Xlog:cds",
+            "-Xlog:class+path", "-Xlog:cds",
             "-cp", appJar,
             "Hello")
             .assertAbnormalExit(output -> {
                 output.shouldContain("Unable to use shared archive");
                 output.shouldContain("shared class paths mismatch");
-                // the "expecting" app classpath from -XX:+TraceClassPaths should not
+                // the "expecting" app classpath from -Xlog:class+path should not
                 // be truncated
-                output.shouldContain(myCP);
+                output.shouldContain(recordedCP);
               });
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/CpAttr6.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+public class CpAttr6 {
+    public static void main(String args[]) {
+        System.out.println("Test passed");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/cpattr6.mf	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Class-Path: cpattrX.jar
+Created-By: 1.9.0-internal (Oracle Corporation)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/serviceability/attach/AttachNegativePidTest.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,54 @@
+/*
+ * 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 Verifies that negative pids are correctly rejected
+ * @bug 8229957
+ * @requires os.family != "windows"
+ * @library /test/lib
+ * @modules jdk.attach/com.sun.tools.attach
+ * @run main AttachNegativePidTest
+ */
+
+import java.io.IOException;
+
+import com.sun.tools.attach.VirtualMachine;
+import com.sun.tools.attach.AttachNotSupportedException;
+
+import jdk.test.lib.apps.LingeredApp;
+
+public class AttachNegativePidTest {
+
+    public static void main(String... args) throws Exception {
+        LingeredApp app = LingeredApp.startApp();
+        String strPID = Long.toString(-1 * app.getPid());
+        try {
+            VirtualMachine.attach(strPID);
+        } catch (AttachNotSupportedException anse) {
+            // Passed
+            return;
+        }
+        throw new RuntimeException("There is no expected AttachNotSupportedException for " + strPID);
+    }
+
+}
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbLongConstant.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbLongConstant.java	Wed Aug 28 11:58:56 2019 -0400
@@ -88,7 +88,7 @@
 
     private static void checkForTruncation(String longConstantOutput) throws Exception {
 
-        // Expected values obtained from the hash_mask_in_place definition in markOop.hpp
+        // Expected values obtained from the hash_mask_in_place definition in markWord.hpp
 
         // Expected output snippet is of the form (on x64-64):
         // ...
--- a/test/jaxp/javax/xml/jaxp/unittest/transform/SecureProcessingTest.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jaxp/javax/xml/jaxp/unittest/transform/SecureProcessingTest.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
 
 import org.testng.Assert;
 import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
 
 /*
  * @test
@@ -46,6 +47,7 @@
  */
 @Listeners({jaxp.library.FilePolicy.class})
 public class SecureProcessingTest {
+    @Test
     public void testSecureProcessing() {
         boolean _isSecureMode = System.getSecurityManager() != null;
         // SECURE_PROCESSING == false
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/net/httpserver/bugs/8199849/BasicAuthenticatorCharset.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,191 @@
+/*
+ * 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 8199849
+ * @library /test/lib
+ * @run main/othervm/timeout=6000 BasicAuthenticatorCharset
+ * @summary Check for correct use of character sets with BasicAuthenticator() authentication
+ */
+
+import com.sun.net.httpserver.*;
+import jdk.test.lib.net.URIBuilder;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.*;
+
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.nio.charset.Charset;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.nio.charset.StandardCharsets.ISO_8859_1;
+
+/**
+ * Test authentication
+ */
+
+public class BasicAuthenticatorCharset {
+
+    public static volatile int failCount = 0;
+
+    static final String TEST_USER = "test";
+    static final String UNICODE_PW = "Selam D\u00fcnya. Ho\u015f\u00e7akal D\u00fcnya";
+
+    static Handler testHandler;
+    static HttpServer testHttpServer;
+    static java.net.Authenticator clientAuth;
+    static HttpClient client;
+
+    static class Handler implements HttpHandler {
+        public void handle(HttpExchange t) throws IOException {
+            InputStream is = t.getRequestBody();
+            while (is.read() != -1) ;
+            is.close();
+            t.sendResponseHeaders(200, -1);
+            t.close();
+        }
+    }
+
+    static class ClientAuthenticator extends java.net.Authenticator {
+        public PasswordAuthentication getPasswordAuthentication() {
+            return new PasswordAuthentication(TEST_USER, UNICODE_PW.toCharArray());
+        }
+    }
+
+    static void setAuthenticationPW(String path, String realm, String testPW, Charset charset) {
+        HttpContext ctx = testHttpServer.createContext(path, testHandler);
+        BasicAuthenticator auth;
+        if (charset != null) {
+            auth = new BasicAuthenticator(realm, charset) {
+                public boolean checkCredentials(String username, String pw) {
+                    return username.equals(TEST_USER) && pw.equals(testPW);
+                }
+            };
+        } else {
+            auth = new BasicAuthenticator(realm) {
+                public boolean checkCredentials(String username, String pw) {
+                    return username.equals(TEST_USER) && pw.equals(testPW);
+                }
+            };
+        }
+        ctx.setAuthenticator(auth);
+    }
+
+    static void connectAndAuth(String path, int expectedStatus) throws Exception {
+        // path is prepended with /old or /new for old and new http client
+        URL oldurl = URIBuilder.newBuilder()
+                .scheme("http")
+                .loopback()
+                .port(testHttpServer.getAddress().getPort())
+                .path("/old" + path)
+                .toURL();
+
+        URI newuri = URIBuilder.newBuilder()
+            .scheme("http")
+            .loopback()
+            .port(testHttpServer.getAddress().getPort())
+            .path("/new" + path)
+            .build();
+
+        // check old client
+
+        HttpURLConnection testConnection = (HttpURLConnection) oldurl.openConnection(Proxy.NO_PROXY);
+
+        // Check for successful authentication
+        int status = testConnection.getResponseCode();
+        if (status != 401) {
+            InputStream is = testConnection.getInputStream();
+            while (is.read() != -1) ;
+            is.close();
+        }
+        if (status != expectedStatus) {
+            System.err.println("Error (old): " + path);
+            failCount++;
+        }
+
+        HttpRequest request = HttpRequest.newBuilder()
+            .uri(newuri)
+            .GET()
+            .build();
+
+        status = -1;
+        try {
+            HttpResponse<Void> response = client.send(request, HttpResponse.BodyHandlers.discarding());
+            status = response.statusCode();
+        } catch (IOException e) {
+            System.out.println("NEW: " + e);
+            status = 401; // limitation in new API.
+        }
+        if (status != expectedStatus) {
+            System.err.println("Error (new): " + path);
+            failCount++;
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        clientAuth = new ClientAuthenticator();
+        client = HttpClient.newBuilder()
+            .authenticator(clientAuth)
+            .build();
+
+        String defaultCharset = System.getProperty("file.encoding");
+        boolean isUTF8 = defaultCharset.equalsIgnoreCase("UTF-8");
+        testHandler = new Handler();
+        InetSocketAddress addr = new InetSocketAddress(0);
+        testHttpServer = HttpServer.create(addr, 0);
+
+        // Set the passing credentials OLD client
+        setAuthenticationPW("/old/test1/", "passingCharset@test.realm", UNICODE_PW, UTF_8);
+        setAuthenticationPW("/old/test2/", "failingCharset@test.realm", UNICODE_PW, ISO_8859_1);
+        setAuthenticationPW("/old/test3/", "defaultCharset@test.realm", UNICODE_PW, null);
+
+        // Set the passing credentials NEW client
+        setAuthenticationPW("/new/test1/", "passingCharset@test.realm", UNICODE_PW, UTF_8);
+        setAuthenticationPW("/new/test2/", "failingCharset@test.realm", UNICODE_PW, ISO_8859_1);
+        setAuthenticationPW("/new/test3/", "defaultCharset@test.realm", UNICODE_PW, null);
+
+        ExecutorService executor = Executors.newCachedThreadPool();
+        testHttpServer.setExecutor(executor);
+        testHttpServer.start();
+        java.net.Authenticator.setDefault(clientAuth);
+
+        connectAndAuth("/test1/passingCharset.html", 200);
+        connectAndAuth("/test2/failingCharset.html", 401);
+        if (isUTF8) {
+            connectAndAuth("/test3/defaultCharset.html", 200);
+        }
+
+        testHttpServer.stop(2);
+        executor.shutdown();
+
+        // should fail once with UNICODE_PW and unsupporting character set
+        if (failCount > 0)
+            throw new RuntimeException("Fail count : " + failCount);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/net/httpserver/bugs/8199849/ParamTest.java	Wed Aug 28 11:58:56 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.
+ */
+
+import java.io.*;
+import java.net.*;
+import java.net.http.HttpClient;
+import java.net.http.HttpRequest;
+import java.net.http.HttpResponse;
+import java.util.*;
+import java.nio.charset.StandardCharsets;
+import jdk.test.lib.net.URIBuilder;
+
+/**
+ * @test
+ * @bug 8199849
+ * @summary
+ * @library /test/lib
+ * @run main/othervm ParamTest
+ * @run main/othervm -Djava.net.preferIPv6Addresses=true ParamTest
+ */
+
+public class ParamTest {
+
+    static final String[] variants = {
+        " charset=utf-8",
+        " charset=UtF-8",
+        " charset=\"utF-8\"",
+        " charset=\"UtF-8\""
+    };
+
+    static final int LOOPS = variants.length;
+
+    volatile static boolean error = false;
+
+    static class BasicServer extends Thread {
+
+        final ServerSocket server;
+
+        Socket s;
+        InputStream is;
+        OutputStream os;
+
+        static final String realm = "wallyworld";
+
+        String reply1 = "HTTP/1.1 401 Unauthorized\r\n"+
+            "WWW-Authenticate: Basic realm=\""+realm+"\"\r\n";
+
+        String reply2 = "HTTP/1.1 200 OK\r\n"+
+            "Date: Mon, 15 Jan 2001 12:18:21 GMT\r\n" +
+            "Server: Apache/1.3.14 (Unix)\r\n" +
+            "Connection: close\r\n" +
+            "Content-Type: text/html; charset=iso-8859-1\r\n" +
+            "Content-Length: 10\r\n\r\n";
+
+        BasicServer(ServerSocket s) {
+            server = s;
+        }
+
+        String readHeaders(Socket sock) throws IOException {
+            InputStream is = sock.getInputStream();
+            String s = "";
+            byte[] buf = new byte[1024];
+            while (!s.endsWith("\r\n\r\n")) {
+                int c = is.read(buf);
+                if (c == -1)
+                    return s;
+                String f = new String(buf, 0, c, StandardCharsets.ISO_8859_1);
+                s = s + f;
+            }
+            return s;
+        }
+
+        void check(String s, int iteration) {
+            if (s.indexOf(encodedAuthString) == -1) {
+                System.err.printf("On iteration %d, wrong auth string received %s\n", iteration, s);
+                error = true;
+            } else {
+                System.err.println("check: correct auth string received");
+            }
+        }
+
+        public void run() {
+            try {
+                for (int j = 0; j < 2; j++)
+                    for (int i = 0; i < LOOPS; i++) {
+                        System.out.println("Server 1: accept");
+                        s = server.accept();
+                        readHeaders(s);
+                        System.out.println("accepted");
+                        os = s.getOutputStream();
+                        String str = reply1 + variants[i] + "\r\n\r\n";
+                        os.write(str.getBytes());
+
+                        System.out.println("Server 2: accept");
+                        Socket s1 = server.accept();
+                        String request = readHeaders(s1);
+                        check(request, i);
+                        System.out.println("accepted");
+                        os = s1.getOutputStream();
+                        os.write((reply2 + "HelloWorld").getBytes());
+                        os.flush();
+                        s.close();
+                        s1.close();
+                        finished();
+                    }
+            } catch (Exception e) {
+                System.out.println(e);
+                error = true;
+            }
+        }
+
+        public synchronized void finished() {
+            notifyAll();
+        }
+
+    }
+
+    static final String password = "Selam D\u00fcnya.";
+
+    // "user : <password above>" encoded in UTF-8 and converted to Base 64
+
+    static final String encodedAuthString = "dXNlcjpTZWxhbSBEw7xueWEu";
+
+    static class MyAuthenticator extends Authenticator {
+        MyAuthenticator() {
+            super();
+        }
+
+        public PasswordAuthentication getPasswordAuthentication()
+            {
+            System.out.println("Auth called");
+            return (new PasswordAuthentication ("user", password.toCharArray()));
+        }
+    }
+
+
+    static void read(InputStream is) throws IOException {
+        int c;
+        System.out.println("reading");
+        while ((c=is.read()) != -1) {
+            System.out.write(c);
+        }
+        System.out.println("");
+        System.out.println("finished reading");
+    }
+
+    public static void main(String args[]) throws Exception {
+        MyAuthenticator auth = new MyAuthenticator();
+        Authenticator.setDefault(auth);
+        InetAddress loopback = InetAddress.getLoopbackAddress();
+        ServerSocket ss = new ServerSocket();
+        ss.bind(new InetSocketAddress(loopback, 0));
+        int port = ss.getLocalPort();
+        BasicServer server = new BasicServer(ss);
+        synchronized (server) {
+            server.start();
+            System.out.println("client 1");
+            String base = URIBuilder.newBuilder()
+                .scheme("http")
+                .loopback()
+                .port(port)
+                .path("/")
+                .build()
+                .toString();
+            URL url = new URL(base + "d1/d2/d3/foo.html");
+
+            for (int i = 0; i < LOOPS; i++) {
+                URLConnection urlc = url.openConnection(Proxy.NO_PROXY);
+                InputStream is = urlc.getInputStream();
+                read(is);
+                System.out.println("Client: waiting for notify");
+                server.wait();
+                System.out.println("Client: continue");
+                // check if authenticator was called once (ok) or twice (not)
+                if (error) {
+                    System.err.println("Error old client iteration " + i);
+                }
+            }
+
+            URI uri = url.toURI();
+            HttpClient client = HttpClient.newBuilder()
+                .authenticator(auth)
+                .build();
+
+            HttpRequest request = HttpRequest
+                .newBuilder(uri)
+                .GET()
+                .build();
+
+            for (int i = 0; i < LOOPS; i++) {
+                HttpResponse<Void> response = client.send(request, HttpResponse.BodyHandlers.discarding());
+                int status = response.statusCode();
+                if (status != 200) {
+                    System.err.printf("Error new client (%d) iteration ",
+                                status, i);
+                    error = true;
+                } else
+                    System.err.println("New client ok iteration " + i);
+                System.out.println("New Client: waiting for notify");
+                server.wait();
+                System.out.println("New Client: continue");
+            }
+
+            if (error) {
+                throw new RuntimeException("Test failed");
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/com/sun/net/httpserver/bugs/8199849/TestHttpUnicode.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,100 @@
+/*
+ * 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 8199849
+ * @library /test/lib
+ * @summary Checks that unicode bytes are being handled correctly
+ * @run main/othervm -Dfile.encoding=UTF_8 TestHttpUnicode
+ */
+
+import com.sun.net.httpserver.*;
+import jdk.test.lib.net.URIBuilder;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.*;
+
+public class TestHttpUnicode {
+
+    private static final String TEST_USER = "Selam D\u00fcnya. Ho\u015f\u00e7akal D\u00fcnya";
+    private static final String TEST_PW = "Selam D\u00fcnya. Ho\u015f\u00e7akal D\u00fcnya";
+
+    static class ClientAuthenticator extends java.net.Authenticator {
+        public PasswordAuthentication getPasswordAuthentication() {
+            return new PasswordAuthentication(TEST_USER, TEST_PW.toCharArray());
+        }
+    }
+
+    static class Handler implements HttpHandler {
+        public void handle(HttpExchange t) throws IOException {
+            InputStream is = t.getRequestBody();
+            while (is.read() != -1) ;
+            is.close();
+
+            HttpPrincipal p = t.getPrincipal();
+            if (p.getUsername().equals(TEST_USER)) {
+                t.sendResponseHeaders(200, -1);
+            }
+            t.close();
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        HttpServer testHttpServer = null;
+        try {
+            InetSocketAddress loopbackAddress = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
+            testHttpServer = HttpServer.create(loopbackAddress, 0);
+            HttpContext context = testHttpServer.createContext("/test", new Handler());
+            System.setProperty("http.maxRedirects", "3");
+
+            BasicAuthenticator serverAuthenticator = new BasicAuthenticator("authCharacterSet@test.realm") {
+                public boolean checkCredentials(String username, String pw) {
+                    return username.equals(TEST_USER) && pw.equals(TEST_PW);
+                }
+            };
+            context.setAuthenticator(serverAuthenticator);
+            java.net.Authenticator.setDefault(new ClientAuthenticator());
+
+            testHttpServer.start();
+            URL url = URIBuilder.newBuilder()
+                .scheme("http")
+                .loopback()
+                .port(testHttpServer.getAddress().getPort())
+                .path("/test/authCharacterSet.html")
+                .toURL();
+            HttpURLConnection testConnection = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
+
+            // Authenication CHECK
+            if (testConnection.getResponseCode() == 401) {
+                throw new RuntimeException("Test Authentication failed with HTTP Status 401.");
+            }
+
+            InputStream is = testConnection.getInputStream();
+            while (is.read() != -1) ;
+        } finally {
+            testHttpServer.stop(2);
+        }
+    }
+}
--- a/test/jdk/java/lang/Math/ExactArithTests.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/lang/Math/ExactArithTests.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2016, 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
@@ -56,8 +56,8 @@
     }
 
     /**
-     * Test Math.addExact, multiplyExact, subtractExact, toIntValue methods
-     * with {@code int} arguments.
+     * Test Math.addExact, multiplyExact, subtractExact, incrementExact,
+     * decrementExact, negateExact methods with {@code int} arguments.
      */
     static void testIntegerExact() {
         testIntegerExact(0, 0);
@@ -76,7 +76,6 @@
         testIntegerExact(Integer.MAX_VALUE, -1);
         testIntegerExact(Integer.MIN_VALUE, -2);
         testIntegerExact(Integer.MAX_VALUE, -2);
-
     }
 
     /**
@@ -101,7 +100,6 @@
             long sum2 = (long) x + (long) y;
             if ((int) sum2 == sum2) {
                 fail("FAIL: int Math.addExact(" + x + " + " + y + ")" + "; Unexpected exception: " + ex);
-
             }
         }
 
@@ -147,7 +145,6 @@
             long inc2 = (long) x + 1L;
             if ((int) inc2 == inc2) {
                 fail("FAIL: int Math.incrementExact(" + x + ")" + "; Unexpected exception: " + ex);
-
             }
         }
 
@@ -164,31 +161,29 @@
             long dec2 = (long) x - 1L;
             if ((int) dec2 == dec2) {
                 fail("FAIL: int Math.decrementExact(" + x + ")" + "; Unexpected exception: " + ex);
-
             }
         }
 
         try {
             // Test negateExact
             int neg = Math.negateExact(x);
-            long neg2 = -((long)x) ;
+            long neg2 = -((long)x);
             if ((int) neg2 != neg2) {
                 fail("FAIL: int Math.negateExact(" + x + ") = " + neg + "; expected Arithmetic exception");
             } else if (neg != neg2) {
                 fail("FAIL: long Math.negateExact(" + x + ") = " + neg + "; expected: " + neg2);
             }
         } catch (ArithmeticException ex) {
-            long neg2 = (long) x - 1L;
+            long neg2 = -((long)x);
             if ((int) neg2 == neg2) {
                 fail("FAIL: int Math.negateExact(" + x + ")" + "; Unexpected exception: " + ex);
-
             }
         }
     }
 
     /**
-     * Test Math.addExact, multiplyExact, subtractExact, toIntExact methods
-     * with {@code long} arguments.
+     * Test Math.addExact, multiplyExact, subtractExact, incrementExact,
+     * decrementExact, negateExact, toIntExact methods with {@code long} arguments.
      */
     static void testLongExact() {
         testLongExactTwice(0, 0);
@@ -215,7 +210,6 @@
         testLongExactTwice(Integer.MIN_VALUE-1, Integer.MIN_VALUE-1);
         testLongExactTwice(Integer.MIN_VALUE-1, -Integer.MIN_VALUE-1);
         testLongExactTwice(Integer.MIN_VALUE/2, 2);
-
     }
 
     /**
@@ -319,7 +313,6 @@
                 fail("FAIL: long Math.toIntExact(" + x + ")" + "; Unexpected exception: " + ex);
             }
         }
-
     }
 
     /**
--- a/test/jdk/java/lang/StrictMath/ExactArithTests.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/lang/StrictMath/ExactArithTests.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 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
@@ -55,8 +55,8 @@
     }
 
     /**
-     * Test StrictMath.addExact, multiplyExact, subtractExact, toIntValue methods
-     * with {@code int} arguments.
+     * Test StrictMath.addExact, multiplyExact, subtractExact, incrementExact,
+     * decrementExact, negateExact methods with {@code int} arguments.
      */
     static void testIntegerExact() {
         testIntegerExact(0, 0);
@@ -75,7 +75,6 @@
         testIntegerExact(Integer.MAX_VALUE, -1);
         testIntegerExact(Integer.MIN_VALUE, -2);
         testIntegerExact(Integer.MAX_VALUE, -2);
-
     }
 
     /**
@@ -100,7 +99,6 @@
             long sum2 = (long) x + (long) y;
             if ((int) sum2 == sum2) {
                 fail("FAIL: int StrictMath.addExact(" + x + " + " + y + ")" + "; Unexpected exception: " + ex);
-
             }
         }
 
@@ -133,11 +131,58 @@
             }
         }
 
+        try {
+            // Test incrementExact
+            int inc = StrictMath.incrementExact(x);
+            long inc2 = (long) x + 1L;
+            if ((int) inc2 != inc2) {
+                fail("FAIL: int StrictMath.incrementExact(" + x + ") = " + inc + "; expected Arithmetic exception");
+            } else if (inc != inc2) {
+                fail("FAIL: long StrictMath.incrementExact(" + x + ") = " + inc + "; expected: " + inc2);
+            }
+        } catch (ArithmeticException ex) {
+            long inc2 = (long) x + 1L;
+            if ((int) inc2 == inc2) {
+                fail("FAIL: int StrictMath.incrementExact(" + x + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test decrementExact
+            int dec = StrictMath.decrementExact(x);
+            long dec2 = (long) x - 1L;
+            if ((int) dec2 != dec2) {
+                fail("FAIL: int StrictMath.decrementExact(" + x + ") = " + dec + "; expected Arithmetic exception");
+            } else if (dec != dec2) {
+                fail("FAIL: long StrictMath.decrementExact(" + x + ") = " + dec + "; expected: " + dec2);
+            }
+        } catch (ArithmeticException ex) {
+            long dec2 = (long) x - 1L;
+            if ((int) dec2 == dec2) {
+                fail("FAIL: int StrictMath.decrementExact(" + x + ")" + "; Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test negateExact
+            int neg = StrictMath.negateExact(x);
+            long neg2 = -((long)x);
+            if ((int) neg2 != neg2) {
+                fail("FAIL: int StrictMath.negateExact(" + x + ") = " + neg + "; expected Arithmetic exception");
+            } else if (neg != neg2) {
+                fail("FAIL: long StrictMath.negateExact(" + x + ") = " + neg + "; expected: " + neg2);
+            }
+        } catch (ArithmeticException ex) {
+            long neg2 = -((long)x);
+            if ((int) neg2 == neg2) {
+                fail("FAIL: int StrictMath.negateExact(" + x + ")" + "; Unexpected exception: " + ex);
+            }
+        }
     }
 
     /**
-     * Test StrictMath.addExact, multiplyExact, subtractExact, toIntExact methods
-     * with {@code long} arguments.
+     * Test StrictMath.addExact, multiplyExact, subtractExact, incrementExact,
+     * decrementExact, negateExact, toIntExact methods with {@code long} arguments.
      */
     static void testLongExact() {
         testLongExactTwice(0, 0);
@@ -164,7 +209,6 @@
         testLongExactTwice(Integer.MIN_VALUE-1, Integer.MIN_VALUE-1);
         testLongExactTwice(Integer.MIN_VALUE-1, -Integer.MIN_VALUE-1);
         testLongExactTwice(Integer.MIN_VALUE/2, 2);
-
     }
 
     /**
@@ -225,6 +269,39 @@
         }
 
         try {
+            // Test incrementExact
+            resultBig = xBig.add(BigInteger.ONE);
+            long inc = StrictMath.incrementExact(x);
+            checkResult("long Math.incrementExact", x, 1L, inc, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long Math.incrementExact(" + x + "); Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test decrementExact
+            resultBig = xBig.subtract(BigInteger.ONE);
+            long dec = StrictMath.decrementExact(x);
+            checkResult("long Math.decrementExact", x, 1L, dec, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long Math.decrementExact(" + x + "); Unexpected exception: " + ex);
+            }
+        }
+
+        try {
+            // Test negateExact
+            resultBig = xBig.negate();
+            long dec = StrictMath.negateExact(x);
+            checkResult("long Math.negateExact", x, 0L, dec, resultBig);
+        } catch (ArithmeticException ex) {
+            if (inLongRange(resultBig)) {
+                fail("FAIL: long Math.negateExact(" + x + "); Unexpected exception: " + ex);
+            }
+        }
+
+        try {
             // Test toIntExact
             int value = StrictMath.toIntExact(x);
             if ((long)value != x) {
@@ -235,7 +312,6 @@
                 fail("FAIL: long StrictMath.toIntExact(" + x + ")" + "; Unexpected exception: " + ex);
             }
         }
-
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/reflect/Proxy/ProxyGeneratorCombo.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,568 @@
+/*
+ * 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
+ * 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 Proxy Generator Combo tests
+ * @library /test/langtools/tools/javac/lib .
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ *          jdk.compiler/com.sun.tools.javac.code
+ *          jdk.compiler/com.sun.tools.javac.comp
+ *          jdk.compiler/com.sun.tools.javac.main
+ *          jdk.compiler/com.sun.tools.javac.tree
+ *          jdk.compiler/com.sun.tools.javac.util
+ * @build combo.ComboTestHelper
+ * @run main/othervm ProxyGeneratorCombo
+ * @run main/othervm -Djdk.proxy.ProxyGenerator.v49=true ProxyGeneratorCombo
+ */
+
+import java.io.IOException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringJoiner;
+
+import combo.ComboInstance;
+import combo.ComboParameter;
+import combo.ComboTask.Result;
+import combo.ComboTestHelper;
+
+public class ProxyGeneratorCombo extends ComboInstance<ProxyGeneratorCombo> {
+
+    // The unique number to qualify interface names, unique across multiple runs
+    private static int uniqueId = 0;
+
+    /**
+     * Class Access kinds.
+     */
+    enum ClassAccessKind implements ComboParameter {
+        PUBLIC("public"),
+        PACKAGE(""),
+        ;
+
+        String classAccessTemplate;
+
+        ClassAccessKind(String classAccessTemplate) {
+            this.classAccessTemplate = classAccessTemplate;
+        }
+
+        @Override
+        public String expand(String optParameter) {
+            return classAccessTemplate;
+        }
+    }
+
+    /**
+     * Signatures of methods to be tested.
+     */
+    enum MethodsKind implements ComboParameter {
+        NONE(""),
+        ZERO("#{METHODACCESS} void zero() #{EXCEPTION};"),
+        ONE("#{METHODACCESS} void one(#{ARG[0]} a) #{EXCEPTION};"),
+        TWO("#{METHODACCESS} void one(#{ARG[0]} b);\n" +
+                "#{METHODACCESS} void two(#{ARG[0]} a, #{ARG[1]} b);"),
+        THREE("#{METHODACCESS} void one(#{ARG[0]} a);\n" +
+                "#{METHODACCESS} void two(#{ARG[0]} a, #{ARG[1]} b);\n" +
+                "#{METHODACCESS} void three(#{ARG[0]} a, #{ARG[1]} b, #{ARG[0]} c);");
+
+        String methodsKindTemplate;
+
+        MethodsKind(String methodsKindTemplate) {
+            this.methodsKindTemplate = methodsKindTemplate;
+        }
+
+        @Override
+        public String expand(String optParameter) {
+            return methodsKindTemplate;
+        }
+    }
+
+    /**
+     * Type of arguments to insert in method signatures
+     */
+    enum ArgumentKind implements ComboParameter {
+        BOOLEAN("boolean"),
+        BYTE("byte"),
+        CHAR("char"),
+        SHORT("short"),
+        INT("int"),
+        LONG("long"),
+        FLOAT("float"),
+        DOUBLE("double"),
+        STRING("String");
+
+        String argumentsKindTemplate;
+
+        ArgumentKind(String argumentsKindTemplate) {
+            this.argumentsKindTemplate = argumentsKindTemplate;
+        }
+
+        @Override
+        public String expand(String optParameter) {
+            return argumentsKindTemplate;
+        }
+    }
+
+    /**
+     * Exceptions to be added to zero and one methods.
+     */
+    enum ExceptionKind implements ComboParameter {
+        NONE(null),
+        EXCEPTION(java.lang.Exception.class),
+        RUNTIME_EXCEPTION(java.lang.RuntimeException.class),
+        ILLEGAL_ARGUMENT_EXCEPTION(java.lang.IllegalArgumentException.class),
+        IOEXCEPTION(java.io.IOException.class),
+        /**
+         * Used only for throw testing, is empty for throws clause in the source,
+         */
+        UNDECLARED_EXCEPTION(Exception1.class),
+        ;
+
+        Class<? extends Throwable> exceptionKindClass;
+
+        ExceptionKind(Class<? extends Throwable> exceptionKindClass) {
+            this.exceptionKindClass = exceptionKindClass;
+        }
+
+        @Override
+        public String expand(String optParameter) {
+            return exceptionKindClass == null || exceptionKindClass == Exception1.class
+                    ? "" : "throws " + exceptionKindClass.getName();
+        }
+    }
+
+    /**
+     * Extra interfaces to be added.
+     */
+    enum MultiInterfacesKind implements ComboParameter {
+        NONE(new Class<?>[0]),
+        INTERFACE_WITH_EXCEPTION(new Class<?>[] {InterfaceWithException.class}),
+        ;
+
+        Class<?>[] multiInterfaceClasses;
+
+        MultiInterfacesKind(Class<?>[] multiInterfaceClasses) {
+            this.multiInterfaceClasses = multiInterfaceClasses;
+        }
+
+        @Override
+        // Not used for expansion only execution
+        public String expand(String optParameter) {
+            throw new RuntimeException("NYI");
+        }
+
+        Class<?>[] classes() {
+            return multiInterfaceClasses;
+        }
+    }
+
+    @Override
+    public int id() {
+        return ++uniqueId;
+    }
+
+    protected void fail(String msg, Throwable thrown) {
+        super.fail(msg);
+        thrown.printStackTrace();
+    }
+
+    /**
+     * Test interface with a "one(int)" method.
+     */
+    interface InterfaceWithException {
+        // The signature must match the ONE MethodsKind above
+        void one(int a) throws RuntimeException, IOException;
+    }
+
+
+    /**
+     * Main to generate combinations and run the tests.
+     * @param args unused
+     * @throws Exception In case of failure
+     */
+    public static void main(String... args) throws Exception {
+
+        // Test variations of access declarations
+        new ComboTestHelper<ProxyGeneratorCombo>()
+                .withDimension("CLASSACCESS", ClassAccessKind.values())
+                .withDimension("METHODACCESS", new ClassAccessKind[]{ClassAccessKind.PUBLIC})
+                .withDimension("METHODS", ProxyGeneratorCombo::saveMethod,
+                        new MethodsKind[] {MethodsKind.NONE, MethodsKind.ZERO, MethodsKind.ONE})
+                .withDimension("ARG[0]", new ArgumentKind[] {ArgumentKind.INT})
+                .withDimension("EXCEPTION", ProxyGeneratorCombo::saveException,
+                        new ExceptionKind[]{ExceptionKind.NONE})
+                .run(ProxyGeneratorCombo::new);
+
+        // Test variations of argument types
+        new ComboTestHelper<ProxyGeneratorCombo>()
+                .withDimension("CLASSACCESS", new ClassAccessKind[]{ClassAccessKind.PUBLIC})
+                .withDimension("METHODACCESS", new ClassAccessKind[]{ClassAccessKind.PUBLIC})
+                .withDimension("METHODS", ProxyGeneratorCombo::saveMethod,
+                        MethodsKind.values())
+                .withArrayDimension("ARG", ProxyGeneratorCombo::saveArg, 2,
+                        ArgumentKind.values())
+                .withDimension("EXCEPTION", ProxyGeneratorCombo::saveException,
+                        new ExceptionKind[]{ExceptionKind.NONE})
+                .withFilter(ProxyGeneratorCombo::filter)
+                .run(ProxyGeneratorCombo::new);
+
+        // Test for conflicts in Exceptions on methods with the same signatures
+        new ComboTestHelper<ProxyGeneratorCombo>()
+                .withDimension("CLASSACCESS", new ClassAccessKind[]{ClassAccessKind.PUBLIC})
+                .withDimension("METHODACCESS", new ClassAccessKind[]{ClassAccessKind.PUBLIC})
+                .withDimension("METHODS", ProxyGeneratorCombo::saveMethod, new MethodsKind[] {
+                        MethodsKind.ZERO})
+                .withDimension("EXCEPTION", ProxyGeneratorCombo::saveException,
+                        ExceptionKind.values())
+                .withDimension("MULTI_INTERFACES", ProxyGeneratorCombo::saveInterface,
+                        new MultiInterfacesKind[] {MultiInterfacesKind.NONE})
+                .run(ProxyGeneratorCombo::new);
+    }
+
+    /**
+     * Basic template.
+     */
+    String template = "#{CLASSACCESS} interface #{TESTNAME} {\n" +
+            "#{METHODS}" +
+            "}";
+
+    // Saved values of Combo values
+    private MultiInterfacesKind currInterface = MultiInterfacesKind.NONE;
+    private MethodsKind currMethod = MethodsKind.NONE;
+    private ExceptionKind currException = ExceptionKind.NONE;
+    private ArgumentKind[] currArgs = new ArgumentKind[0];
+
+    void saveInterface(ComboParameter s) {
+        currInterface = (MultiInterfacesKind)s;
+    }
+
+    void saveMethod(ComboParameter s) {
+        currMethod = (MethodsKind)s;
+    }
+
+    void saveException(ComboParameter s) {
+        currException = (ExceptionKind)s;
+    }
+
+    void saveArg(ComboParameter s, int index) {
+        if (index >= currArgs.length) {
+            currArgs = Arrays.copyOf(currArgs, index + 1);
+        }
+        currArgs[index] = (ArgumentKind)s;
+    }
+
+    /**
+     * Filter out needless tests (mostly with more variations of arguments than needed).
+     * @return true to run the test, false if not
+     */
+    boolean filter() {
+        if ((currMethod == MethodsKind.NONE || currMethod == MethodsKind.ZERO) &&
+                currArgs.length >= 2) {
+            return currArgs[0] == ArgumentKind.INT &&
+                currArgs[1] == ArgumentKind.INT;
+        }
+        if (currMethod == MethodsKind.ONE &&
+                currArgs.length >= 2 ) {
+            return currArgs[0] == currArgs[1];
+        }
+        return true;
+    }
+
+    /**
+     * Generate the source file and compile.
+     * Generate a proxy for the interface and test the resulting Proxy
+     * for the methods, exceptions and handling of a thrown exception
+     * @throws IOException catch all IOException
+     */
+    @Override
+    public void doWork() throws IOException {
+        String cp = System.getProperty("test.classes");
+        String ifaceName = "Interface_" + this.id();
+        newCompilationTask()
+                .withSourceFromTemplate(ifaceName, template.replace("#{TESTNAME}", ifaceName))
+                .withOption("-d")
+                .withOption(cp)
+                .generate(this::checkCompile);
+        try {
+            ClassLoader loader = ClassLoader.getSystemClassLoader();
+            Class<?> tc = Class.forName(ifaceName);
+            InvocationHandler handler =
+                    new ProxyHandler(currException.exceptionKindClass);
+
+            // Construct array of interfaces for the proxy
+            Class<?>[] interfaces = new Class<?>[currInterface.classes().length + 1];
+            interfaces[0] = tc;
+            System.arraycopy(currInterface.classes(), 0,
+                    interfaces, 1,
+                    currInterface.classes().length);
+
+            Object proxy = Proxy.newProxyInstance(loader, interfaces, handler);
+            if (!Proxy.isProxyClass(proxy.getClass())) {
+                fail("generated proxy is not a proxy class");
+                return;
+            }
+            for (Class<?> i : interfaces) {
+                if (!i.isAssignableFrom(proxy.getClass())) {
+                    fail("proxy is not assignable to " + i.getName());
+                }
+            }
+            try {
+                String s = proxy.toString();
+            } catch (Exception ex) {
+                ex.printStackTrace();
+                fail("proxy.toString() threw an exception");
+            }
+
+            checkDeclaredProxyExceptions(proxy, interfaces);
+
+            if (currMethod == MethodsKind.ZERO && currException != ExceptionKind.NONE) {
+                checkThrowsException(proxy, interfaces);
+            }
+
+        } catch (Exception ex) {
+            throw new RuntimeException("doWork unexpected", ex);
+        }
+    }
+
+    /**
+     * Check that the exceptions declared on the proxy match the declarations for
+     * exceptions from the interfaces.
+     *
+     * @param proxy a proxy object
+     * @param interfaces the interfaces that defined it
+     */
+    void checkDeclaredProxyExceptions(Object proxy, Class<?>[] interfaces) {
+        var allMethods = allMethods(Arrays.asList(interfaces));
+        Method[] methods = proxy.getClass().getDeclaredMethods();
+        for (Method m : methods) {
+            String sig = toShortSignature(m);
+            var imethods = allMethods.get(sig);
+            if (imethods != null) {
+                var expectedEx = Set.copyOf(Arrays.asList(m.getExceptionTypes()));
+                var exs = Set.copyOf(extractExceptions(imethods));
+                if (!expectedEx.equals(exs)) {
+                    System.out.printf("mismatch on exceptions for method %s:%nExpected: " +
+                                    "%s%nActual:  %s%n",
+                            sig, expectedEx, exs);
+                    fail("Exceptions declared on proxy don't match interface methods");
+                }
+            }
+        }
+    }
+
+    void checkThrowsException(Object proxy, Class<?>[] interfaces) {
+        ProxyHandler ph = (ProxyHandler)(Proxy.getInvocationHandler(proxy));
+        try {
+            Method m = proxy.getClass().getDeclaredMethod("zero");
+            m.invoke(proxy);
+            fail("Missing exception: " + ph.exceptionClass);
+        } catch (NoSuchMethodException nsme) {
+            System.out.printf("No method 'zero()' to test exceptions with%n");
+            for (var cl : interfaces) {
+                System.out.printf("     i/f %s: %s%n", cl, Arrays.toString(cl.getMethods()));
+            }
+            Method[] methods = proxy.getClass().getMethods();
+            System.out.printf("    Proxy methods: %s%n", Arrays.toString(methods));
+            fail("No such method test bug", nsme);
+        } catch (InvocationTargetException actual) {
+            ph.checkThrownException(actual.getTargetException());
+        } catch (IllegalAccessException iae) {
+            fail("IllegalAccessException", iae);
+        }
+    }
+
+    /**
+     * Exceptions known to be supported by all methods with the same signature.
+     * @return a list of universal exception types
+     */
+    private static List<Class<?>> extractExceptions(List<Method> methods) {
+        // for all methods with the same signature
+        // start with the exceptions from the first method
+        // while there are any exceptions remaining
+        // look at the next method
+        List<Class<?>> exceptions = null;
+        for (Method m : methods) {
+            var e = m.getExceptionTypes();
+            if (e.length == 0)
+                return emptyClassList();
+            List<Class<?>> elist = Arrays.asList(e);
+            if (exceptions == null) {
+                exceptions = elist;    // initialize to first method exceptions
+            } else {
+                // for each exception
+                // if it is compatible (both ways) with any of the existing exceptions continue
+                //    else remove the current exception
+                var okExceptions = new HashSet<Class<?>>();
+                for (int j = 0; j < exceptions.size(); j++) {
+                    var ex = exceptions.get(j);
+                    for (int i = 0; i < elist.size();i++) {
+                        var ci = elist.get(i);
+
+                        if (ci.isAssignableFrom(ex)) {
+                            okExceptions.add(ex);
+                        }
+                        if (ex.isAssignableFrom(ci)) {
+                            okExceptions.add(ci);
+                        }
+                    }
+                }
+                if (exceptions.isEmpty()) {
+                    // The empty set terminates the search for a common set of exceptions
+                    return emptyClassList();
+                }
+                // Use the new set for the next iteration
+                exceptions = List.copyOf(okExceptions);
+            }
+        }
+        return (exceptions == null) ? emptyClassList() : exceptions;
+    }
+
+    /**
+     * An empty correctly typed list of classes.
+     * @return An empty typed list of classes
+     */
+    @SuppressWarnings("unchecked")
+    static List<Class<?>> emptyClassList() {
+        return Collections.EMPTY_LIST;
+    }
+
+    /**
+     * Accumulate all of the unique methods.
+     *
+     * @param interfaces a list of interfaces
+     * @return a map from signature to List of methods, unique by signature
+     */
+    private static Map<String, List<Method>> allMethods(List<Class<?>> interfaces) {
+        Map<String, List<Method>> methods = new HashMap<>();
+        for (Class<?> c : interfaces) {
+            for (Method m : c.getMethods()) {
+                if (!Modifier.isStatic(m.getModifiers())) {
+                    String sig = toShortSignature(m);
+                    methods.computeIfAbsent(sig, s -> new ArrayList<Method>())
+                            .add(m);
+                }
+            }
+        }
+        return methods;
+    }
+
+    /**
+     * The signature of a method without the return type.
+     * @param m a Method
+     * @return the signature with method name and parameters
+     */
+    static String toShortSignature(Method m) {
+        StringJoiner sj = new StringJoiner(",", m.getName() + "(", ")");
+        for (Class<?> parameterType : m.getParameterTypes()) {
+            sj.add(parameterType.getTypeName());
+        }
+        return sj.toString();
+    }
+
+    /**
+     * Report any compilation errors.
+     * @param res the result
+     */
+    void checkCompile(Result<?> res) {
+        if (res.hasErrors()) {
+            fail("invalid diagnostics for source:\n" +
+                    res.compilationInfo() +
+                    "\nFound error: " + res.hasErrors());
+        }
+    }
+
+    /**
+     * The Handler for the proxy includes the method to invoke the proxy
+     * and the expected exception, if any.
+     */
+    class ProxyHandler implements InvocationHandler {
+
+        private final Class<? extends Throwable> exceptionClass;
+
+        ProxyHandler(Class<? extends Throwable> throwable) {
+            this.exceptionClass = throwable;
+        }
+
+        /**
+         * Invoke a method on the proxy or return a value.
+         * @param   proxy the proxy instance that the method was invoked on
+         * @param   method a method
+         * @param   args some args
+         * @return
+         * @throws Throwable a throwable
+         */
+        @Override
+        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+            if (method.getName().equals("toString")) {
+                return "Proxy" + System.identityHashCode(proxy);
+            }
+            if (method.getName().equals("zero")) {
+                if (exceptionClass != null) {
+                    throw exceptionClass.getDeclaredConstructor().newInstance();
+                }
+            }
+            return "meth: " + method.toString();
+        }
+
+        /**
+         * Check that the expected exception was thrown.
+         * Special case is handled for Exception1 which does not appear in the
+         * throws clause of the method so UndeclaredThrowableException is expected.
+         */
+        void checkThrownException(Throwable thrown) {
+            if (exceptionClass == Exception1.class &&
+                    thrown instanceof UndeclaredThrowableException &&
+                    ((UndeclaredThrowableException)thrown).getUndeclaredThrowable() instanceof Exception1) {
+                // Exception1 caused UndeclaredThrowableException
+                return;
+            } else if (exceptionClass == Exception1.class) {
+                fail("UndeclaredThrowableException", thrown);
+            }
+
+            if (exceptionClass != null &&
+                    !exceptionClass.equals(thrown.getClass())) {
+                throw new RuntimeException("Wrong exception thrown: expected: " + exceptionClass +
+                        ", actual: " + thrown.getClass());
+            }
+        }
+    }
+
+    /**
+     * Exception to be thrown as a test of InvocationTarget.
+     */
+    static class Exception1 extends Exception {
+        private static final long serialVersionUID = 1L;
+        Exception1() {}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/net/HttpURLConnection/HttpURLProxySelectionTest.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,162 @@
+/*
+ * 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 com.sun.net.httpserver.HttpExchange;
+import com.sun.net.httpserver.HttpHandler;
+import com.sun.net.httpserver.HttpServer;
+import jdk.test.lib.net.URIBuilder;
+import org.testng.Assert;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import sun.net.spi.DefaultProxySelector;
+
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.List;
+
+/**
+ * @test
+ * @bug 6563286 6797318 8177648 8230220
+ * @summary Tests that sun.net.www.protocol.http.HttpURLConnection when dealing with
+ * sun.net.spi.DefaultProxySelector#select() handles any IllegalArgumentException
+ * correctly
+ * @library /test/lib
+ * @run testng HttpURLProxySelectionTest
+ * @modules java.base/sun.net.spi:+open
+ */
+public class HttpURLProxySelectionTest {
+
+    private static final String WEB_APP_CONTEXT = "/httpurlproxytest";
+
+    private HttpServer server;
+    private SimpleHandler handler;
+    private ProxySelector previousDefault;
+    private CustomProxySelector ourProxySelector = new CustomProxySelector();
+
+    @BeforeTest
+    public void beforeTest() throws Exception {
+        previousDefault = ProxySelector.getDefault();
+        ProxySelector.setDefault(ourProxySelector);
+        handler = new SimpleHandler();
+        server = createServer(handler);
+    }
+
+    @AfterTest
+    public void afterTest() {
+        try {
+            if (server != null) {
+                final int delaySeconds = 0;
+                server.stop(delaySeconds);
+            }
+        } finally {
+            ProxySelector.setDefault(previousDefault);
+        }
+    }
+
+    /**
+     * - Test initiates a HTTP request to server
+     * - Server receives request and sends a 301 redirect to an URI which doesn't have a "host"
+     * - Redirect is expected to fail with IOException (caused by IllegalArgumentException from DefaultProxySelector)
+     *
+     * @throws Exception
+     */
+    @Test
+    public void test() throws Exception {
+        final URL targetURL = URIBuilder.newBuilder()
+                .scheme("http")
+                .host(server.getAddress().getAddress())
+                .port(server.getAddress().getPort())
+                .path(WEB_APP_CONTEXT)
+                .toURL();
+        System.out.println("Sending request to " + targetURL);
+        final HttpURLConnection conn = (HttpURLConnection) targetURL.openConnection();
+        try {
+            conn.getResponseCode();
+            Assert.fail("Request to " + targetURL + " was expected to fail during redirect");
+        } catch (IOException ioe) {
+            // expected because of the redirect to an invalid URL, for which a proxy can't be selected
+
+            // make sure the it was indeed a redirect
+            Assert.assertTrue(handler.redirectSent, "Server was expected to send a redirect, but didn't");
+            Assert.assertTrue(ourProxySelector.selectorUsedForRedirect, "Proxy selector wasn't used for redirect");
+
+            // make sure the IOException was caused by an IllegalArgumentException
+            Assert.assertTrue(ioe.getCause() instanceof IllegalArgumentException, "Unexpected cause in the IOException");
+        }
+    }
+
+
+    private static HttpServer createServer(final HttpHandler handler) throws IOException {
+        final InetSocketAddress serverAddr = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
+        final int backlog = -1;
+        final HttpServer server = HttpServer.create(serverAddr, backlog);
+        // setup the handler
+        server.createContext(WEB_APP_CONTEXT, handler);
+        // start the server
+        server.start();
+        System.out.println("Server started on " + server.getAddress());
+        return server;
+    }
+
+    private static class SimpleHandler implements HttpHandler {
+        private volatile boolean redirectSent = false;
+
+        @Override
+        public void handle(final HttpExchange httpExchange) throws IOException {
+            final String redirectURL;
+            try {
+                redirectURL = new URI("http", "/irrelevant", null).toString();
+            } catch (URISyntaxException e) {
+                throw new IOException(e);
+            }
+            httpExchange.getResponseHeaders().add("Location", redirectURL);
+            final URI requestURI = httpExchange.getRequestURI();
+            System.out.println("Handling " + httpExchange.getRequestMethod() + " request "
+                    + requestURI + " responding with redirect to " + redirectURL);
+            this.redirectSent = true;
+            httpExchange.sendResponseHeaders(301, -1);
+        }
+
+    }
+
+    private static class CustomProxySelector extends DefaultProxySelector {
+
+        private volatile boolean selectorUsedForRedirect = false;
+
+        @Override
+        public List<Proxy> select(final URI uri) {
+            if (uri.toString().contains("/irrelevant")) {
+                this.selectorUsedForRedirect = true;
+            }
+            return super.select(uri);
+        }
+    }
+}
--- a/test/jdk/java/net/MulticastSocket/MulticastAddresses.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/net/MulticastSocket/MulticastAddresses.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 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
@@ -22,76 +22,32 @@
  */
 
 /*
- *
+ * @test
  * @bug 4488458
+ * @library /test/lib
  * @summary Test that MutlicastSocket.joinGroup is working for
  *          various multicast and non-multicast addresses.
  */
+
+import jdk.test.lib.NetworkConfiguration;
+
 import java.net.*;
-import java.util.Enumeration;
 import java.io.IOException;
+import java.util.stream.Collectors;
 
 public class MulticastAddresses {
-
-    public static void main(String args[]) throws Exception {
-
-        boolean ipv6_available = false;
-        NetworkInterface ni = null;
-
-        /*
-         * Examine the network interfaces and determine :-
-         *
-         * 1. If host has IPv6 support
-         * 2. Get reference to a non-loopback interface
-         */
-        Enumeration nifs = NetworkInterface.getNetworkInterfaces();
-        while (nifs.hasMoreElements()) {
-            NetworkInterface this_ni = (NetworkInterface)nifs.nextElement();
-
-            Enumeration addrs = this_ni.getInetAddresses();
-            while (addrs.hasMoreElements()) {
-                InetAddress addr = (InetAddress)addrs.nextElement();
-                if (addr instanceof Inet6Address) {
-                    ipv6_available = true;
-                }
-
-                if (!addr.isLoopbackAddress() && ni == null) {
-                    ni = this_ni;
-                }
-            }
-
-            if (ipv6_available) {
-                break;
-            }
-        }
-
+    public static void runTest(NetworkInterface ni,
+                               String[] multicasts,
+                               String[] nonMulticasts) throws Exception {
         int failures = 0;
 
-        String multicasts[] = {
-                "224.80.80.80",
-                "ff01::1",
-                "ff02::1234",
-                "ff05::a",
-                "ff0e::1234:a" };
-
-        String non_multicasts[] = {
-                "129.1.1.1",
-                "::1",
-                "::129.1.1.1",
-                "fe80::a00:20ff:fee5:bc02" };
-
         MulticastSocket s = new MulticastSocket();
 
         /* test valid multicast addresses */
-
-        for (int i=0; i<multicasts.length; i++) {
+        for (int i = 0; i < multicasts.length; i++) {
             InetAddress ia = InetAddress.getByName(multicasts[i]);
-            if (ia instanceof Inet6Address && !ipv6_available) {
-                continue;
-            }
 
-            System.out.println("Test: " + ia);
-
+            System.out.println("Test: " + ia + " " + " ni: " + ni);
             try {
 
                 System.out.print("    joinGroup(InetAddress) ");
@@ -100,8 +56,8 @@
                 System.out.println("    Passed.");
 
                 System.out.print("    joinGroup(InetAddress,NetworkInterface) ");
-                s.joinGroup(new InetSocketAddress(ia,0), ni);
-                s.leaveGroup(new InetSocketAddress(ia,0), ni);
+                s.joinGroup(new InetSocketAddress(ia, 0), ni);
+                s.leaveGroup(new InetSocketAddress(ia, 0), ni);
                 System.out.println("    Passed.");
             } catch (IOException e) {
                 failures++;
@@ -111,13 +67,8 @@
         }
 
         /* test non-multicast addresses */
-
-        for (int i=0; i<non_multicasts.length; i++) {
-            InetAddress ia = InetAddress.getByName(non_multicasts[i]);
-            if (ia instanceof Inet6Address && !ipv6_available) {
-                continue;
-            }
-
+        for (int i = 0; i < nonMulticasts.length; i++) {
+            InetAddress ia = InetAddress.getByName(nonMulticasts[i]);
             boolean failed = false;
 
             System.out.println("Test: " + ia + " ");
@@ -130,20 +81,59 @@
             } catch (IOException e) {
                 System.out.println("    Passed: " + e.getMessage());
             }
-
             if (failed) {
                 s.leaveGroup(ia);
                 failures++;
             }
         }
-
-        /* done */
-
         s.close();
-
         if (failures > 0) {
             throw new Exception(failures + " test(s) failed - see log file.");
         }
     }
 
+
+    public static void main(String args[]) throws Exception {
+
+        String[] multicastIPv4 = {
+                "224.80.80.80",
+        };
+        String[] multicastIPv6 = {
+                "ff01::1",
+                "ff02::1234",
+                "ff05::a",
+                "ff0e::1234:a"};
+
+        String[] nonMulticastIPv4 = {
+                "129.1.1.1"
+        };
+
+        String[] nonMulticastIPv6 = {
+                "::1",
+                "::129.1.1.1",
+                "fe80::a00:20ff:fee5:bc02"};
+
+        /*
+         * Examine the network interfaces and determine :-
+         *
+         * 1. If host has IPv6 support
+         * 2. Get reference to a non-loopback interface
+         */
+        NetworkConfiguration nc = NetworkConfiguration.probe();
+        var ipv6List = nc.ip6MulticastInterfaces(false)
+                .collect(Collectors.toList());
+
+        var ipv4List = nc.ip4MulticastInterfaces(false)
+                .collect(Collectors.toList());
+
+        if (ipv6List.retainAll(ipv4List)) {
+            runTest(ipv6List.get(0), multicastIPv4, nonMulticastIPv4);
+            runTest(ipv6List.get(0), multicastIPv6, nonMulticastIPv6);
+        } else {
+            if (!ipv4List.isEmpty())
+                runTest(ipv4List.get(0), multicastIPv4, nonMulticastIPv4);
+            if (!ipv6List.isEmpty())
+                runTest(ipv6List.get(0), multicastIPv6, nonMulticastIPv6);
+        }
+    }
 }
--- a/test/jdk/java/net/MulticastSocket/NoLoopbackPackets.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/net/MulticastSocket/NoLoopbackPackets.java	Wed Aug 28 11:58:56 2019 -0400
@@ -29,6 +29,7 @@
  */
 import java.util.*;
 import java.net.*;
+import jdk.test.lib.NetworkConfiguration;
 import jdk.test.lib.net.IPSupport;
 
 public class NoLoopbackPackets {
@@ -62,7 +63,9 @@
             if (IPSupport.hasIPv4()) {
                 groups.add(new InetSocketAddress(InetAddress.getByName("224.1.1.1"), port));
             }
-            if (IPSupport.hasIPv6()) {
+
+            NetworkConfiguration nc = NetworkConfiguration.probe();
+            if (IPSupport.hasIPv6() && nc.hasTestableIPv6Address()) {
                 groups.add(new InetSocketAddress(InetAddress.getByName("::ffff:224.1.1.2"), port));
                 groups.add(new InetSocketAddress(InetAddress.getByName("ff02::1:1"), port));
             }
--- a/test/jdk/java/net/MulticastSocket/Reuse.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/net/MulticastSocket/Reuse.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,11 @@
 import java.net.MulticastSocket;
 import java.net.BindException;
 
+/*
+ * @test
+ * @summary Check if MulticastSocket sets SO_REUSEADDR
+ */
+
 public class Reuse {
     public static void main(String[] args) throws Exception {
         MulticastSocket s1, s2;
--- a/test/jdk/java/net/Socket/reset/Test.java	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-/*
- * @bug 4517622
- * @summary SocketException on first read after error; -1 on subsequent reads
- */
-import java.net.*;
-import java.io.*;
-import java.util.Random;
-
-public class Test {
-
-    static int TEST_COMBINATIONS = 5;
-
-    // test server that cycles through each combination of response
-
-    static class Server extends Thread {
-        ServerSocket ss;
-
-        public Server() throws IOException {
-            ss = new ServerSocket(0);
-            System.out.println("Server listening on port: " + getPort());
-        }
-
-        public void run() {
-
-            int testCombination = 0;
-
-            try {
-                for (;;) {
-                    Socket s = ss.accept();
-
-                    switch (testCombination) {
-                        case 0:
-                            s.setTcpNoDelay(false);
-                            s.getOutputStream().write(new byte[256]);
-                            s.setSoLinger(true, 0);
-                            break;
-
-                        case 1:
-                            s.setTcpNoDelay(true);
-                            s.getOutputStream().write(new byte[256]);
-                            s.setSoLinger(true, 0);
-                            break;
-
-                        case 2:
-                            s.getOutputStream().write("hello".getBytes());
-                            s.setSoLinger(true, 0);
-                            break;
-
-                        case 3:
-                            break;      /* EOF test */
-
-                        case 4:
-                            s.getOutputStream().write(new byte[256]);
-                            break;
-                    }
-
-                    s.close();
-
-                    testCombination = (testCombination + 1) % TEST_COMBINATIONS;
-                }
-            } catch (IOException ioe) {
-                if (!ss.isClosed()) {
-                    System.err.println("Server failed: " + ioe);
-                }
-            }
-        }
-
-        public int getPort() {
-            return ss.getLocalPort();
-        }
-
-        public void shutdown() {
-            try {
-                ss.close();
-            } catch (IOException ioe) { }
-        }
-
-    }
-
-    static final int STATE_DATA = 0;
-    static final int STATE_EOF = 1;
-    static final int STATE_IOE = 2;
-
-    static void Test(SocketAddress sa) throws Exception {
-        System.out.println("-----------");
-
-        Socket s = new Socket();
-        s.connect(sa);
-
-        byte b[] = new byte[50];
-        int state = STATE_DATA;
-        boolean failed = false;
-
-        Random rand = new Random();
-
-        for (int i=0; i<200; i++) {
-            switch (rand.nextInt(4)) {
-                case 0:
-                    try {
-                        s.getOutputStream().write("data".getBytes());
-                    } catch (IOException ioe) { }
-                    break;
-
-                case 1:
-                    try {
-                        int n = s.getInputStream().available();
-
-                        // available should never return > 0 if read
-                        // has already thrown IOE or returned EOF
-
-                        if (n > 0 && state != STATE_DATA) {
-                            System.out.println("FAILED!! available: " + n +
-                                " (unexpected as IOE or EOF already received)");
-                            failed = true;
-                        }
-                    } catch (IOException ioe) {
-                        System.out.println("FAILED!!! available: " + ioe);
-                        failed = true;
-                    }
-                    break;
-
-                case 2:
-                    try {
-                        int n = s.getInputStream().read(b);
-
-                        if (n > 0 && state == STATE_IOE) {
-                            System.out.println("FAILED!! read: " + n +
-                                " (unexpected as IOE already thrown)");
-                            failed = true;
-                        }
-
-                        if (n > 0 && state == STATE_EOF) {
-                            System.out.println("FAILED!! read: " + n +
-                                " (unexpected as EOF already received)");
-                            failed = true;
-                        }
-
-                        if (n < 0) {
-                            if (state == STATE_IOE) {
-                                System.out.println("FAILED!! read: EOF " +
-                                    " (unexpected as IOE already thrown)");
-                                failed = true;
-                            }
-                            if (state != STATE_EOF) {
-                                System.out.println("read: EOF");
-                                state = STATE_EOF;
-                            }
-                        }
-
-                    } catch (IOException ioe) {
-                        if (state == STATE_EOF) {
-                            System.out.println("FAILED!! read: " + ioe +
-                                " (unexpected as EOF already received)");
-                            failed = true;
-                        }
-                        if (state != STATE_IOE) {
-                            System.out.println("read: " + ioe);
-                            state = STATE_IOE;
-                        }
-                    }
-                    break;
-
-                case 3:
-                    try {
-                        Thread.currentThread().sleep(100);
-                    } catch (Exception ie) { }
-            }
-
-            if (failed) {
-                failures++;
-                break;
-            }
-        }
-
-        s.close();
-    }
-
-    static int failures = 0;
-
-    public static void main(String args[]) throws Exception {
-        SocketAddress sa = null;
-        Server svr = null;
-
-        // server mode only
-        if (args.length > 0) {
-            if (args[0].equals("-server")) {
-                svr = new Server();
-                svr.start();
-                return;
-            }
-        }
-
-        // run standalone or connect to remote server
-        if (args.length > 0) {
-            InetAddress rh = InetAddress.getByName(args[0]);
-            int port = Integer.parseInt(args[1]);
-            sa = new InetSocketAddress(rh, port);
-        } else {
-            svr = new Server();
-            svr.start();
-
-            InetAddress lh = InetAddress.getLocalHost();
-            sa = new InetSocketAddress(lh, svr.getPort());
-        }
-
-        for (int i=0; i<10; i++) {
-            Test(sa);
-        }
-
-        if (svr != null) {
-            svr.shutdown();
-        }
-
-        if (failures > 0) {
-            throw new Exception(failures + " sub-test(s) failed.");
-        }
-    }
-}
--- a/test/jdk/java/net/Socks/SocksIPv6Test.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/net/Socks/SocksIPv6Test.java	Wed Aug 28 11:58:56 2019 -0400
@@ -24,6 +24,7 @@
 /* @test
  * @bug 7100957
  * @modules jdk.httpserver
+ * @library /test/lib
  * @summary Java doesn't correctly handle the SOCKS protocol when used over IPv6.
  * @run testng SocksIPv6Test
  */
@@ -46,10 +47,13 @@
 import java.util.List;
 import com.sun.net.httpserver.*;
 import java.io.BufferedWriter;
+import org.testng.SkipException;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import jdk.test.lib.NetworkConfiguration;
+
 import static org.testng.Assert.*;
 
 public class SocksIPv6Test {
@@ -57,11 +61,13 @@
     private HttpServer server;
     private SocksServer socks;
     private String response = "Hello.";
-    private static boolean shouldRun = false;
 
     @BeforeClass
     public void setUp() throws Exception {
-        shouldRun = ensureInet6AddressFamily() && ensureIPv6OnLoopback();
+        if (!ensureInet6AddressFamily() || !ensureIPv6OnLoopback()) {
+            NetworkConfiguration.printSystemConfiguration(System.out);
+            throw new SkipException("Host does not support IPv6");
+        }
 
         server = HttpServer.create(new InetSocketAddress("::1", 0), 0);
         server.createContext("/", ex -> {
@@ -120,8 +126,6 @@
 
     @Test(groups = "unit")
     public void testSocksOverIPv6() throws Exception {
-        if (!shouldRun) return;
-
         Proxy proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("::1",
                 socks.getPort()));
         URL url = new URL("http://[::1]:" + server.getAddress().getPort());
@@ -136,8 +140,6 @@
 
     @Test(groups = "unit")
     public void testSocksOverIPv6Hostname() throws Exception {
-        if (!shouldRun) return;
-
         InetAddress ipv6Loopback = InetAddress.getByName("::1");
         String ipv6Hostname = ipv6Loopback.getHostName();
         String ipv6HostAddress = ipv6Loopback.getHostAddress();
--- a/test/jdk/java/net/URLClassLoader/GetURLsTest.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/net/URLClassLoader/GetURLsTest.java	Wed Aug 28 11:58:56 2019 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 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
@@ -25,11 +25,16 @@
 import java.io.*;
 
 /*
- * Regression test for URLClassLoader getURLs() and addURL() methods.
+ * @test
+ * @summary Regression test for URLClassLoader getURLs() and addURL() methods.
  * See RFE 4102580: Need URLClassLoader.getURLs() method
  */
-class GetURLsTest {
+public class GetURLsTest {
+    static final String TEST_DIR = System.getProperty("test.src", ".");
+
     public static void main(String[] args) throws Exception {
+        File testJars = new File(TEST_DIR, "jars");
+
         MyURLClassLoader ucl =
             new MyURLClassLoader(new URL[] { new File(".").toURL() });
         p("initial urls = ", ucl.getURLs());
@@ -37,7 +42,7 @@
         if (u != null) {
             p("found resource = " + u);
         }
-        ucl.addURL(new File("jars", "class_path_test.jar").toURL());
+        ucl.addURL(new File(testJars, "class_path_test.jar").toURL());
         p("new urls = ", ucl.getURLs());
         Class c = ucl.loadClass("Foo");
         p("found class = " + c);
--- a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java	Wed Aug 28 11:58:56 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
@@ -21,18 +21,24 @@
  * questions.
  */
 
-/*
- * @test
- * @summary Tests what happens when push promise handlers and their
- *          response body handlers and subscribers throw unexpected exceptions.
+
+/**
+ * This is not a test. Actual tests are implemented by concrete subclasses.
+ * The abstract class AbstractThrowingPushPromises provides a base framework
+ * to test what happens when push promise handlers and their
+ * response body handlers and subscribers throw unexpected exceptions.
+ * Concrete tests that extend this abstract class will need to include
+ * the following jtreg tags:
+ *
  * @library /test/lib http2/server
  * @build jdk.test.lib.net.SimpleSSLContext HttpServerAdapters
-  *       ReferenceTracker AbstractThrowingPushPromises
+ *        ReferenceTracker AbstractThrowingPushPromises
+ *        <concrete-class-name>
  * @modules java.base/sun.net.www.http
  *          java.net.http/jdk.internal.net.http.common
  *          java.net.http/jdk.internal.net.http.frame
  *          java.net.http/jdk.internal.net.http.hpack
- * @run testng/othervm -Djdk.internal.httpclient.debug=true AbstractThrowingPushPromises
+ * @run testng/othervm -Djdk.internal.httpclient.debug=true <concrete-class-name>
  */
 
 import jdk.test.lib.net.SimpleSSLContext;
--- a/test/jdk/java/net/httpclient/LineStreamsAndSurrogatesTest.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/net/httpclient/LineStreamsAndSurrogatesTest.java	Wed Aug 28 11:58:56 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
@@ -61,7 +61,7 @@
     }
 
     @Test
-    void testUncomplete() throws Exception {
+    public void testUncomplete() throws Exception {
         // Uses U+10400 which is encoded as the surrogate pair U+D801 U+DC00
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r les\n\n" +
                 " fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres\ud801\udc00";
@@ -121,7 +121,7 @@
     }
 
     @Test
-    void testStream1() throws Exception {
+    public void testStream1() throws Exception {
         // Uses U+10400 which is encoded as the surrogate pair U+D801 U+DC00
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r\r les\n\n" +
                 " fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres";
@@ -170,7 +170,7 @@
 
 
     @Test
-    void testStream2() throws Exception {
+    public void testStream2() throws Exception {
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r\r" +
                 " les fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres\r\r";
         Charset charset = UTF_8;
@@ -216,7 +216,7 @@
     }
 
     @Test
-    void testStream3_UTF16() throws Exception {
+    public void testStream3_UTF16() throws Exception {
         // Uses U+10400 which is encoded as the surrogate pair U+D801 U+DC00
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r\r" +
                 " les\n\n fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres";
@@ -263,7 +263,7 @@
 
 
     @Test
-    void testStream4_UTF16() throws Exception {
+    public void testStream4_UTF16() throws Exception {
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r\r" +
                 " les fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres\r\r";
         Charset charset = UTF_16;
--- a/test/jdk/java/net/httpclient/LineSubscribersAndSurrogatesTest.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/net/httpclient/LineSubscribersAndSurrogatesTest.java	Wed Aug 28 11:58:56 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
@@ -81,7 +81,7 @@
     }
 
     @Test
-    void testIncomplete() throws Exception {
+    public void testIncomplete() throws Exception {
         // Uses U+10400 which is encoded as the surrogate pair U+D801 U+DC00
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r" +
                 " les\n\n fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres\ud801\udc00";
@@ -123,7 +123,7 @@
 
 
     @Test
-    void testStringWithFinisherLF() throws Exception {
+    public void testStringWithFinisherLF() throws Exception {
         // Uses U+10400 which is encoded as the surrogate pair U+D801 U+DC00
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r" +
                 " les\n\n fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres\r";
@@ -155,7 +155,7 @@
 
 
     @Test
-    void testStringWithFinisherCR() throws Exception {
+    public void testStringWithFinisherCR() throws Exception {
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r" +
                 " les fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres\r\r";
         ObjectSubscriber subscriber = new ObjectSubscriber();
@@ -183,7 +183,7 @@
     }
 
     @Test
-    void testStringWithFinisherCRLF() throws Exception {
+    public void testStringWithFinisherCRLF() throws Exception {
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r" +
                 " les fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres";
         ObjectSubscriber subscriber = new ObjectSubscriber();
@@ -210,7 +210,7 @@
 
 
     @Test
-    void testStringWithFinisherBR() throws Exception {
+    public void testStringWithFinisherBR() throws Exception {
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r" +
                 " les\r\r fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres";
         ObjectSubscriber subscriber = new ObjectSubscriber();
@@ -240,7 +240,7 @@
     }
 
     @Test
-    void testStringWithFinisherBR_UTF_16() throws Exception {
+    public void testStringWithFinisherBR_UTF_16() throws Exception {
         String text = "Bient\u00f4t\r\n nous plongerons\r\n dans\r" +
                 " les\r\r fr\u00f4\ud801\udc00des\r\n t\u00e9n\u00e8bres\r\r";
         ObjectSubscriber subscriber = new ObjectSubscriber();
--- a/test/jdk/java/net/ipv6tests/TcpTest.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/java/net/ipv6tests/TcpTest.java	Wed Aug 28 11:58:56 2019 -0400
@@ -133,7 +133,19 @@
             dprintln ("connecting to " + ia6addr);
             c2 = new Socket ();
             c2.connect (sadr6, 1000);
-            throw new RuntimeException ("connect to IPv6 address should be refused");
+            dprintln ("Unexpected successful connection: " + c2);
+            // Connect should fail with timeout exception. However, if something else is
+            // accepting connections, verify it is not our server.
+            server.setSoTimeout(500);
+            // Ok if accept() fails because of timeout
+            while (true) {
+                // acceptedSocket could be connected to c1, but not c2
+                try (Socket acceptedSocket = server.accept()) {
+                    dprintln("accepted socket: " + acceptedSocket);
+                    if (acceptedSocket.getRemoteSocketAddress().equals(c2.getLocalSocketAddress()))
+                        throw new RuntimeException("connect to IPv6 address should be refused");
+                }
+            }
         } catch (IOException e) { }
         server.close ();
         c1.close ();
@@ -153,7 +165,19 @@
         try {
             dprintln ("connecting to " + ia4addr);
             c2 = new Socket (ia4addr, port);
-            throw new RuntimeException ("connect to IPv4 address should be refused");
+            dprintln ("Unexpected successful connection: " + c2);
+            // Connect should fail with timeout exception. However, if something else is
+            // accepting connections, verify it is not our server.
+            server.setSoTimeout(500);
+            // Ok if accept() fails because of timeout
+            while (true) {
+                // acceptedSocket could be connected to c1, but not c2
+                try (Socket acceptedSocket = server.accept()) {
+                    dprintln("accepted socket: " + acceptedSocket);
+                    if (acceptedSocket.getRemoteSocketAddress().equals(c2.getLocalSocketAddress()))
+                        throw new RuntimeException("connect to IPv4 address should be refused");
+                }
+            }
         } catch (IOException e) { }
         server.close ();
         c1.close ();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/MappedByteBuffer/MapSyncFail.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @summary Test failure paths for MAP_SYNC FileChannel.map of non-DAX files
+ * @modules java.base/jdk.internal.misc
+ * @run main MapSyncFail true
+ * @run main MapSyncFail false
+ */
+
+import java.io.*;
+import java.nio.*;
+import java.util.*;
+import java.nio.channels.*;
+import jdk.nio.mapmode.*;
+import jdk.internal.misc.Unsafe;
+
+public class MapSyncFail {
+
+    public static final int K = 1024;
+
+    public static void main(String[] args) throws Exception {
+        if (args.length != 1) {
+            throw new Exception("Expected true or false as argument");
+        }
+        boolean is_rw = Boolean.valueOf(args[0]);
+        FileChannel.MapMode mode = (is_rw ? ExtendedMapMode.READ_WRITE_SYNC : ExtendedMapMode.READ_ONLY_SYNC);
+        // it is assumed that /tmp is not a DAX file system
+        File file = File.createTempFile("MapSyncFail", null);
+        file.deleteOnExit();
+        long filesize = (8 * K);
+        try (RandomAccessFile raf = new RandomAccessFile(file, "rw")) {
+            raf.setLength(filesize);
+            FileChannel fc = raf.getChannel();
+            MappedByteBuffer mbb = fc.map(mode, 0, filesize);
+        } catch(IOException ioe) {
+            // when writeback is enabled for the current os/cpu
+            // combination the underlying mmap should be attempted and
+            // the map call should fail with IOException
+            if (!Unsafe.isWritebackEnabled()) {
+                throw new Exception("IOException not expected");
+            }
+            System.out.println("caught " + ioe);
+            ioe.printStackTrace();
+            return;
+        } catch (UnsupportedOperationException uoe) {
+            // when writeback is not enabled for the current os/cpu
+            // combination the mmap should not be attempted and the
+            // map call should fail with UnsupportedOperationException
+
+            if (Unsafe.isWritebackEnabled()) {
+                throw new Exception("UnsupportedOperationException not expected");
+            }
+            System.out.println("caught " + uoe);
+            uoe.printStackTrace();
+            return;
+        }
+
+        throw new Exception("expected IOException or UnsupportedOperationException");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/nio/MappedByteBuffer/PmemTest.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,154 @@
+/*
+ * 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.
+ */
+
+/*
+ * This test is manually run because it requires an NVRAM device to be
+ * mapped as DAX file system or, at least, to be simulated by a
+ * volatile RAM mapped file system. Also, on AArch64 it requires an
+ * ARMV8.2 CPU which implements the dc CVAP instruction (CPU feature
+ * dcpop) and an OS that makes it available from user space.
+ *
+ * If the test runs on such a host without throwing an exception then
+ * that confirms that NVRAM-backed byte buffers can be allocated,
+ * updated and forced via cache line writeback.
+ */
+
+/*
+ * How to run this test:
+ *
+ * Ideally this test should be run on a x86_64/amd64 or aarch64 host
+ * fitted with an NVRAM memory device. The NVRAM should appear as
+ * /dev/pmem0 or some equivalent DAX file device. The file device
+ * should be mounted at /mnt/pmem with a directory tmp created
+ * directly under that mount point with a+rwx access.
+ *
+ * It is possible to run the test on x86_64 using a volatile RAM
+ * backed device to simulate NVRAM, even though this does not provide
+ * any guarantee of persistence of data across program runs. For the
+ * latter case the following instructions explain how to set up the
+ * simulated NVRAM device.
+ *
+ * https://developers.redhat.com/blog/2016/12/05/configuring-and-using-persistent-memory-rhel-7-3/
+ * https://nvdimm.wiki.kernel.org/
+ * TL;DR: add "memmap=1G!4G" to /etc/default/grub,
+ *        then grub2-mkconfig -o /boot/grub2/grub.cfg and reboot
+ *
+ *  ndctl create-namespace  * -f -e namespace0.0 -m memory -M mem
+ *  mkdir /mnt/pmem
+ *  mkfs.xfs -f /dev/pmem0; mount -o dax /dev/pmem0 /mnt/pmem/
+ *  mkdir /mnt/pmem/test; chmod a+rwx /mnt/pmem/test
+ *
+ * Now run the test program
+ *
+ *  java PmemTest
+ *
+ * or
+ *
+ *  make test TEST=jdk/java/nio/MappedByteBuffer/PmemTest.java
+*/
+
+/* @test
+ * @summary Testing NVRAM mapped byte buffer support
+ * @run main/manual PmemTest
+ * @requires (os.family == "linux")
+ * @requires ((os.arch == "x86_64")|(os.arch == "amd64")|(os.arch == "aarch64"))
+ */
+
+import java.io.File;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.EnumSet;
+import java.util.List;
+import jdk.nio.mapmode.ExtendedMapMode;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.BufferPoolMXBean;
+
+public class PmemTest {
+
+    public static final int K = 1024;
+    public static final int NUM_KBS = 16;
+
+    public static void main(String[] args) throws Exception {
+
+        System.out.println("test");
+
+        String dir = "/tmp"; // mapSync should fail
+        dir = "/mnt/pmem/test"; // mapSync should work, since fs mount is -o dax
+
+        Path path = new File(dir, "pmemtest").toPath();
+
+        FileChannel fileChannel = (FileChannel) Files
+                .newByteChannel(path, EnumSet.of(
+                        StandardOpenOption.READ,
+                        StandardOpenOption.WRITE,
+                        StandardOpenOption.CREATE));
+
+        MappedByteBuffer mappedByteBuffer = fileChannel.map(ExtendedMapMode.READ_WRITE_SYNC, 0, NUM_KBS * K);
+
+
+        dumpBufferPoolBeans();
+
+        // for (int loops = 0; loops < 1000; loops++) {
+        for (int loops = 0; loops < 100; loops++) {
+            int base = K * (loops % NUM_KBS);
+            for (int i = 0; i < K ; i++) {
+                for (int j = 0; j < K ;j++) {
+                    testBuffer(mappedByteBuffer, base, (i << 3) + j);
+                    commitBuffer(mappedByteBuffer, base);
+                }
+            }
+        }
+        dumpBufferPoolBeans();
+    }
+
+    public static void testBuffer(MappedByteBuffer mappedByteBuffer, int base, int start) {
+        for (int k = 0; k < 8; k++) {
+            int idx = (start + k) % K;
+            byte z = mappedByteBuffer.get(base + idx);
+            z++;
+            mappedByteBuffer.put(base + idx, z);
+        }
+    }
+
+    public static void commitBuffer(MappedByteBuffer mappedByteBuffer, int base)
+    {
+        mappedByteBuffer.force(base, K);
+    }
+
+    public static void dumpBufferPoolBeans()
+    {
+        List<BufferPoolMXBean> beansList = ManagementFactory.getPlatformMXBeans(BufferPoolMXBean.class);
+        for (BufferPoolMXBean bean : beansList) {
+            System.out.println("BufferPoolMXBean {" +
+                               "\n\tname:          " + bean.getName() +
+                               "\n\tcount:         " + bean.getCount() +
+                               "\n\ttotalCapacity: " + bean.getTotalCapacity() +
+                               "\n\tmemoryUsed:    " + bean.getMemoryUsed() +
+                               "\n}");
+        }
+    }
+}
--- a/test/jdk/javax/xml/jaxp/testng/validation/jdk8037819/BasicTest1.java	Wed Aug 28 11:52:20 2019 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-package validation.jdk8037819;
-
-import com.sun.org.apache.xerces.internal.dom.PSVIElementNSImpl;
-import com.sun.org.apache.xerces.internal.xs.ItemPSVI;
-import validation.BaseTest;
-
-public class BasicTest1 extends BaseTest {
-    public static void main(String[] args) throws Exception {
-        BasicTest1 test = new BasicTest1();
-        test.setUp();
-        test.testSimpleValidation();
-        test.testSimpleValidationWithTrivialXSIType();
-        test.tearDown();
-    }
-
-    protected String getXMLDocument() {
-        return "base.xml";
-    }
-
-    protected String getSchemaFile() {
-        return "base.xsd";
-    }
-
-    public BasicTest1() {
-        super("BasicTest1");
-    }
-
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    public void testSimpleValidation() {
-        try {
-            reset();
-            validateDocument();
-        } catch (Exception e) {
-            fail("Validation failed: " + e.getMessage());
-        }
-        doValidityAsserts();
-    }
-
-    public void testSimpleValidationWithTrivialXSIType() {
-        try {
-            reset();
-            ((PSVIElementNSImpl) fRootNode).setAttributeNS(
-                "http://www.w3.org/2001/XMLSchema-instance", "type", "X");
-            validateDocument();
-        } catch (Exception e) {
-            fail("Validation failed: " + e.getMessage());
-        }
-        doValidityAsserts();
-    }
-
-    private void doValidityAsserts() {
-        assertValidity(ItemPSVI.VALIDITY_VALID, fRootNode.getValidity());
-        assertValidationAttempted(ItemPSVI.VALIDATION_FULL, fRootNode
-                .getValidationAttempted());
-        assertElementName("A", fRootNode.getElementDeclaration().getName());
-        assertElementNamespaceNull(fRootNode.getElementDeclaration()
-                .getNamespace());
-        assertTypeName("X", fRootNode.getTypeDefinition().getName());
-        assertTypeNamespaceNull(fRootNode.getTypeDefinition().getNamespace());
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/javaagent/EventEmitterAgent.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.javaagent;
+
+import java.lang.instrument.Instrumentation;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import jdk.jfr.Configuration;
+import jdk.jfr.Event;
+import jdk.jfr.Name;
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.jfr.EventNames;
+
+// Java agent that emits in multiple threads
+public class EventEmitterAgent {
+
+    private static final int THREADS = 5;
+    private static final int EVENTS_PER_THREAD = 150_000;
+    private static final int EXPECTED_COUNT = THREADS * EVENTS_PER_THREAD;
+    private static final Path DUMP_PATH = Paths.get("dump.jfr").toAbsolutePath();
+
+    // Called when agent is loaded from command line
+    public static void agentmain(String agentArgs, Instrumentation inst) throws Exception {
+        agentWork();
+    }
+
+    // Called when agent is dynamically loaded
+    public static void premain(String agentArgs, Instrumentation inst) throws Exception {
+        agentWork();
+    }
+
+    private static void agentWork() throws Exception {
+        try (Recording r = new Recording(Configuration.getConfiguration("default"))) {
+            r.enable(EventNames.JavaExceptionThrow);
+            r.setDestination(DUMP_PATH);
+            r.start();
+            Thread[] threads = new Thread[THREADS];
+            for (int i = 0; i < THREADS; i++) {
+                threads[i] = new Thread(EventEmitterAgent::emitEvents);
+                threads[i].start();
+            }
+            for (int i = 0; i < THREADS; i++) {
+                threads[i].join();
+            }
+            r.stop();
+        }
+    }
+
+    public static void emitEvents() {
+        for (int i = 0; i < EVENTS_PER_THREAD; i++) {
+            TestEvent e = new TestEvent();
+            e.msg = "Long message that puts pressure on the string pool " + i % 100;
+            e.count = i;
+            e.thread = Thread.currentThread();
+            e.clazz = String.class;
+            e.commit();
+            if (i % 10000 == 0) {
+                try {
+                    Thread.sleep(1);
+                } catch (InterruptedException ie) {
+                    // ignore
+                }
+            }
+        }
+    }
+
+    @Name("Test")
+    static class TestEvent extends Event {
+        String msg;
+        int count;
+        Thread thread;
+        Class<?> clazz;
+    }
+
+    public static void validateRecording() throws Exception {
+        long testEventCount = RecordingFile.readAllEvents(DUMP_PATH)
+                .stream()
+                .filter(e -> e.getEventType().getName().equals("Test"))
+                .count();
+        Asserts.assertTrue(testEventCount == EXPECTED_COUNT, "Mismatch in TestEvent count");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/javaagent/JavaAgentBuilder.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,87 @@
+/*
+ * 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 jdk.test.lib.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.util.JarUtils;
+
+/**
+ * A builder for a common Java agent.
+ * Can be used directly from the jtreg test header to
+ * build a java agent before the test is executed.
+ *
+ * E.g.:
+ * @run driver jdk.test.lib.util.JavaAgentBuilder
+ *             jdk.jfr.javaagent.EventEmitterAgent EventEmitterAgent.jar
+ *
+ */
+public class JavaAgentBuilder {
+
+    /**
+     * Build a java agent jar file with a given agent class.
+     *
+     * @param args[0]    fully qualified name of an agent class
+     * @param args[1]    file name of the agent jar to be created
+     * @throws IOException
+     */
+    public static void main(String... args) throws IOException {
+        String agentClass = args[0];
+        String agentJar = args[1];
+        System.out.println("Building " + agentJar + " with agent class " + agentClass);
+        build(agentClass, agentJar);
+    }
+
+    /**
+     * Build a java agent jar file with a given agent class.
+     * The agent class will be added as both premain class and agent class.
+     *
+     * @param agentClass fully qualified name of an agent class
+     * @param agentJar   file name of the agent jar to be created
+     *                   the file will be placed in a current work directory
+     * @throws IOException
+     */
+    public static void build(String agentClass, String agentJar) throws IOException {
+        Manifest mf = new Manifest();
+        Attributes attrs = mf.getMainAttributes();
+        attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0");
+        attrs.putValue("Premain-Class", agentClass);
+        attrs.putValue("Agent-Class", agentClass);
+
+        Path jarFile = Paths.get(".", agentJar);
+        String testClasses = Utils.TEST_CLASSES;
+        String agentPath = agentClass.replace(".", File.separator) + ".class";
+        Path agentFile = Paths.get(testClasses, agentPath);
+        Path dir = Paths.get(testClasses);
+        JarUtils.createJarFile(jarFile, mf, dir, agentFile);
+        System.out.println("Agent built:" + jarFile.toAbsolutePath());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/javaagent/TestLoadedAgent.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,58 @@
+/*
+ * 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
+ * @key jfr
+ * @summary Tests emitting events in a dynamically loaded Java agent
+ * @requires vm.hasJFR
+ *
+ * @library /test/lib /test/jdk
+ * @modules java.instrument
+ *
+ * @build jdk.jfr.javaagent.EventEmitterAgent
+ *
+ * @run driver jdk.test.lib.util.JavaAgentBuilder
+ *             jdk.jfr.javaagent.EventEmitterAgent EventEmitterAgent.jar
+ *
+ * @run main/othervm -Djdk.attach.allowAttachSelf=true jdk.jfr.javaagent.TestLoadedAgent
+ */
+
+package jdk.jfr.javaagent;
+
+import com.sun.tools.attach.VirtualMachine;
+import jdk.jfr.FlightRecorder;
+import jdk.jfr.FlightRecorderListener;
+import jdk.jfr.Recording;
+import jdk.jfr.RecordingState;
+
+
+public class TestLoadedAgent {
+    public static void main(String... arg) throws Exception {
+        long pid = ProcessHandle.current().pid();
+        VirtualMachine vm = VirtualMachine.attach(Long.toString(pid));
+        vm.loadAgent("EventEmitterAgent.jar");
+        vm.detach();
+        EventEmitterAgent.validateRecording();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/jfr/javaagent/TestPremainAgent.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @key jfr
+ * @summary Tests emitting event before main using a Java agent
+ * @requires vm.hasJFR
+ *
+ * @library /test/lib
+ * @modules java.instrument
+ *
+ * @build jdk.jfr.javaagent.EventEmitterAgent
+ *
+ * @run driver jdk.test.lib.util.JavaAgentBuilder
+ *             jdk.jfr.javaagent.EventEmitterAgent EventEmitterAgent.jar
+ *
+ * @run main/othervm -javaagent:EventEmitterAgent.jar jdk.jfr.javaagent.TestPremainAgent
+ */
+
+package jdk.jfr.javaagent;
+
+
+public class TestPremainAgent {
+    public static void main(String... arg) throws Exception {
+        EventEmitterAgent.validateRecording();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/jdk/nio/zipfs/UpdateEntryTest.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,210 @@
+/*
+ * 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.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+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.util.Arrays;
+import java.util.spi.ToolProvider;
+import java.util.zip.CRC32;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+import static org.testng.Assert.*;
+
+/**
+ * @test
+ * @bug 8229887
+ * @summary Validate ZIP FileSystem can replace existing STORED and DEFLATED entries
+ * @modules jdk.zipfs
+ * @run testng UpdateEntryTest
+ */
+@Test
+public class UpdateEntryTest {
+
+    private static final Path HERE = Path.of(".");
+
+    // Use the ToolProvider interface for accessing the jar tool
+    private static final ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")
+            .orElseThrow(() -> new RuntimeException("jar tool not found")
+            );
+
+    /**
+     * Represents an entry in a ZIP file. An entry encapsulates a name, a
+     * compression method, and its contents/data.
+     */
+    static class Entry {
+        private final String name;
+        private final int method;
+        private final byte[] bytes;
+
+        Entry(String name, int method, String contents) {
+            this.name = name;
+            this.method = method;
+            this.bytes = contents.getBytes(StandardCharsets.UTF_8);
+        }
+
+        static Entry of(String name, int method, String contents) {
+            return new Entry(name, method, contents);
+        }
+
+        /**
+         * Returns a new Entry with the same name and compression method as this
+         * Entry but with the given content.
+         */
+        Entry content(String contents) {
+            return new Entry(name, method, contents);
+        }
+
+        /**
+         * Writes this entry to the given ZIP output stream.
+         */
+        ZipEntry put(ZipOutputStream zos) throws IOException {
+            ZipEntry e = new ZipEntry(name);
+            e.setMethod(method);
+            e.setTime(System.currentTimeMillis());
+            if (method == ZipEntry.STORED) {
+                var crc = new CRC32();
+                crc.update(bytes);
+                e.setCrc(crc.getValue());
+                e.setSize(bytes.length);
+            }
+            zos.putNextEntry(e);
+            zos.write(bytes);
+            return e;
+        }
+    }
+
+    /**
+     * Validate that you can replace an existing entry in a JAR file that
+     * was added with the STORED(no-compression) option
+     */
+    public void testReplaceStoredEntry() throws IOException {
+        String jarFileName = "updateStoredEntry.jar";
+        String storedFileName = "storedFile.txt";
+        String replacedValue = "bar";
+        Path zipFile = Path.of(jarFileName);
+
+        // Create JAR file with a STORED(non-compressed) entry
+        Files.writeString(Path.of(storedFileName), "foobar");
+        int rc = JAR_TOOL.run(System.out, System.err,
+                "cM0vf", jarFileName, storedFileName);
+
+        // Replace the STORED entry
+        try (FileSystem fs = FileSystems.newFileSystem(zipFile)) {
+            Files.writeString(fs.getPath(storedFileName), replacedValue);
+        }
+        Entry e1 = Entry.of(storedFileName, ZipEntry.STORED, replacedValue);
+        verify(zipFile, e1);
+    }
+
+    /**
+     * Test updating an entry that is STORED (not compressed)
+     */
+    public void test1() throws IOException {
+        Entry e1 = Entry.of("foo", ZipEntry.STORED, "hello");
+        Entry e2 = Entry.of("bar", ZipEntry.STORED, "world");
+        test(e1, e2);
+    }
+
+    /**
+     * Test updating an entry that is DEFLATED (compressed)
+     */
+    public void test2() throws IOException {
+        Entry e1 = Entry.of("foo", ZipEntry.DEFLATED, "hello");
+        Entry e2 = Entry.of("bar", ZipEntry.STORED, "world");
+        test(e1, e2);
+    }
+
+    private void test(Entry e1, Entry e2) throws IOException {
+        Path zipfile = Files.createTempFile(HERE, "test", "zip");
+
+        // create zip file
+        try (OutputStream out = Files.newOutputStream(zipfile);
+             ZipOutputStream zos = new ZipOutputStream(out)) {
+            e1.put(zos);
+            e2.put(zos);
+        }
+
+        verify(zipfile, e1, e2);
+
+        String newContents = "hi";
+
+        // replace contents of e1
+        try (FileSystem fs = FileSystems.newFileSystem(zipfile)) {
+            Path foo = fs.getPath(e1.name);
+            Files.writeString(foo, newContents);
+        }
+
+        verify(zipfile, e1.content(newContents), e2);
+    }
+
+
+    /**
+     * Verify that the given path is a zip files containing exactly the
+     * given entries.
+     */
+    private static void verify(Path zipfile, Entry... entries) throws IOException {
+        // check entries with zip API
+        try (ZipFile zf = new ZipFile(zipfile.toFile())) {
+            // check entry count
+            assertTrue(zf.size() == entries.length);
+
+            // check compression method and content of each entry
+            for (Entry e : entries) {
+                ZipEntry ze = zf.getEntry(e.name);
+                assertTrue(ze != null);
+                assertTrue(ze.getMethod() == e.method);
+                try (InputStream in = zf.getInputStream(ze)) {
+                    byte[] bytes = in.readAllBytes();
+                    assertTrue(Arrays.equals(bytes, e.bytes));
+                }
+            }
+        }
+
+        // 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()).count();
+            assertTrue(count == entries.length);
+
+            // check content of each entry
+            for (Entry e : entries) {
+                Path file = fs.getPath(e.name);
+                byte[] bytes = Files.readAllBytes(file);
+                assertTrue(Arrays.equals(bytes, e.bytes));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/net/spi/DefaultProxySelectorTest.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,90 @@
+/*
+ * 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.Assert;
+import org.testng.annotations.Test;
+import sun.net.spi.DefaultProxySelector;
+
+import java.net.ProxySelector;
+import java.net.URI;
+
+/**
+ * @test
+ * @bug 6563286 6797318 8177648
+ * @summary Tests sun.net.spi.DefaultProxySelector#select(URI)
+ * @run testng DefaultProxySelectorTest
+ * @modules java.base/sun.net.spi:+open
+ */
+public class DefaultProxySelectorTest {
+
+    /**
+     * Tests that {@link DefaultProxySelector#select(URI)} throws
+     * {@link IllegalArgumentException} when passed {@code null}
+     */
+    @Test
+    public void testIllegalArgForNull() {
+        final ProxySelector selector = new DefaultProxySelector();
+        try {
+            selector.select(null);
+            Assert.fail("select() was expected to fail for null URI");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+
+    /**
+     * Tests that {@link DefaultProxySelector} throws a {@link IllegalArgumentException}
+     * for URIs that don't have host information
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testIllegalArgForNoHost() throws Exception {
+        final ProxySelector selector = new DefaultProxySelector();
+        assertFailsWithIAE(selector, new URI("http", "/test", null));
+        assertFailsWithIAE(selector, new URI("https", "/test2", null));
+        assertFailsWithIAE(selector, new URI("ftp", "/test3", null));
+    }
+
+
+    /**
+     * Tests that {@link DefaultProxySelector} throws a {@link IllegalArgumentException}
+     * for URIs that don't have protocol/scheme information
+     *
+     * @throws Exception
+     */
+    @Test
+    public void testIllegalArgForNoScheme() throws Exception {
+        final ProxySelector selector = new DefaultProxySelector();
+        assertFailsWithIAE(selector, new URI(null, "/test", null));
+    }
+
+    private static void assertFailsWithIAE(final ProxySelector selector, final URI uri) {
+        try {
+            selector.select(uri);
+            Assert.fail("select() was expected to fail for URI " + uri);
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/validator/PKIXValAndRevCheckTests.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,496 @@
+/*
+ * 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 8225436
+ * @summary Stapled OCSPResponses should be added to PKIXRevocationChecker
+ *          irrespective of revocationEnabled flag
+ * @library /test/lib
+ * @modules java.base/sun.security.validator
+ * @build jdk.test.lib.Convert
+ * @run main PKIXValAndRevCheckTests
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.UnsupportedEncodingException;
+import java.security.cert.CertPathValidator;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertPathValidatorException.BasicReason;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.PKIXRevocationChecker;
+import java.security.cert.TrustAnchor;
+import java.security.cert.X509Certificate;
+import java.util.Base64;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import sun.security.validator.Validator;
+
+public class PKIXValAndRevCheckTests {
+
+    // subject: CN=Good Server,O=TestPKI
+    // issuer: CN=CA1 Intermediate,O=TestPKI
+    // serial: 01000015
+    // notBefore: Aug 16 02:42:32 2019 GMT
+    // notAfter: Aug 15 02:42:32 2020 GMT
+    static final String GOOD_SERVER_PEM =
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIDjTCCAnWgAwIBAgIEAQAAFTANBgkqhkiG9w0BAQsFADAtMRAwDgYDVQQKDAdU\n" +
+        "ZXN0UEtJMRkwFwYDVQQDDBBDQTEgSW50ZXJtZWRpYXRlMB4XDTE5MDgxNjAyNDIz\n" +
+        "MloXDTIwMDgxNTAyNDIzMlowKDEQMA4GA1UECgwHVGVzdFBLSTEUMBIGA1UEAwwL\n" +
+        "R29vZCBTZXJ2ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDSQSUF\n" +
+        "L5th5P21Vijy5pm0WnC0AWCSHX5003f9um70k/IdaAg2rsj/aKHnsm+r4xXGD236\n" +
+        "S7DxBR2w8NTnAofgRWlsAn74lWQhV2p3SU/JKEtFbJV1YAnNOUPKsCnVKDfe3Gev\n" +
+        "zxOLpZ/VKSx9u20bOUbh6QxqlIdIuJ6AW/cgyjdvuN16sIWGWzl17lm81T1cy89x\n" +
+        "TvvsHHqfAh+y3jMwqvIRxoaNQoOjcmxSldRnCwBfhg8xHxB4wKa4z+6Y3gndzne1\n" +
+        "Ms0itbtdYlSF3ADOtwoBrftYDpvsG8VhA4x4QqFAAKx1FPO6OJBYGNfZvnoDDi9g\n" +
+        "i0PgDNftm0l/6FGlAgMBAAGjgbkwgbYwHQYDVR0OBBYEFJNBzLRxgb0znmeuYXc3\n" +
+        "UaFGd9m3MB8GA1UdIwQYMBaAFJraQNM+W62lwqzcSEc6VjNXAaSaMA4GA1UdDwEB\n" +
+        "/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEwYDVR0RBAww\n" +
+        "CoIIdGVyaXlha2kwMAYIKwYBBQUHAQEEJDAiMCAGCCsGAQUFBzABhhRodHRwOi8v\n" +
+        "dGVyaXlha2k6NTIwMDANBgkqhkiG9w0BAQsFAAOCAQEAadl0EQdBJw6dBBelxtox\n" +
+        "id18HMt+MsXssHun1nx8My0VZ3uQBNJ4GgKipNFa+s8nPZIzRr0Ls65dIUiBcg3R\n" +
+        "ep0he/gnkaowRRxGqMkALl3VzUz8INSRzdCIVm0EBeDCaHGLzE6G3uIqWwldei8k\n" +
+        "IOHtiVLESAJvCvSEOAnoJHRVD8+tbEIxRsSFkoKGqc5U7bsCVC5uSXOkiHEP/3zm\n" +
+        "6YixiT+hLk6QKegkQxQPZ+irGBeN2q2PAq5vTh1hJDciwqE3h8GxZ15iR3WIedc8\n" +
+        "6EHJ7+N27nWZLtFgcLKNXEsm1Eh/YNIrpeN0OQBGSLD3lIju5IO0mD3oQfA4miqT\n" +
+        "wQ==\n" +
+        "-----END CERTIFICATE-----";
+
+    // subject: CN=Bad Server,O=TestPKI
+    // issuer: CN=CA1 Intermediate,O=TestPKI
+    // serial: 01000016
+    // notBefore: Aug 16 02:43:11 2019 GMT
+    // notAfter: Aug 15 02:43:11 2020 GMT
+    static final String BAD_SERVER_PEM =
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIDjDCCAnSgAwIBAgIEAQAAFjANBgkqhkiG9w0BAQsFADAtMRAwDgYDVQQKDAdU\n" +
+        "ZXN0UEtJMRkwFwYDVQQDDBBDQTEgSW50ZXJtZWRpYXRlMB4XDTE5MDgxNjAyNDMx\n" +
+        "MVoXDTIwMDgxNTAyNDMxMVowJzEQMA4GA1UECgwHVGVzdFBLSTETMBEGA1UEAwwK\n" +
+        "QmFkIFNlcnZlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9syEok\n" +
+        "K/8E/hm8Q/cLhSwirDIGFC9nqS8p1bVNTClkMsqxkQAcQptP1zLZiMBdgLjOH3cF\n" +
+        "60UAaz2Y+7WYU5MB6AE8IloDgUUKKUTUmXHzM31OiSVu21+ooo59XzV/cCEu+Qlu\n" +
+        "AiaDuTDhIEtM58zs/3RZN0h+v8M2NXUU4bwYmYVeqP8UW9BEjgznIIrvGpqpHKz5\n" +
+        "EwctL+u/h5Z/DoCOnVq3irMCpInY5/VbIuxfkdfawsFROzUWl6fZ3+CTfQfHhKSM\n" +
+        "sz1/zY/BtQLDTKY120M2FaLmmIoOLrqZo8Pi+JL8IVentNfSHvUX5rrnPKB2/JVS\n" +
+        "8Jc2qvLPk4PWbwECAwEAAaOBuTCBtjAdBgNVHQ4EFgQU8z9qWpJ/FDmKOgQI2vY7\n" +
+        "0OwCNFEwHwYDVR0jBBgwFoAUmtpA0z5braXCrNxIRzpWM1cBpJowDgYDVR0PAQH/\n" +
+        "BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjATBgNVHREEDDAK\n" +
+        "ggh0ZXJpeWFraTAwBggrBgEFBQcBAQQkMCIwIAYIKwYBBQUHMAGGFGh0dHA6Ly90\n" +
+        "ZXJpeWFraTo1MjAwMA0GCSqGSIb3DQEBCwUAA4IBAQBzi8U/3b6hfGwE/przqyha\n" +
+        "Y40Nhh1uCm1rz4bZ27z2Q3vzlg2ay4V3I2NaR4eY/wsuO8AW0qdBJExmYqgi+l9U\n" +
+        "S6i9WqyI22jAKUPsx9WmCZltyU589VDU40h2g6C4+8VnOZm6OKKKTjkKrDn/IFJF\n" +
+        "jU4yIvXrEBHNJr/tcQW0+dF2okIBAnVLUNs8CZZJyWesQtu6J0OBj4tE8s0ET4ep\n" +
+        "XC/3mZkGjziEZw8/dDZ0/+CQbrkDP2vs6iNjz/LUIA9dVXUs9sNeqW+VEHI3vZvJ\n" +
+        "gYVDJn5tWZSIY/O2zV97dz9VeDH3aukuoEm5aAxxhazxRDntcnl2DYrrr2bGuS2Y\n" +
+        "-----END CERTIFICATE-----";
+
+    // subject: CN=CA1 Intermediate,O=TestPKI
+    // issuer: CN=TestRoot,O=TestPKI
+    // serial: 0100
+    // notBefore: May  6 06:00:00 2015 GMT
+    // notAfter: Jan 21 12:00:00 2025 GMT
+    static final String INT_CA_PEM =
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIEbTCCAlWgAwIBAgICAQAwDQYJKoZIhvcNAQELBQAwJTEQMA4GA1UECgwHVGVz\n" +
+        "dFBLSTERMA8GA1UEAwwIVGVzdFJvb3QwHhcNMTUwNTA2MDYwMDAwWhcNMjUwMTIx\n" +
+        "MTIwMDAwWjAtMRAwDgYDVQQKDAdUZXN0UEtJMRkwFwYDVQQDDBBDQTEgSW50ZXJt\n" +
+        "ZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtdKjBpeuJJEv\n" +
+        "di4wMGHE5y7inXuDvMCjkjFRv9XOH20BVAIDMTMeIByk6NQJYeeaTRGXTawZN8/c\n" +
+        "aXtQuqsRGz/q2va/I+A5HIvtu+vujdVksu2baafGM0Ql8Gdzj8MdLGb+kGFji/FX\n" +
+        "f+2PL8UfpnmUikLN728lF9bzcA046I8B43SriFJeYOlLPfE/yjNg5eccdMPDBw7h\n" +
+        "KQPVbXfpcmWRJm/vGlCR38Rd7ceYF3/ctf/0J8Dab7q98ITpH9q5NFD+o2NJZoFq\n" +
+        "7HBPdGTIJ73m3WPzLRrU+JPD7xs9wgmuuRq6hU/lPSd5IJSkJ/cyXkma1RwBO4Lm\n" +
+        "rU2aWDGhNwIDAQABo4GeMIGbMB0GA1UdDgQWBBSa2kDTPlutpcKs3EhHOlYzVwGk\n" +
+        "mjAfBgNVHSMEGDAWgBTwWIIuUEAneAXJeud3ioakmTg32zAPBgNVHRMBAf8EBTAD\n" +
+        "AQH/MA4GA1UdDwEB/wQEAwIBhjA4BggrBgEFBQcBAQQsMCowKAYIKwYBBQUHMAGG\n" +
+        "HGh0dHA6Ly9qaWFuLm9zdGFwbGUub3JnOjcxMDAwDQYJKoZIhvcNAQELBQADggIB\n" +
+        "ADRoginKFigLOKz1NJN86w66eP3r4D/5Qq8+G9DiasmThLQfaVYBvuaR9kL3D9Vr\n" +
+        "1EEXRGmCxMTHetW0SQ/SsMeRbBf8Ihck4MOeAC9cMysvtNfjpwxaAh6zF5bX4pjj\n" +
+        "33gJpjPLNAZru09rSF0GIo9CxPh9rBOkmttrnPDX7rLR9962i/P4KHyHknGM7gY0\n" +
+        "U88ddugkANiFIiAfBRGFz3AqMiMi3VP5STCP0k0ab/frkev6C/qq3th4gQ/Bog/5\n" +
+        "YaoWvzGAs7QoQ7+r0BIRZhG71WQKD4Yx1a43RnG3tFPLFznk0odeh8sr/CI3H/+b\n" +
+        "eyyJLd02ApujZoAfMHzTcq/27mO1ZvA5qSt4wsb7gswnIYwXbJZBBRoixGFD7VP0\n" +
+        "NEXREljpEuGIIy2lkHb5wNV3OEMmAmoKwx1GXWXRfQRHqn1f2/XLYInDg0u9u+G6\n" +
+        "UX3edn6rwP+vlIX2Cx4qC/yX4zg7YxMXCwrol91/7wugkUGPjmU6qmK+TtuwZNQG\n" +
+        "2wtCB4FJXa0YZyDd7U/FH7nWZtG9BgzpLit90hC4+m5V4E/7I6slvwxpkE7y0Nju\n" +
+        "tjy/qcuil6imrOR/apuwT1ecAmyjm1UmpKPLLzYnE6AtSKOTndGa2iNyPDrseFLy\n" +
+        "7TUF/fg/dvZ46OmouSX3upAFRnvpXYXwSQRQ2S+wEnbp\n" +
+        "-----END CERTIFICATE-----";
+
+    // subject: CN=TestRoot,O=TestPKI
+    // issuer: CN=TestRoot,O=TestPKI
+    // serial: 01
+    // notBefore: May  6 00:36:03 2015 GMT
+    // notAfter: Jan 21 00:36:03 2035 GMT
+    static final String ROOT_CA_PEM =
+        "-----BEGIN CERTIFICATE-----\n" +
+        "MIIFKDCCAxCgAwIBAgIBATANBgkqhkiG9w0BAQsFADAlMRAwDgYDVQQKDAdUZXN0\n" +
+        "UEtJMREwDwYDVQQDDAhUZXN0Um9vdDAeFw0xNTA1MDYwMDM2MDNaFw0zNTAxMjEw\n" +
+        "MDM2MDNaMCUxEDAOBgNVBAoMB1Rlc3RQS0kxETAPBgNVBAMMCFRlc3RSb290MIIC\n" +
+        "IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuLCcVhyIaPV5CHjvnyAvK978\n" +
+        "TUC2YY5wZ8e21L8C+SvxCoE5U66H+wMsNIC90i1ynlz49G4oKR67GXcijJpVD1fA\n" +
+        "Dq3Hpc3WDY9/5jRKWZOC0qLmXMPEF8wrwyC3aQ81sytDJOhEfxEf3KvwFDI9NUQb\n" +
+        "tFdWB+IDEvaDCTJgOt/jIJAzLTxzvwPBzP/JHdRCwKdmlQStRp20AmDtpgIlm2RH\n" +
+        "v8ywabI/UqncZHe/LVYdmDNxztziM98Zs1I7vsO2/yebWE/QH3g3k9ZgaT6UnBAq\n" +
+        "gvV2TQhZOGMmps7RrfNdVEHeeRXmJTFAtmbi/o6Ou7xli+3bDuY5Faxk7uOpC54H\n" +
+        "iyyH2Htoyc9A0M9qwkwnrKxlWe594uD9LbWMNBMMTv4nUtf1ZE1swHg/L9XATDa/\n" +
+        "ZB5hL6p/oS2CxloLL982CIbSuV1TcI6s4naTyZ3HxnIKCaOijAK+IDo9qbTFkt9w\n" +
+        "4toc09fWGRV/pgm3p6YptP48JDYTHQK8GvjzQIdALXee28BmM496cV49uo1O6ia0\n" +
+        "Ht1MFMDKav2g9Cr5SYKIFkpZjJ2T0aJ4dLeft+nQCwDP4odHRBTQbqK9oMw6qYav\n" +
+        "PVuZJWwW3ilZtke2D28N4bF2X1nMYFM2obnB/TLkpreNSiyV6M0D2DW8tpGLTXOp\n" +
+        "yZEJqAx2dEhfxRNE7sECAwEAAaNjMGEwHQYDVR0OBBYEFPBYgi5QQCd4Bcl653eK\n" +
+        "hqSZODfbMB8GA1UdIwQYMBaAFPBYgi5QQCd4Bcl653eKhqSZODfbMA8GA1UdEwEB\n" +
+        "/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBjCVYc\n" +
+        "0PmSjzxYGfXtR6+JaDrA/1jhkTPTVTqVniKV4beqoX90BE9krvic7nfvxoYecNux\n" +
+        "b1ZZkXMZ0NVadjxySaFmHo9E5eoPWp2N0Jb5rV+imlofz+U9/lANTb9QJ4L+qUwL\n" +
+        "s40zai1i5yvt4ZcowBRy2BohF2qgaFy8rd+amqVd8LnG06HIOJjZYKgKd2EJyQR6\n" +
+        "F6SPPuSfK5wpkBnkTUvtsvx4+8MKUfKRThGQkovSbXxfusAWehe9XT5hCgG2s04J\n" +
+        "7rL1LVrviBXPFaQgbIGov0PubCJM6V6GFwNJxqVLxbFS0mN+z9M6JzJM5SRF/Ki5\n" +
+        "daczIOGNELVbCct/4aaWeHYwXfnJo/EghAdbS2DPvESXQhNsuW6KYTl6Qhzu3UHw\n" +
+        "yaEIOh2LYENhKJq91Ww6Xhk9seGuwIsj6HXS30lrRztDM+GPU44WQxhmSUwY0C9g\n" +
+        "+KydH1c71eH5vBG3ODKsqBtFkHVD0qhm3Oa33uyUOdvNeRyIQzXSH9QJPXbJURqD\n" +
+        "TRNWmLG4eEIGIFCYyuaBSeCKrvPyiUXR0p9XQjOJVuCQPr8pfW483/BtlzAa6v3r\n" +
+        "jDOoB5v4FaC57HFt8aMrf/B3KGtH/PBpdRSAAIWAIwt9sbTq8nzhCIFhxJTiRWxQ\n" +
+        "uvSM40WEaUsmfpxU+tF2LJvWmNNbDDtEmbFsQQ==\n" +
+        "-----END CERTIFICATE-----";
+
+    // OCSP Response Status: successful (0x0)
+    // Response Type: Basic OCSP Response
+    // Version: 1 (0x0)
+    // Responder Id: O = TestPKI, CN = TestRoot
+    // Produced At: Aug 16 06:06:27 2019 GMT
+    // Responses:
+    // Certificate ID:
+    //   Hash Algorithm: sha1
+    //   Issuer Name Hash: 622C4B816C42E2E99FF41B5CED388DAA33A6B9B3
+    //   Issuer Key Hash: F058822E5040277805C97AE7778A86A4993837DB
+    //   Serial Number: 0100
+    // Cert Status: good
+    // This Update: Aug 16 06:06:27 2019 GMT
+    // Next Update: Aug 17 06:06:27 2019 GMT
+    static final String INT_CA_OCSP_PEM =
+        "MIIILwoBAKCCCCgwgggkBgkrBgEFBQcwAQEEgggVMIIIETCBxqEnMCUxEDAOBgNV\n" +
+        "BAoMB1Rlc3RQS0kxETAPBgNVBAMMCFRlc3RSb290GA8yMDE5MDgxNjA2MDYyN1ow\n" +
+        "ZTBjMDswCQYFKw4DAhoFAAQUYixLgWxC4umf9Btc7TiNqjOmubMEFPBYgi5QQCd4\n" +
+        "Bcl653eKhqSZODfbAgIBAIAAGA8yMDE5MDgxNjA2MDYyN1qgERgPMjAxOTA4MTcw\n" +
+        "NjA2MjdaoSMwITAfBgkrBgEFBQcwAQIEEgQQwlXs/KMVtgxAfc/QGVpHojANBgkq\n" +
+        "hkiG9w0BAQsFAAOCAgEAsDp1oTacP+wZ5ryFzM+j5AaMJ9k7Gmer4QqecszG2YzS\n" +
+        "eM4TUoB2xh3VyQy7OdIDeEsPIwSs/tzJ15/QfJz9WZ6iEUJRj9rnkwdAdRr13AIr\n" +
+        "I7G2jwp7Mbm3h/jluT84tE8+DGohsUq0JGsv1pviT0HL0x40OqfDcOjwvrFCAid1\n" +
+        "ZZwlCWMeybFdX9+GLeHWnyzotajChw52iMK/EHwEWAD2gVX1WbuByGLRy4Oy9HPY\n" +
+        "QbZHjRwlDD29gv9eWK+sFGKV7aBAYTqPkAAvp+GA0xnVUKCuTSHMp53pDA2lkOMp\n" +
+        "z5Hi7SMmkxckTDQI+2By0qwxLymEDbHaALO+XdSD5F5Kysjp6GnfjNcYZQgbxtrC\n" +
+        "ZJOud/hPtBqVEJg42KLLdcYq7uTdNxuQmsu5MK+TTlM37eOWhtbRAozIn2j17QT0\n" +
+        "GV9s+BZWyku8la5+yFUuel5FbNQQTP5av+dKCS3BD/29XFOG4EfK0MEZknA3QKSG\n" +
+        "cI0kd8q5I4fEtsxGW6afra1YBj1TWcnsbHGL/PGHBR0WBr5DXo48dXLHCxEeiAiq\n" +
+        "4lZMcgL4od+hyIOK21evO20sH/Ec73Z0/tXykYp8Y92uv56hRj4/y+WnueyrTOIH\n" +
+        "cwXSvyNTcf0fyZuWEsmUAQmchNPLsEmAolDTcUJsMWOzmYk8cr1WYFrcLWgbOvag\n" +
+        "ggUwMIIFLDCCBSgwggMQoAMCAQICAQEwDQYJKoZIhvcNAQELBQAwJTEQMA4GA1UE\n" +
+        "CgwHVGVzdFBLSTERMA8GA1UEAwwIVGVzdFJvb3QwHhcNMTUwNTA2MDAzNjAzWhcN\n" +
+        "MzUwMTIxMDAzNjAzWjAlMRAwDgYDVQQKDAdUZXN0UEtJMREwDwYDVQQDDAhUZXN0\n" +
+        "Um9vdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALiwnFYciGj1eQh4\n" +
+        "758gLyve/E1AtmGOcGfHttS/Avkr8QqBOVOuh/sDLDSAvdItcp5c+PRuKCkeuxl3\n" +
+        "IoyaVQ9XwA6tx6XN1g2Pf+Y0SlmTgtKi5lzDxBfMK8Mgt2kPNbMrQyToRH8RH9yr\n" +
+        "8BQyPTVEG7RXVgfiAxL2gwkyYDrf4yCQMy08c78Dwcz/yR3UQsCnZpUErUadtAJg\n" +
+        "7aYCJZtkR7/MsGmyP1Kp3GR3vy1WHZgzcc7c4jPfGbNSO77Dtv8nm1hP0B94N5PW\n" +
+        "YGk+lJwQKoL1dk0IWThjJqbO0a3zXVRB3nkV5iUxQLZm4v6Ojru8ZYvt2w7mORWs\n" +
+        "ZO7jqQueB4ssh9h7aMnPQNDPasJMJ6ysZVnufeLg/S21jDQTDE7+J1LX9WRNbMB4\n" +
+        "Py/VwEw2v2QeYS+qf6EtgsZaCy/fNgiG0rldU3COrOJ2k8mdx8ZyCgmjoowCviA6\n" +
+        "Pam0xZLfcOLaHNPX1hkVf6YJt6emKbT+PCQ2Ex0CvBr480CHQC13ntvAZjOPenFe\n" +
+        "PbqNTuomtB7dTBTAymr9oPQq+UmCiBZKWYydk9GieHS3n7fp0AsAz+KHR0QU0G6i\n" +
+        "vaDMOqmGrz1bmSVsFt4pWbZHtg9vDeGxdl9ZzGBTNqG5wf0y5Ka3jUoslejNA9g1\n" +
+        "vLaRi01zqcmRCagMdnRIX8UTRO7BAgMBAAGjYzBhMB0GA1UdDgQWBBTwWIIuUEAn\n" +
+        "eAXJeud3ioakmTg32zAfBgNVHSMEGDAWgBTwWIIuUEAneAXJeud3ioakmTg32zAP\n" +
+        "BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOC\n" +
+        "AgEAYwlWHND5ko88WBn17UeviWg6wP9Y4ZEz01U6lZ4ileG3qqF/dARPZK74nO53\n" +
+        "78aGHnDbsW9WWZFzGdDVWnY8ckmhZh6PROXqD1qdjdCW+a1foppaH8/lPf5QDU2/\n" +
+        "UCeC/qlMC7ONM2otYucr7eGXKMAUctgaIRdqoGhcvK3fmpqlXfC5xtOhyDiY2WCo\n" +
+        "CndhCckEehekjz7knyucKZAZ5E1L7bL8ePvDClHykU4RkJKL0m18X7rAFnoXvV0+\n" +
+        "YQoBtrNOCe6y9S1a74gVzxWkIGyBqL9D7mwiTOlehhcDScalS8WxUtJjfs/TOicy\n" +
+        "TOUkRfyouXWnMyDhjRC1WwnLf+Gmlnh2MF35yaPxIIQHW0tgz7xEl0ITbLluimE5\n" +
+        "ekIc7t1B8MmhCDodi2BDYSiavdVsOl4ZPbHhrsCLI+h10t9Ja0c7QzPhj1OOFkMY\n" +
+        "ZklMGNAvYPisnR9XO9Xh+bwRtzgyrKgbRZB1Q9KoZtzmt97slDnbzXkciEM10h/U\n" +
+        "CT12yVEag00TVpixuHhCBiBQmMrmgUngiq7z8olF0dKfV0IziVbgkD6/KX1uPN/w\n" +
+        "bZcwGur964wzqAeb+BWguexxbfGjK3/wdyhrR/zwaXUUgACFgCMLfbG06vJ84QiB\n" +
+        "YcSU4kVsULr0jONFhGlLJn6cVPrRdiyb1pjTWww7RJmxbEE=";
+
+    // OCSP Response Status: successful (0x0)
+    // Response Type: Basic OCSP Response
+    // Version: 1 (0x0)
+    // Responder Id: O = TestPKI, CN = CA1 Intermediate
+    // Produced At: Aug 16 05:03:09 2019 GMT
+    // Responses:
+    // Certificate ID:
+    //   Hash Algorithm: sha1
+    //   Issuer Name Hash: FE48D59BAF624773549AE209AA14FD20DCE6B8F4
+    //   Issuer Key Hash: 9ADA40D33E5BADA5C2ACDC48473A56335701A49A
+    //   Serial Number: 01000015
+    // Cert Status: good
+    // This Update: Aug 16 05:03:09 2019 GMT
+    // Next Update: Aug 17 05:03:09 2019 GMT
+    static final String GOOD_GUY_OCSP_PEM =
+        "MIIGfgoBAKCCBncwggZzBgkrBgEFBQcwAQEEggZkMIIGYDCB0KEvMC0xEDAOBgNV\n" +
+        "BAoMB1Rlc3RQS0kxGTAXBgNVBAMMEENBMSBJbnRlcm1lZGlhdGUYDzIwMTkwODE2\n" +
+        "MDUwMzA5WjBnMGUwPTAJBgUrDgMCGgUABBT+SNWbr2JHc1Sa4gmqFP0g3Oa49AQU\n" +
+        "mtpA0z5braXCrNxIRzpWM1cBpJoCBAEAABWAABgPMjAxOTA4MTYwNTAzMDlaoBEY\n" +
+        "DzIwMTkwODE3MDUwMzA5WqEjMCEwHwYJKwYBBQUHMAECBBIEEN087n3ef92+4d2K\n" +
+        "+XaudDUwDQYJKoZIhvcNAQELBQADggEBAErIOOkLGwbDWgrpl3lQbsnaoVY6YNYV\n" +
+        "x1bfJ89S8twBouei6a/HmAIDqUPmlVF7gm8sNvgANXuZGkWXmqadSpWxLA36ZT4d\n" +
+        "70iRLmdTaPnKVpUEO5dYMg7nWW+D4hp9wupkPaB3PsEPb4pwrcTOUH1FAi3pZ+hF\n" +
+        "oeNDaE3jHQGEz4dVK1XgK2pxFNf4aTIgj+w40xN5yaCcTYicbLmumNGCzrGwnRqh\n" +
+        "tyoiz27+rTxFrEeWGnNslJfScD9O4oe/KhvYBusurNVrFgG4VcxB5NNemrCW4/cf\n" +
+        "dehv8z50FaZvq1xklqkZ4hgbjNxtI8lAHp+wYDQJub0mhXWmb9K/4kOgggR1MIIE\n" +
+        "cTCCBG0wggJVoAMCAQICAgEAMA0GCSqGSIb3DQEBCwUAMCUxEDAOBgNVBAoMB1Rl\n" +
+        "c3RQS0kxETAPBgNVBAMMCFRlc3RSb290MB4XDTE1MDUwNjA2MDAwMFoXDTI1MDEy\n" +
+        "MTEyMDAwMFowLTEQMA4GA1UECgwHVGVzdFBLSTEZMBcGA1UEAwwQQ0ExIEludGVy\n" +
+        "bWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALXSowaXriSR\n" +
+        "L3YuMDBhxOcu4p17g7zAo5IxUb/Vzh9tAVQCAzEzHiAcpOjUCWHnmk0Rl02sGTfP\n" +
+        "3Gl7ULqrERs/6tr2vyPgORyL7bvr7o3VZLLtm2mnxjNEJfBnc4/DHSxm/pBhY4vx\n" +
+        "V3/tjy/FH6Z5lIpCze9vJRfW83ANOOiPAeN0q4hSXmDpSz3xP8ozYOXnHHTDwwcO\n" +
+        "4SkD1W136XJlkSZv7xpQkd/EXe3HmBd/3LX/9CfA2m+6vfCE6R/auTRQ/qNjSWaB\n" +
+        "auxwT3RkyCe95t1j8y0a1PiTw+8bPcIJrrkauoVP5T0neSCUpCf3Ml5JmtUcATuC\n" +
+        "5q1NmlgxoTcCAwEAAaOBnjCBmzAdBgNVHQ4EFgQUmtpA0z5braXCrNxIRzpWM1cB\n" +
+        "pJowHwYDVR0jBBgwFoAU8FiCLlBAJ3gFyXrnd4qGpJk4N9swDwYDVR0TAQH/BAUw\n" +
+        "AwEB/zAOBgNVHQ8BAf8EBAMCAYYwOAYIKwYBBQUHAQEELDAqMCgGCCsGAQUFBzAB\n" +
+        "hhxodHRwOi8vamlhbi5vc3RhcGxlLm9yZzo3MTAwMA0GCSqGSIb3DQEBCwUAA4IC\n" +
+        "AQA0aIIpyhYoCzis9TSTfOsOunj96+A/+UKvPhvQ4mrJk4S0H2lWAb7mkfZC9w/V\n" +
+        "a9RBF0RpgsTEx3rVtEkP0rDHkWwX/CIXJODDngAvXDMrL7TX46cMWgIesxeW1+KY\n" +
+        "4994CaYzyzQGa7tPa0hdBiKPQsT4fawTpJrba5zw1+6y0ffetovz+Ch8h5JxjO4G\n" +
+        "NFPPHXboJADYhSIgHwURhc9wKjIjIt1T+Ukwj9JNGm/365Hr+gv6qt7YeIEPwaIP\n" +
+        "+WGqFr8xgLO0KEO/q9ASEWYRu9VkCg+GMdWuN0Zxt7RTyxc55NKHXofLK/wiNx//\n" +
+        "m3ssiS3dNgKbo2aAHzB803Kv9u5jtWbwOakreMLG+4LMJyGMF2yWQQUaIsRhQ+1T\n" +
+        "9DRF0RJY6RLhiCMtpZB2+cDVdzhDJgJqCsMdRl1l0X0ER6p9X9v1y2CJw4NLvbvh\n" +
+        "ulF93nZ+q8D/r5SF9gseKgv8l+M4O2MTFwsK6Jfdf+8LoJFBj45lOqpivk7bsGTU\n" +
+        "BtsLQgeBSV2tGGcg3e1PxR+51mbRvQYM6S4rfdIQuPpuVeBP+yOrJb8MaZBO8tDY\n" +
+        "7rY8v6nLopeopqzkf2qbsE9XnAJso5tVJqSjyy82JxOgLUijk53Rmtojcjw67HhS\n" +
+        "8u01Bf34P3b2eOjpqLkl97qQBUZ76V2F8EkEUNkvsBJ26Q==";
+
+    // OCSP Response Status: successful (0x0)
+    // Response Type: Basic OCSP Response
+    // Version: 1 (0x0)
+    // Responder Id: O = TestPKI, CN = CA1 Intermediate
+    // Produced At: Aug 16 05:03:27 2019 GMT
+    // Responses:
+    // Certificate ID:
+    //   Hash Algorithm: sha1
+    //   Issuer Name Hash: FE48D59BAF624773549AE209AA14FD20DCE6B8F4
+    //   Issuer Key Hash: 9ADA40D33E5BADA5C2ACDC48473A56335701A49A
+    //   Serial Number: 01000016
+    // Cert Status: revoked
+    // Revocation Time: Aug 16 04:59:31 2019 GMT
+    // Revocation Reason: keyCompromise (0x1)
+    // This Update: Aug 16 05:03:27 2019 GMT
+    // Next Update: Aug 17 05:03:27 2019 GMT
+    static final String BAD_GUY_OCSP_PEM =
+        "MIIGlAoBAKCCBo0wggaJBgkrBgEFBQcwAQEEggZ6MIIGdjCB5qEvMC0xEDAOBgNV\n" +
+        "BAoMB1Rlc3RQS0kxGTAXBgNVBAMMEENBMSBJbnRlcm1lZGlhdGUYDzIwMTkwODE2\n" +
+        "MDUwMzI3WjB9MHswPTAJBgUrDgMCGgUABBT+SNWbr2JHc1Sa4gmqFP0g3Oa49AQU\n" +
+        "mtpA0z5braXCrNxIRzpWM1cBpJoCBAEAABahFhgPMjAxOTA4MTYwNDU5MzFaoAMK\n" +
+        "AQEYDzIwMTkwODE2MDUwMzI3WqARGA8yMDE5MDgxNzA1MDMyN1qhIzAhMB8GCSsG\n" +
+        "AQUFBzABAgQSBBBbPvAp5xnQ39vLywYMAWbPMA0GCSqGSIb3DQEBCwUAA4IBAQBX\n" +
+        "Ii5GX3Nu9Jqk5ARv+hXlYoJMia+cy02AcVcQiPE250dtNu7tfkX4FhtCDtN+HqqB\n" +
+        "xYUEBk95KPXZiLt7Dla9B38KC5i5gscGBPUW2tGa2wFyqXkG+blPasOc+O5DlvUU\n" +
+        "294HpH3QIVKnZioGpfIHR8h5sa0CGaXykEK4qyjw7IWD7mf5xQZflwE50Ez/0nDi\n" +
+        "NhN+MOp8kfHNfgQmzbx3dLL8LT1j5qdQ9cdkdXwn+DF6v6SJXwn/hOdFDUr4eZ7L\n" +
+        "RAzgaAKvL6DbOGWtnw7fifx++agTzQWkjAto4ekTkzyHK74mqBuyT/6vkgppcPuD\n" +
+        "osE9qhBxWJYQsqWNydXEoIIEdTCCBHEwggRtMIICVaADAgECAgIBADANBgkqhkiG\n" +
+        "9w0BAQsFADAlMRAwDgYDVQQKDAdUZXN0UEtJMREwDwYDVQQDDAhUZXN0Um9vdDAe\n" +
+        "Fw0xNTA1MDYwNjAwMDBaFw0yNTAxMjExMjAwMDBaMC0xEDAOBgNVBAoMB1Rlc3RQ\n" +
+        "S0kxGTAXBgNVBAMMEENBMSBJbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEBAQUA\n" +
+        "A4IBDwAwggEKAoIBAQC10qMGl64kkS92LjAwYcTnLuKde4O8wKOSMVG/1c4fbQFU\n" +
+        "AgMxMx4gHKTo1Alh55pNEZdNrBk3z9xpe1C6qxEbP+ra9r8j4Dkci+276+6N1WSy\n" +
+        "7Ztpp8YzRCXwZ3OPwx0sZv6QYWOL8Vd/7Y8vxR+meZSKQs3vbyUX1vNwDTjojwHj\n" +
+        "dKuIUl5g6Us98T/KM2Dl5xx0w8MHDuEpA9Vtd+lyZZEmb+8aUJHfxF3tx5gXf9y1\n" +
+        "//QnwNpvur3whOkf2rk0UP6jY0lmgWrscE90ZMgnvebdY/MtGtT4k8PvGz3CCa65\n" +
+        "GrqFT+U9J3kglKQn9zJeSZrVHAE7guatTZpYMaE3AgMBAAGjgZ4wgZswHQYDVR0O\n" +
+        "BBYEFJraQNM+W62lwqzcSEc6VjNXAaSaMB8GA1UdIwQYMBaAFPBYgi5QQCd4Bcl6\n" +
+        "53eKhqSZODfbMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMDgGCCsG\n" +
+        "AQUFBwEBBCwwKjAoBggrBgEFBQcwAYYcaHR0cDovL2ppYW4ub3N0YXBsZS5vcmc6\n" +
+        "NzEwMDANBgkqhkiG9w0BAQsFAAOCAgEANGiCKcoWKAs4rPU0k3zrDrp4/evgP/lC\n" +
+        "rz4b0OJqyZOEtB9pVgG+5pH2QvcP1WvUQRdEaYLExMd61bRJD9Kwx5FsF/wiFyTg\n" +
+        "w54AL1wzKy+01+OnDFoCHrMXltfimOPfeAmmM8s0Bmu7T2tIXQYij0LE+H2sE6Sa\n" +
+        "22uc8NfustH33raL8/gofIeScYzuBjRTzx126CQA2IUiIB8FEYXPcCoyIyLdU/lJ\n" +
+        "MI/STRpv9+uR6/oL+qre2HiBD8GiD/lhqha/MYCztChDv6vQEhFmEbvVZAoPhjHV\n" +
+        "rjdGcbe0U8sXOeTSh16Hyyv8Ijcf/5t7LIkt3TYCm6NmgB8wfNNyr/buY7Vm8Dmp\n" +
+        "K3jCxvuCzCchjBdslkEFGiLEYUPtU/Q0RdESWOkS4YgjLaWQdvnA1Xc4QyYCagrD\n" +
+        "HUZdZdF9BEeqfV/b9ctgicODS7274bpRfd52fqvA/6+UhfYLHioL/JfjODtjExcL\n" +
+        "CuiX3X/vC6CRQY+OZTqqYr5O27Bk1AbbC0IHgUldrRhnIN3tT8UfudZm0b0GDOku\n" +
+        "K33SELj6blXgT/sjqyW/DGmQTvLQ2O62PL+py6KXqKas5H9qm7BPV5wCbKObVSak\n" +
+        "o8svNicToC1Io5Od0ZraI3I8Oux4UvLtNQX9+D929njo6ai5Jfe6kAVGe+ldhfBJ\n" +
+        "BFDZL7ASduk=";
+
+    // Saturday, August 17, 2019 2:00:00 AM GMT
+    static final Date VALID_DATE = new Date(1566007200000L);
+
+    public static void main(String[] args) throws Exception {
+        CertificateFactory certFac = CertificateFactory.getInstance("X.509");
+        CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
+        X509Certificate goodGuyCert = getCert(certFac, GOOD_SERVER_PEM);
+        X509Certificate badGuyCert = getCert(certFac, BAD_SERVER_PEM);
+        X509Certificate intCACert = getCert(certFac, INT_CA_PEM);
+        X509Certificate rootCACert = getCert(certFac, ROOT_CA_PEM);
+        byte[] goodOcspDer = pemToDer(GOOD_GUY_OCSP_PEM);
+        byte[] badOcspDer = pemToDer(BAD_GUY_OCSP_PEM);
+        byte[] intCAOcspDer = pemToDer(INT_CA_OCSP_PEM);
+        Set<TrustAnchor> trustAnchors =
+                Set.of(new TrustAnchor(rootCACert, null));
+        PKIXRevocationChecker pkrc;
+        PKIXBuilderParameters pkixParams;
+
+        X509Certificate[] goodPath = { goodGuyCert, intCACert,
+            rootCACert };
+        X509Certificate[] badPath = { badGuyCert, intCACert,
+            rootCACert };
+
+        List<byte[]> goodResponses = List.of(goodOcspDer, intCAOcspDer);
+        List<byte[]> badResponses = List.of(badOcspDer, intCAOcspDer);
+
+        // Test 1: Path validation with revocation explicitly turned
+        // off, expected to pass.
+        pkixParams = new PKIXBuilderParameters(trustAnchors, null);
+        pkixParams.setRevocationEnabled(false);
+        validatePath(goodPath, Collections.emptyList(), pkixParams, null);
+
+        // Test 2: Path validation with revocation turned on using the
+        // good path.  Should fail due to no responses.
+        pkixParams = new PKIXBuilderParameters(trustAnchors, null);
+        pkixParams.setDate(VALID_DATE);
+        validatePath(goodPath, Collections.emptyList(), pkixParams,
+            new CertPathValidatorException("KABOOM! No OCSP Responses!", null,
+            certFac.generateCertPath(List.of(goodGuyCert, intCACert)), 1,
+            BasicReason.UNDETERMINED_REVOCATION_STATUS));
+
+        // Test 3: Path validation of the good path with revocation turned
+        // on and available valid OCSP responses delivered through the
+        // List<byte[]> rather than via the PKIXRevocationChecker.
+        pkixParams = new PKIXBuilderParameters(trustAnchors, null);
+        pkixParams.setDate(VALID_DATE);
+        pkrc = (PKIXRevocationChecker)cpv.getRevocationChecker();
+        pkixParams.addCertPathChecker(pkrc);
+        validatePath(goodPath, goodResponses, pkixParams, null);
+
+        // Test 4: Path validation of the bad path with revocation explicitly
+        // disabled and valid OCSP responses provided through the PKIXRevocationChecker
+        // indicating a revoked certificate.  Even with the
+        // setRevocationEnabled method set to false this should perform
+        // revocation checking and catch the revoked certificate.
+        pkixParams = new PKIXBuilderParameters(trustAnchors, null);
+        pkixParams.setDate(VALID_DATE);
+        pkixParams.setRevocationEnabled(false);
+        pkrc = (PKIXRevocationChecker)cpv.getRevocationChecker();
+        pkrc.setOcspResponses(Map.of(badGuyCert, badOcspDer,
+                intCACert, intCAOcspDer));
+        pkixParams.addCertPathChecker(pkrc);
+        validatePath(badPath, Collections.emptyList(), pkixParams,
+                new CertPathValidatorException("Ouch!", null,
+                certFac.generateCertPath(List.of(badGuyCert, intCACert)), 0,
+                BasicReason.REVOKED));
+
+        // Test 5: This is the same basic setup as test 4, but instead of
+        // delivering the OCSP responses via the PKIXRevocationChecker use
+        // the third parameter (List<byte[]>) for the Validator.validate()
+        // call.  Revocation checking should be performed.
+        pkixParams = new PKIXBuilderParameters(trustAnchors, null);
+        pkixParams.setDate(VALID_DATE);
+        pkixParams.setRevocationEnabled(false);
+        pkrc = (PKIXRevocationChecker)cpv.getRevocationChecker();
+        pkixParams.addCertPathChecker(pkrc);
+        validatePath(badPath, badResponses, pkixParams,
+                new CertPathValidatorException("Ouch!", null,
+                certFac.generateCertPath(List.of(badGuyCert, intCACert)), 0,
+                BasicReason.REVOKED));
+    }
+
+    static void validatePath(X509Certificate[] path, List<byte[]> responses,
+            PKIXBuilderParameters params, Exception expectedExc) {
+        try {
+            Validator val = Validator.getInstance(Validator.TYPE_PKIX,
+                    Validator.VAR_TLS_SERVER, params);
+            val.validate(path, null, responses, null, "RSA");
+            if (expectedExc != null) {
+                // We expected to receive an exception here
+                throw new RuntimeException("Did not receive expected " +
+                        expectedExc.getClass().getName());
+            }
+        } catch (CertificateException certExc) {
+            if (expectedExc == null) {
+                // This test was supposed to pass, so wrap it in a Runtime
+                throw new RuntimeException("Received unexpected exception: ",
+                        certExc);
+            } else {
+                Throwable cause = certExc.getCause();
+                if (cause == null) {
+                    throw new RuntimeException("Missing expected cause: " +
+                            expectedExc.getClass().getName(),
+                            certExc);
+                } else {
+                    verifyCause(cause, expectedExc);
+                }
+            }
+        }
+    }
+
+    static void verifyCause(Throwable cause, Throwable expectedExc) {
+        if (cause.getClass() != expectedExc.getClass()) {
+            throw new RuntimeException("Exception class mismatch: expected = " +
+                    expectedExc.getClass().getName() + ", actual = " +
+                    cause.getClass().getName());
+        } else if (cause instanceof CertPathValidatorException) {
+            CertPathValidatorException actual =
+                    (CertPathValidatorException)cause;
+            CertPathValidatorException expected =
+                    (CertPathValidatorException)expectedExc;
+            // The failure index and reason should be the same
+            if (actual.getIndex() != expected.getIndex() ||
+                    actual.getReason() != expected.getReason()) {
+                throw new RuntimeException("CertPathValidatorException " +
+                        "differs from expected.  Expected: index = " +
+                        expected.getIndex() + ", reason = " +
+                        expected.getReason() + ", Actual: index = " +
+                        actual.getIndex() + ", reason = " +
+                        actual.getReason(), actual);
+            }
+        }
+    }
+
+    static X509Certificate getCert(CertificateFactory fac, String pemCert) {
+        try {
+            ByteArrayInputStream bais =
+                    new ByteArrayInputStream(pemCert.getBytes("UTF-8"));
+            return (X509Certificate)fac.generateCertificate(bais);
+        } catch (UnsupportedEncodingException | CertificateException exc) {
+            throw new RuntimeException(exc);
+        }
+    }
+
+    static byte[] pemToDer(String pemData) {
+        Base64.Decoder b64Dec = Base64.getMimeDecoder();
+        return b64Dec.decode(pemData);
+    }
+}
--- a/test/jdk/tools/jlink/basic/BasicTest.java	Wed Aug 28 11:52:20 2019 -0400
+++ b/test/jdk/tools/jlink/basic/BasicTest.java	Wed Aug 28 11:58:56 2019 -0400
@@ -100,7 +100,6 @@
         runJmod(classes.toString(), TEST_MODULE, true);
         runJlink(image, TEST_MODULE, "--launcher", "bar=" + TEST_MODULE);
         execute(image, "bar");
-
         Files.delete(jmods.resolve(TEST_MODULE + ".jmod"));
 
         image = Paths.get("myimage2");
@@ -108,7 +107,28 @@
         // specify main class in --launcher command line
         runJlink(image, TEST_MODULE, "--launcher", "bar2=" + TEST_MODULE + "/jdk.test.Test");
         execute(image, "bar2");
+        Files.delete(jmods.resolve(TEST_MODULE + ".jmod"));
 
+        image = Paths.get("myadder");
+        runJmod(classes.toString(), TEST_MODULE, false /* no ModuleMainClass! */);
+        // specify main class in --launcher command line
+        runJlink(image, TEST_MODULE, "--launcher", "adder=" + TEST_MODULE + "/jdk.test.Adder");
+        addAndCheck(image, "adder");
+    }
+
+    private void addAndCheck(Path image, String scriptName) throws Throwable {
+        String cmd = image.resolve("bin").resolve(scriptName).toString();
+        OutputAnalyzer analyzer;
+        if (System.getProperty("os.name").startsWith("Windows")) {
+            analyzer = ProcessTools.executeProcess("sh.exe", cmd, "12", "8", "7", "--", "foo bar");
+        } else {
+            analyzer = ProcessTools.executeProcess(cmd, "12", "8", "7", "--", "foo bar");
+        }
+        if (analyzer.getExitValue() != 27) {
+            throw new AssertionError("Image invocation failed: expected 27, rc=" + analyzer.getExitValue());
+        }
+        // last argument contains space and should be properly quoted.
+        analyzer.stdoutShouldContain("Num args: 5");
     }
 
     private void execute(Path image, String scriptName) throws Throwable {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/tools/jlink/basic/src/test/jdk/test/Adder.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,45 @@
+/**
+ * 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 jdk.test;
+
+import java.util.Arrays;
+
+public class Adder {
+    public static void main(String[] args) {
+        System.out.println(Adder.class + " ...");
+        System.out.println("Num args: " + args.length);
+        System.out.println("args list: " + Arrays.asList(args));
+        int sum = 0;
+        // Only add arguments upto "--". The remaining argument(s) are for
+        // testing quoting.
+        for (String arg: args) {
+            System.out.println(arg);
+            if ("--".equals(arg)) {
+                break;
+            }
+            sum += Integer.parseInt(arg);
+        }
+        System.exit(sum); // checked by the test
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/reflect/Proxy/ProxyBench.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,93 @@
+/*
+ * 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.
+ *
+ * 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.lang.reflect.proxy;
+
+import org.openjdk.jmh.annotations.*;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Proxy;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+@Warmup(iterations = 5)
+@Measurement(iterations = 10)
+@Fork(value = 1)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ProxyBench {
+
+    /**
+     * On Dell T7610:
+     *
+     * Benchmark w/ -Djdk.proxy.ProxyGenerator.v49=true
+     * Benchmark                      Mode  Cnt   Score   Error  Units
+     * ProxyBench.getProxyClass1i     avgt   10  20.472 +/- 0.209  ns/op
+     * ProxyBench.getProxyClass4i     avgt   10  57.353 +/- 0.461  ns/op
+     * ProxyBench.newProxyInstance1i  avgt   10  31.459 +/- 0.516  ns/op
+     * ProxyBench.newProxyInstance4i  avgt   10  66.580 +/- 0.983  ns/op
+     *
+     * Benchmark                      Mode  Cnt   Score   Error  Units
+     * ProxyBench.getProxyClass1i     avgt   10  21.291 +/- 0.475  ns/op
+     * ProxyBench.getProxyClass4i     avgt   10  61.481 +/- 4.709  ns/op
+     * ProxyBench.newProxyInstance1i  avgt   10  30.177 +/- 0.761  ns/op
+     * ProxyBench.newProxyInstance4i  avgt   10  68.302 +/- 1.344  ns/op
+     */
+
+    interface PkgPrivate1 {
+        void m1();
+    }
+
+    interface PkgPrivate2 {
+        void m2();
+    }
+
+    static final InvocationHandler handler = (proxy, method, args) -> null;
+
+    static final ClassLoader loader1 = null;
+    static final Class<?>[] interfaces1 = {Runnable.class};
+
+    static final ClassLoader loader4 = PkgPrivate1.class.getClassLoader();
+    static final Class<?>[] interfaces4 = {Runnable.class, Callable.class,
+                                           PkgPrivate1.class, PkgPrivate2.class};
+
+    @Benchmark
+    public Class<?> getProxyClass1i() {
+        return Proxy.getProxyClass(loader1, interfaces1);
+    }
+
+    @Benchmark
+    public Class<?> getProxyClass4i() {
+        return Proxy.getProxyClass(loader4, interfaces4);
+    }
+
+    @Benchmark
+    public Object newProxyInstance1i() {
+        return Proxy.newProxyInstance(loader1, interfaces1, handler);
+    }
+
+    @Benchmark
+    public Object newProxyInstance4i() {
+        return Proxy.newProxyInstance(loader4, interfaces4, handler);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/micro/org/openjdk/bench/java/lang/reflect/Proxy/ProxyPerf.java	Wed Aug 28 11:58:56 2019 -0400
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ *
+ * 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.lang.reflect.proxy;
+
+import java.util.List;
+
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.CompilerControl;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.Measurement;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Warmup;
+
+import org.openjdk.jmh.infra.Blackhole;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmark measuring java.lang.reflect.ProxyGenerator.generateProxyClass.
+ * It bypasses the cache of proxies to measure the time to construct a proxy.
+ */
+@Warmup(iterations = 5)
+@Measurement(iterations = 10)
+@Fork(value = 1)
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+public class ProxyPerf {
+
+    /**
+     * Sample results from a Dell T7610.
+     * Benchmark                        Mode  Cnt      Score      Error  Units
+     *      ProxyPerf.genIntf_1              avgt   10  35325.428 +/-  780.459  ns/op
+     *      ProxyPerf.genIntf_1_V49          avgt   10  34309.423 +/-  727.188  ns/op
+     *      ProxyPerf.genStringsIntf_3       avgt   10  46600.366 +/-  663.812  ns/op
+     *      ProxyPerf.genStringsIntf_3_V49   avgt   10  45911.817 +/- 1598.536  ns/op
+     *      ProxyPerf.genZeroParams          avgt   10  33245.048 +/-  437.988  ns/op
+     *      ProxyPerf.genZeroParams_V49      avgt   10  32954.254 +/- 1041.932  ns/op
+     *      ProxyPerf.getPrimsIntf_2         avgt   10  43987.819 +/-  837.443  ns/op
+     *      ProxyPerf.getPrimsIntf_2_V49     avgt   10  42863.462 +/- 1193.480  ns/op
+     */
+
+    public interface Intf_1 {
+        public Object mL(Object o);
+    }
+
+    public interface Intf_2 {
+        public int m1I(int i);
+        public long m2IJ(int i, long l);
+    }
+
+    public interface Intf_3 {
+        public void mString(String s1);
+        public String m2String(String s1);
+        public String m2String(String s1, String s2);
+    }
+
+    private InvocationHandler handler;
+    private ClassLoader classloader;
+    private Method proxyGen;
+    private Method proxyGenV49;
+
+    @Setup
+    public void setup() {
+        try {
+            handler = (Object proxy, Method method, Object[] args) -> null;
+            classloader = ClassLoader.getSystemClassLoader();
+            Class<?> proxyGenClass = Class.forName("java.lang.reflect.ProxyGenerator");
+            proxyGen = proxyGenClass.getDeclaredMethod("generateProxyClass",
+                    ClassLoader.class, String.class, java.util.List.class, int.class);
+            proxyGen.setAccessible(true);
+
+            // Init access to the old Proxy generator
+            Class<?> proxyGenClassV49 = Class.forName("java.lang.reflect.ProxyGenerator_v49");
+            proxyGenV49 = proxyGenClassV49.getDeclaredMethod("generateProxyClass",
+                    String.class, java.util.List.class, int.class);
+            proxyGenV49.setAccessible(true);
+
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            throw new RuntimeException("ProxyClass setup fails", ex);
+        }
+    }
+
+    @Benchmark
+    public void genZeroParams(Blackhole bh) throws Exception {
+        List<Class<?>> interfaces = List.of(Runnable.class);
+        bh.consume(proxyGen.invoke(null, classloader, "ProxyImpl", interfaces, 1));
+    }
+
+    @Benchmark
+    public void genIntf_1(Blackhole bh) throws Exception {
+        List<Class<?>> interfaces = List.of(Intf_1.class);
+        bh.consume(proxyGen.invoke(null, classloader, "ProxyImpl", interfaces, 1));
+    }
+
+    @Benchmark
+    public void getPrimsIntf_2(Blackhole bh) throws Exception {
+        List<Class<?>> interfaces = List.of(Intf_2.class);
+        bh.consume(proxyGen.invoke(null, classloader, "ProxyImpl", interfaces, 1));
+    }
+    @Benchmark
+    public void genStringsIntf_3(Blackhole bh) throws Exception {
+        List<Class<?>> interfaces = List.of(Intf_3.class);
+        bh.consume(proxyGen.invoke(null, classloader, "ProxyImpl", interfaces, 1));
+    }
+
+    // Generate using the V49inal generator for comparison
+
+    @Benchmark
+    public void genZeroParams_V49(Blackhole bh) throws Exception {
+        List<Class<?>> interfaces = List.of(Runnable.class);
+        bh.consume(proxyGenV49.invoke(null, "ProxyImpl", interfaces, 1));
+    }
+
+    @Benchmark
+    public void genIntf_1_V49(Blackhole bh) throws Exception {
+        List<Class<?>> interfaces = List.of(Intf_1.class);
+        bh.consume(proxyGenV49.invoke(null, "ProxyImpl", interfaces, 1));
+    }
+
+    @Benchmark
+    public void getPrimsIntf_2_V49(Blackhole bh) throws Exception {
+        List<Class<?>> interfaces = List.of(Intf_2.class);
+        bh.consume(proxyGenV49.invoke(null, "ProxyImpl", interfaces, 1));
+    }
+    @Benchmark
+    public void genStringsIntf_3_V49(Blackhole bh) throws Exception {
+        List<Class<?>> interfaces = List.of(Intf_3.class);
+        bh.consume(proxyGenV49.invoke(null, "ProxyImpl", interfaces, 1));
+    }
+
+}