diff --git a/.jcheck/conf b/.jcheck/conf
index 49d527e3b81..01cc62ca93b 100644
--- a/.jcheck/conf
+++ b/.jcheck/conf
@@ -27,11 +27,32 @@ repository=amber
 jbs=jdk
 
 [checks]
-error=author,committer,whitespace,executable,symlink
+error=author,committer,reviewers,merge,issues,executable,symlink,message,hg-tag,whitespace,problemlists
+
+[repository]
+tags=(?:jdk-(?:[1-9]([0-9]*)(?:\.(?:0|[1-9][0-9]*)){0,4})(?:\+(?:(?:[0-9]+))|(?:-ga)))|(?:jdk[4-9](?:u\d{1,3})?-(?:(?:b\d{2,3})|(?:ga)))|(?:hs\d\d(?:\.\d{1,2})?-b\d\d)
+branches=
 
 [census]
 version=0
 domain=openjdk.org
 
 [checks "whitespace"]
-files=.*\.cpp|.*\.hpp|.*\.c|.*\.h|.*\.java
+files=.*\.cpp|.*\.hpp|.*\.c|.*\.h|.*\.java|.*\.cc|.*\.hh|.*\.m|.*\.mm
+
+[checks "merge"]
+message=Merge
+
+[checks "reviewers"]
+reviewers=1
+ignore=duke
+
+[checks "committer"]
+role=committer
+
+[checks "issues"]
+pattern=^([124-8][0-9]{6}): (\S.*)$
+
+
+[checks "problemlists"]
+dirs=test/jdk|test/langtools|test/lib-test|test/hotspot/jtreg|test/jaxp
diff --git a/make/hotspot/lib/JvmFeatures.gmk b/make/hotspot/lib/JvmFeatures.gmk
index 17964d84f2c..3647806e1d7 100644
--- a/make/hotspot/lib/JvmFeatures.gmk
+++ b/make/hotspot/lib/JvmFeatures.gmk
@@ -119,7 +119,9 @@ ifneq ($(call check-jvm-feature, cds), true)
       archiveBuilder.cpp \
       archiveUtils.cpp \
       classListParser.cpp \
+      classLoaderDataShared.cpp \
       classLoaderExt.cpp \
+      cppVtables.cpp \
       dumpAllocStats.cpp \
       dynamicArchive.cpp \
       filemap.cpp \
diff --git a/make/hotspot/symbols/symbols-unix b/make/hotspot/symbols/symbols-unix
index b462929c02e..de444eae41c 100644
--- a/make/hotspot/symbols/symbols-unix
+++ b/make/hotspot/symbols/symbols-unix
@@ -198,5 +198,6 @@ JVM_AddModuleExports
 JVM_AddModuleExportsToAll
 JVM_AddModuleExportsToAllUnnamed
 JVM_AddReadsModule
+JVM_DefineArchivedModules
 JVM_DefineModule
 JVM_SetBootLoaderUnnamedModule
diff --git a/make/scripts/generate-symbol-data.sh b/make/scripts/generate-symbol-data.sh
index 3ce684041dc..56aa8016dd6 100644
--- a/make/scripts/generate-symbol-data.sh
+++ b/make/scripts/generate-symbol-data.sh
@@ -63,7 +63,7 @@ if [ ! -f symbols ] ; then
     exit 1
 fi;
 
-if [ "`hg status .`x" != "x" ] ; then
+if [ "`git status --porcelain=v1 .`x" != "x" ] ; then
     echo "The make/data/symbols directory contains local changes!" >&2
     exit 1
 fi;
diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad
index fb9929e2f97..5970a898bf2 100644
--- a/src/hotspot/cpu/aarch64/aarch64.ad
+++ b/src/hotspot/cpu/aarch64/aarch64.ad
@@ -614,8 +614,8 @@ alloc_class chunk3(RFLAGS);
 // Several register classes are automatically defined based upon information in
 // this architecture description.
 // 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
-// 2) reg_class compiler_method_oop_reg    ( /* as def'd in frame section */ )
-// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
+// 2) reg_class compiler_method_reg        ( /* as def'd in frame section */ )
+// 2) reg_class interpreter_method_reg     ( /* as def'd in frame section */ )
 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
 //
 
@@ -2410,12 +2410,6 @@ const int Matcher::float_pressure(int default_pressure_threshold) {
   return default_pressure_threshold;
 }
 
-int Matcher::regnum_to_fpu_offset(int regnum)
-{
-  Unimplemented();
-  return 0;
-}
-
 // Is this branch offset short enough that a short branch can be used?
 //
 // NOTE: If the platform does not provide any short branch variants, then
@@ -4043,17 +4037,14 @@ encode %{
 //         SP meets the minimum alignment.
 
 frame %{
-  // What direction does stack grow in (assumed to be same for C & Java)
-  stack_direction(TOWARDS_LOW);
-
   // These three registers define part of the calling convention
   // between compiled code and the interpreter.
 
   // Inline Cache Register or Method for I2C.
   inline_cache_reg(R12);
 
-  // Method Oop Register when calling interpreter.
-  interpreter_method_oop_reg(R12);
+  // Method Register when calling interpreter.
+  interpreter_method_reg(R12);
 
   // Number of stack slots consumed by locking an object
   sync_stack_slots(2);
@@ -5622,9 +5613,9 @@ operand inline_cache_RegP(iRegP reg)
   interface(REG_INTER);
 %}
 
-operand interpreter_method_oop_RegP(iRegP reg)
+operand interpreter_method_RegP(iRegP reg)
 %{
-  constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_oop_reg
+  constraint(ALLOC_IN_RC(method_reg)); // interpreter_method_reg
   match(reg);
   match(iRegPNoSp);
   op_cost(0);
diff --git a/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp b/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp
index 4ab358a23de..99b213ddab4 100644
--- a/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/gc/shared/barrierSetNMethod_aarch64.cpp
@@ -101,7 +101,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
 
   frame_pointers_t *new_frame = (frame_pointers_t *)(return_address_ptr - 5);
 
-  JavaThread *thread = (JavaThread*)Thread::current();
+  JavaThread *thread = JavaThread::current();
   RegisterMap reg_map(thread, false);
   frame frame = thread->last_frame();
 
@@ -111,14 +111,11 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
 
   LogTarget(Trace, nmethod, barrier) out;
   if (out.is_enabled()) {
-    Thread* thread = Thread::current();
-    assert(thread->is_Java_thread(), "must be JavaThread");
-    JavaThread* jth = (JavaThread*) thread;
     ResourceMark mark;
     log_trace(nmethod, barrier)("deoptimize(nmethod: %s(%p), return_addr: %p, osr: %d, thread: %p(%s), making rsp: %p) -> %p",
                                 nm->method()->name_and_sig_as_C_string(),
-                                nm, *(address *) return_address_ptr, nm->is_osr_method(), jth,
-                                jth->get_thread_name(), frame.sp(), nm->verified_entry_point());
+                                nm, *(address *) return_address_ptr, nm->is_osr_method(), thread,
+                                thread->get_thread_name(), frame.sp(), nm->verified_entry_point());
   }
 
   new_frame->sp = frame.sp();
diff --git a/src/hotspot/cpu/aarch64/globals_aarch64.hpp b/src/hotspot/cpu/aarch64/globals_aarch64.hpp
index 90e76e507e8..294b6b13495 100644
--- a/src/hotspot/cpu/aarch64/globals_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/globals_aarch64.hpp
@@ -75,13 +75,11 @@ define_pd_global(intx, InitArrayShortSize, BytesPerLong);
 define_pd_global(intx, InlineSmallCode,          1000);
 #endif
 
-#define ARCH_FLAGS(develop, \
-                   product, \
-                   diagnostic, \
-                   experimental, \
-                   notproduct, \
-                   range, \
-                   constraint) \
+#define ARCH_FLAGS(develop,                                             \
+                   product,                                             \
+                   notproduct,                                          \
+                   range,                                               \
+                   constraint)                                          \
                                                                         \
   product(bool, NearCpool, true,                                        \
          "constant pool is close to instructions")                      \
@@ -113,4 +111,6 @@ define_pd_global(intx, InlineSmallCode,          1000);
           "Value -1 means off.")                                        \
           range(-1, 4096)
 
+// end of ARCH_FLAGS
+
 #endif // CPU_AARCH64_GLOBALS_AARCH64_HPP
diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
index 3cbf025b0c7..decc17d1958 100644
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.cpp
@@ -28,6 +28,7 @@
 #include "asm/macroAssembler.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/arguments.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
diff --git a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
index 9870b24ecb5..5dde5e89946 100644
--- a/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
+++ b/src/hotspot/cpu/aarch64/vm_version_aarch64.hpp
@@ -27,7 +27,6 @@
 #define CPU_AARCH64_VM_VERSION_AARCH64_HPP
 
 #include "runtime/abstract_vm_version.hpp"
-#include "runtime/globals_extension.hpp"
 #include "utilities/sizes.hpp"
 
 class VM_Version : public Abstract_VM_Version {
diff --git a/src/hotspot/cpu/arm/arm.ad b/src/hotspot/cpu/arm/arm.ad
index d0a82e4176a..4c237673181 100644
--- a/src/hotspot/cpu/arm/arm.ad
+++ b/src/hotspot/cpu/arm/arm.ad
@@ -997,10 +997,6 @@ const int Matcher::float_pressure(int default_pressure_threshold) {
   return default_pressure_threshold;
 }
 
-int Matcher::regnum_to_fpu_offset(int regnum) {
-  return regnum - 32; // The FP registers are in the second chunk
-}
-
 // Vector width in bytes
 const int Matcher::vector_width_in_bytes(BasicType bt) {
   return MaxVectorSize;
@@ -1664,13 +1660,10 @@ encode %{
 //         the region from SP to FP meets the minimum stack alignment.
 
 frame %{
-  // What direction does stack grow in (assumed to be same for native & Java)
-  stack_direction(TOWARDS_LOW);
-
   // These two registers define part of the calling convention
   // between compiled code and the interpreter.
   inline_cache_reg(R_Ricklass);          // Inline Cache Register or Method* for I2C
-  interpreter_method_oop_reg(R_Rmethod); // Method Oop Register when calling interpreter
+  interpreter_method_reg(R_Rmethod);     // Method Register when calling interpreter
 
   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
   cisc_spilling_operand_name(indOffset);
@@ -2530,7 +2523,7 @@ operand inline_cache_regP(iRegP reg) %{
   interface(REG_INTER);
 %}
 
-operand interpreter_method_oop_regP(iRegP reg) %{
+operand interpreter_method_regP(iRegP reg) %{
   constraint(ALLOC_IN_RC(Rmethod_regP));
   match(reg);
   format %{ %}
diff --git a/src/hotspot/cpu/arm/arm_32.ad b/src/hotspot/cpu/arm/arm_32.ad
index 1767f69a287..177c1a7cae0 100644
--- a/src/hotspot/cpu/arm/arm_32.ad
+++ b/src/hotspot/cpu/arm/arm_32.ad
@@ -196,7 +196,7 @@ alloc_class chunk2(APSR, FPSCR);
 // Several register classes are automatically defined based upon information in
 // this architecture description.
 // 1) reg_class inline_cache_reg           ( as defined in frame section )
-// 2) reg_class interpreter_method_oop_reg ( as defined in frame section )
+// 2) reg_class interpreter_method_reg     ( as defined in frame section )
 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
 //
 
diff --git a/src/hotspot/cpu/arm/globals_arm.hpp b/src/hotspot/cpu/arm/globals_arm.hpp
index bbc38662a53..7390729430b 100644
--- a/src/hotspot/cpu/arm/globals_arm.hpp
+++ b/src/hotspot/cpu/arm/globals_arm.hpp
@@ -70,11 +70,12 @@ define_pd_global(bool, CompactStrings, false);
 
 define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
 
-#define ARCH_FLAGS(develop, \
-                   product, \
-                   diagnostic, \
-                   experimental, \
-                   notproduct, \
-                   range, \
+#define ARCH_FLAGS(develop,     \
+                   product,     \
+                   notproduct,  \
+                   range,       \
                    constraint)
+
+// end of ARCH_FLAGS
+
 #endif // CPU_ARM_GLOBALS_ARM_HPP
diff --git a/src/hotspot/cpu/arm/vm_version_arm_32.cpp b/src/hotspot/cpu/arm/vm_version_arm_32.cpp
index 6837187d2d5..5331a20f2fe 100644
--- a/src/hotspot/cpu/arm/vm_version_arm_32.cpp
+++ b/src/hotspot/cpu/arm/vm_version_arm_32.cpp
@@ -27,6 +27,7 @@
 #include "asm/macroAssembler.inline.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/arguments.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/stubCodeGenerator.hpp"
diff --git a/src/hotspot/cpu/ppc/c2_init_ppc.cpp b/src/hotspot/cpu/ppc/c2_init_ppc.cpp
index fdf4062728c..34b330fee2b 100644
--- a/src/hotspot/cpu/ppc/c2_init_ppc.cpp
+++ b/src/hotspot/cpu/ppc/c2_init_ppc.cpp
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
+ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 #include "opto/compile.hpp"
 #include "opto/node.hpp"
 #include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
 #include "utilities/debug.hpp"
 
 // Processor dependent initialization of C2 compiler for ppc.
@@ -40,12 +41,6 @@ void Compile::pd_compiler2_init() {
     }
   }
 
-  if (PowerArchitecturePPC64 == 6) {
-    if (FLAG_IS_DEFAULT(InsertEndGroupPPC64)) {
-      FLAG_SET_ERGO(InsertEndGroupPPC64, true);
-    }
-  }
-
   if (!VM_Version::has_isel() && FLAG_IS_DEFAULT(ConditionalMoveLimit)) {
     FLAG_SET_ERGO(ConditionalMoveLimit, 0);
   }
diff --git a/src/hotspot/cpu/ppc/globals_ppc.hpp b/src/hotspot/cpu/ppc/globals_ppc.hpp
index 0d546b329df..ccc3ffaa9f2 100644
--- a/src/hotspot/cpu/ppc/globals_ppc.hpp
+++ b/src/hotspot/cpu/ppc/globals_ppc.hpp
@@ -75,13 +75,11 @@ define_pd_global(bool, CompactStrings, true);
 define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong);
 
 // Platform dependent flag handling: flags only defined on this platform.
-#define ARCH_FLAGS(develop,      \
-                   product,      \
-                   diagnostic,   \
-                   experimental, \
-                   notproduct,   \
-                   range,        \
-                   constraint)   \
+#define ARCH_FLAGS(develop,                                                 \
+                   product,                                                 \
+                   notproduct,                                              \
+                   range,                                                   \
+                   constraint)                                              \
                                                                             \
   product(uintx, PowerArchitecturePPC64, 0,                                 \
           "Specify the PowerPC family version in use. If not provided, "    \
@@ -136,12 +134,6 @@ define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong);
   product(bool, UseStaticBranchPredictionForUncommonPathsPPC64, false,      \
           "Use static branch prediction hints for uncommon paths.")         \
                                                                             \
-  product(bool, UsePower6SchedulerPPC64, false,                             \
-          "Use Power6 Scheduler.")                                          \
-                                                                            \
-  product(bool, InsertEndGroupPPC64, false,                                 \
-          "Insert EndGroup instructions to optimize for Power6.")           \
-                                                                            \
   /* Trap based checks. */                                                  \
   /* Trap based checks use the ppc trap instructions to check certain */    \
   /* conditions. This instruction raises a SIGTRAP caught by the      */    \
@@ -161,7 +153,7 @@ define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong);
   product(bool, UseRTMLocking, false,                                       \
           "Enable RTM lock eliding for inflated locks in compiled code")    \
                                                                             \
-  experimental(bool, UseRTMForStackLocks, false,                            \
+  product(bool, UseRTMForStackLocks, false, EXPERIMENTAL,                   \
           "Enable RTM lock eliding for stack locks in compiled code")       \
                                                                             \
   product(bool, UseRTMDeopt, false,                                         \
@@ -171,33 +163,35 @@ define_pd_global(intx, InitArrayShortSize, 9*BytesPerLong);
           "Number of RTM retries on lock abort or busy")                    \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(int, RTMSpinLoopCount, 100,                                  \
+  product(int, RTMSpinLoopCount, 100, EXPERIMENTAL,                         \
           "Spin count for lock to become free before RTM retry")            \
           range(0, 32767) /* immediate operand limit on ppc */              \
                                                                             \
-  experimental(int, RTMAbortThreshold, 1000,                                \
+  product(int, RTMAbortThreshold, 1000, EXPERIMENTAL,                       \
           "Calculate abort ratio after this number of aborts")              \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(int, RTMLockingThreshold, 10000,                             \
+  product(int, RTMLockingThreshold, 10000, EXPERIMENTAL,                    \
           "Lock count at which to do RTM lock eliding without "             \
           "abort ratio calculation")                                        \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(int, RTMAbortRatio, 50,                                      \
+  product(int, RTMAbortRatio, 50, EXPERIMENTAL,                             \
           "Lock abort ratio at which to stop use RTM lock eliding")         \
           range(0, 100) /* natural range */                                 \
                                                                             \
-  experimental(int, RTMTotalCountIncrRate, 64,                              \
+  product(int, RTMTotalCountIncrRate, 64, EXPERIMENTAL,                     \
           "Increment total RTM attempted lock count once every n times")    \
           range(1, 32767) /* immediate operand limit on ppc */              \
           constraint(RTMTotalCountIncrRateConstraintFunc,AfterErgo)         \
                                                                             \
-  experimental(intx, RTMLockingCalculationDelay, 0,                         \
+  product(intx, RTMLockingCalculationDelay, 0, EXPERIMENTAL,                \
           "Number of milliseconds to wait before start calculating aborts " \
           "for RTM locking")                                                \
                                                                             \
-  experimental(bool, UseRTMXendForLockBusy, true,                           \
-          "Use RTM Xend instead of Xabort when lock busy")                  \
+  product(bool, UseRTMXendForLockBusy, true, EXPERIMENTAL,                  \
+          "Use RTM Xend instead of Xabort when lock busy")
+
+// end of ARCH_FLAGS
 
 #endif // CPU_PPC_GLOBALS_PPC_HPP
diff --git a/src/hotspot/cpu/ppc/ppc.ad b/src/hotspot/cpu/ppc/ppc.ad
index 0258118af9b..e504b0ce62c 100644
--- a/src/hotspot/cpu/ppc/ppc.ad
+++ b/src/hotspot/cpu/ppc/ppc.ad
@@ -535,8 +535,8 @@ alloc_class chunk4 (
 // information in this architecture description.
 
 // 1) reg_class inline_cache_reg           ( as defined in frame section )
-// 2) reg_class compiler_method_oop_reg    ( as defined in frame section )
-// 2) reg_class interpreter_method_oop_reg ( as defined in frame section )
+// 2) reg_class compiler_method_reg        ( as defined in frame section )
+// 2) reg_class interpreter_method_reg     ( as defined in frame section )
 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
 //
 
@@ -1370,31 +1370,6 @@ void MachPrologNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
 }
 #endif
 
-// Macro used instead of the common __ to emulate the pipes of PPC.
-// Instead of e.g. __ ld(...) one hase to write ___(ld) ld(...) This enables the
-// micro scheduler to cope with "hand written" assembler like in the prolog. Though
-// still no scheduling of this code is possible, the micro scheduler is aware of the
-// code and can update its internal data. The following mechanism is used to achieve this:
-// The micro scheduler calls size() of each compound node during scheduling. size() does a
-// dummy emit and only during this dummy emit C->hb_scheduling() is not NULL.
-#if 0 // TODO: PPC port
-#define ___(op) if (UsePower6SchedulerPPC64 && C->hb_scheduling())                    \
-                  C->hb_scheduling()->_pdScheduling->PdEmulatePipe(ppc64Opcode_##op); \
-                _masm.
-#define ___stop if (UsePower6SchedulerPPC64 && C->hb_scheduling())                    \
-                  C->hb_scheduling()->_pdScheduling->PdEmulatePipe(archOpcode_none)
-#define ___advance if (UsePower6SchedulerPPC64 && C->hb_scheduling())                 \
-                  C->hb_scheduling()->_pdScheduling->advance_offset
-#else
-#define ___(op) if (UsePower6SchedulerPPC64)                                          \
-                  Unimplemented();                                                    \
-                _masm.
-#define ___stop if (UsePower6SchedulerPPC64)                                          \
-                  Unimplemented()
-#define ___advance if (UsePower6SchedulerPPC64)                                       \
-                  Unimplemented()
-#endif
-
 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
   Compile* C = ra_->C;
   C2_MacroAssembler _masm(&cbuf);
@@ -1414,10 +1389,10 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
     // Add nop at beginning of all frameless methods to prevent any
     // oop instructions from getting overwritten by make_not_entrant
     // (patching attempt would fail).
-    ___(nop) nop();
+    __ nop();
   } else {
     // Get return pc.
-    ___(mflr) mflr(return_pc);
+    __ mflr(return_pc);
   }
 
   if (C->clinit_barrier_on_entry()) {
@@ -1477,9 +1452,9 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
       if (Assembler::is_simm(stdoffset, 16)) {
         // Signed 16 bit offset, a simple std is ok.
         if (UseLoadInstructionsForStackBangingPPC64) {
-          ___(ld) ld(R0,  (int)(signed short)stdoffset, R1_SP);
+          __ ld(R0,  (int)(signed short)stdoffset, R1_SP);
         } else {
-          ___(std) std(R0, (int)(signed short)stdoffset, R1_SP);
+          __ std(R0, (int)(signed short)stdoffset, R1_SP);
         }
       } else if (Assembler::is_simm(stdoffset, 31)) {
         // Use largeoffset calculations for addis & ld/std.
@@ -1487,11 +1462,11 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
         const int lo = MacroAssembler::largeoffset_si16_si16_lo(stdoffset);
 
         Register tmp = R11;
-        ___(addis) addis(tmp, R1_SP, hi);
+        __ addis(tmp, R1_SP, hi);
         if (UseLoadInstructionsForStackBangingPPC64) {
-          ___(ld) ld(R0, lo, tmp);
+          __ ld(R0, lo, tmp);
         } else {
-          ___(std) std(R0, lo, tmp);
+          __ std(R0, lo, tmp);
         }
       } else {
         ShouldNotReachHere();
@@ -1506,19 +1481,9 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
   long offset = Assembler::align_addr(bytes, frame::alignment_in_bytes);
   ciMethod *currMethod = C->method();
 
-  // Optimized version for most common case.
-  if (UsePower6SchedulerPPC64 &&
-      !method_is_frameless && Assembler::is_simm((int)(-offset), 16) &&
-      !(false /* ConstantsALot TODO: PPC port*/)) {
-    ___(or) mr(callers_sp, R1_SP);
-    ___(std) std(return_pc, _abi(lr), R1_SP);
-    ___(stdu) stdu(R1_SP, -offset, R1_SP);
-    return;
-  }
-
   if (!method_is_frameless) {
     // Get callers sp.
-    ___(or) mr(callers_sp, R1_SP);
+    __ mr(callers_sp, R1_SP);
 
     // Push method's frame, modifies SP.
     assert(Assembler::is_uimm(framesize, 32U), "wrong type");
@@ -1527,17 +1492,17 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
     Register tmp = push_frame_temp;
     // Had to insert code of push_frame((unsigned int)framesize, push_frame_temp).
     if (Assembler::is_simm(-offset, 16)) {
-      ___(stdu) stdu(R1_SP, -offset, R1_SP);
+      __ stdu(R1_SP, -offset, R1_SP);
     } else {
       long x = -offset;
       // Had to insert load_const(tmp, -offset).
-      ___(addis)  lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16)));
-      ___(ori)    ori( tmp, tmp, ((x >> 32) & 0x0000ffff));
-      ___(rldicr) sldi(tmp, tmp, 32);
-      ___(oris)   oris(tmp, tmp, (x & 0xffff0000) >> 16);
-      ___(ori)    ori( tmp, tmp, (x & 0x0000ffff));
+      __ lis( tmp, (int)((signed short)(((x >> 32) & 0xffff0000) >> 16)));
+      __ ori( tmp, tmp, ((x >> 32) & 0x0000ffff));
+      __ sldi(tmp, tmp, 32);
+      __ oris(tmp, tmp, (x & 0xffff0000) >> 16);
+      __ ori( tmp, tmp, (x & 0x0000ffff));
 
-      ___(stdux) stdux(R1_SP, R1_SP, tmp);
+      __ stdux(R1_SP, R1_SP, tmp);
     }
   }
 #if 0 // TODO: PPC port
@@ -1552,14 +1517,11 @@ void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
 #endif
   if (!method_is_frameless) {
     // Save return pc.
-    ___(std) std(return_pc, _abi(lr), callers_sp);
+    __ std(return_pc, _abi(lr), callers_sp);
   }
 
   C->output()->set_frame_complete(cbuf.insts_size());
 }
-#undef ___
-#undef ___stop
-#undef ___advance
 
 uint MachPrologNode::size(PhaseRegAlloc *ra_) const {
   // Variable size. determine dynamically.
@@ -1641,35 +1603,6 @@ const Pipeline * MachEpilogNode::pipeline() const {
   return MachNode::pipeline_class();
 }
 
-#if 0 // TODO: PPC port
-void MachLoadPollAddrLateNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {
-  C2_MacroAssembler _masm(&cbuf);
-  if (LoadPollAddressFromThread) {
-    _masm.ld(R11, in_bytes(JavaThread::poll_address_offset()), R16_thread);
-  } else {
-    _masm.nop();
-  }
-}
-
-uint MachLoadPollAddrLateNode::size(PhaseRegAlloc* ra_) const {
-  if (LoadPollAddressFromThread) {
-    return 4;
-  } else {
-    return 4;
-  }
-}
-
-#ifndef PRODUCT
-void MachLoadPollAddrLateNode::format(PhaseRegAlloc* ra_, outputStream* st) const {
-  st->print_cr(" LD R11, PollAddressOffset, R16_thread \t// LoadPollAddressFromThread");
-}
-#endif
-
-const RegMask &MachLoadPollAddrLateNode::out_RegMask() const {
-  return RSCRATCH1_BITS64_REG_mask();
-}
-#endif // PPC port
-
 // =============================================================================
 
 // Figure out which register class each belongs in: rc_int, rc_float, rc_vs or
@@ -1952,102 +1885,6 @@ uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
   return implementation(NULL, ra_, true, NULL);
 }
 
-#if 0 // TODO: PPC port
-ArchOpcode MachSpillCopyNode_archOpcode(MachSpillCopyNode *n, PhaseRegAlloc *ra_) {
-#ifndef PRODUCT
-  if (ra_->node_regs_max_index() == 0) return archOpcode_undefined;
-#endif
-  assert(ra_->node_regs_max_index() != 0, "");
-
-  // Get registers to move.
-  OptoReg::Name src_hi = ra_->get_reg_second(n->in(1));
-  OptoReg::Name src_lo = ra_->get_reg_first(n->in(1));
-  OptoReg::Name dst_hi = ra_->get_reg_second(n);
-  OptoReg::Name dst_lo = ra_->get_reg_first(n);
-
-  enum RC src_lo_rc = rc_class(src_lo);
-  enum RC dst_lo_rc = rc_class(dst_lo);
-
-  if (src_lo == dst_lo && src_hi == dst_hi)
-    return ppc64Opcode_none;            // Self copy, no move.
-
-  // --------------------------------------
-  // Memory->Memory Spill. Use R0 to hold the value.
-  if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) {
-    return ppc64Opcode_compound;
-  }
-
-  // --------------------------------------
-  // Check for float->int copy; requires a trip through memory.
-  if (src_lo_rc == rc_float && dst_lo_rc == rc_int) {
-    Unimplemented();
-  }
-
-  // --------------------------------------
-  // Check for integer reg-reg copy.
-  if (src_lo_rc == rc_int && dst_lo_rc == rc_int) {
-    Register Rsrc = as_Register(Matcher::_regEncode[src_lo]);
-    Register Rdst = as_Register(Matcher::_regEncode[dst_lo]);
-    if (Rsrc == Rdst) {
-      return ppc64Opcode_none;
-    } else {
-      return ppc64Opcode_or;
-    }
-  }
-
-  // Check for integer store.
-  if (src_lo_rc == rc_int && dst_lo_rc == rc_stack) {
-    if (src_hi != OptoReg::Bad) {
-      return ppc64Opcode_std;
-    } else {
-      return ppc64Opcode_stw;
-    }
-  }
-
-  // Check for integer load.
-  if (dst_lo_rc == rc_int && src_lo_rc == rc_stack) {
-    if (src_hi != OptoReg::Bad) {
-      return ppc64Opcode_ld;
-    } else {
-      return ppc64Opcode_lwz;
-    }
-  }
-
-  // Check for float reg-reg copy.
-  if (src_lo_rc == rc_float && dst_lo_rc == rc_float) {
-    return ppc64Opcode_fmr;
-  }
-
-  // Check for float store.
-  if (src_lo_rc == rc_float && dst_lo_rc == rc_stack) {
-    if (src_hi != OptoReg::Bad) {
-      return ppc64Opcode_stfd;
-    } else {
-      return ppc64Opcode_stfs;
-    }
-  }
-
-  // Check for float load.
-  if (dst_lo_rc == rc_float && src_lo_rc == rc_stack) {
-    if (src_hi != OptoReg::Bad) {
-      return ppc64Opcode_lfd;
-    } else {
-      return ppc64Opcode_lfs;
-    }
-  }
-
-  // --------------------------------------------------------------------
-  // Check for hi bits still needing moving. Only happens for misaligned
-  // arguments to native calls.
-  if (src_hi == dst_hi) {
-    return ppc64Opcode_none;               // Self copy; no move.
-  }
-
-  ShouldNotReachHere();
-  return ppc64Opcode_undefined;
-}
-#endif // PPC port
-
 #ifndef PRODUCT
 void MachNopNode::format(PhaseRegAlloc *ra_, outputStream *st) const {
   st->print("NOP \t// %d nops to pad for loops.", _count);
@@ -2143,13 +1980,6 @@ void MachUEPNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
   // Argument is valid and klass is as expected, continue.
 }
 
-#if 0 // TODO: PPC port
-// Optimize UEP code on z (save a load_const() call in main path).
-int MachUEPNode::ep_offset() {
-  return 0;
-}
-#endif
-
 uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
   // Variable size. Determine dynamically.
   return MachNode::size(ra_);
@@ -2335,12 +2165,6 @@ const int Matcher::float_pressure(int default_pressure_threshold) {
   return default_pressure_threshold;
 }
 
-int Matcher::regnum_to_fpu_offset(int regnum) {
-  // No user for this method?
-  Unimplemented();
-  return 999;
-}
-
 const bool Matcher::convL2FSupported(void) {
   // fcfids can do the conversion (>= Power7).
   // fcfid + frsp showed rounding problem when result should be 0x3f800001.
@@ -2678,23 +2502,19 @@ const bool Matcher::convi2l_type_required = true;
 // needs for encoding need to be specified.
 encode %{
   enc_class enc_unimplemented %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     C2_MacroAssembler _masm(&cbuf);
     __ unimplemented("Unimplemented mach node encoding in AD file.", 13);
   %}
 
   enc_class enc_untested %{
 #ifdef ASSERT
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     C2_MacroAssembler _masm(&cbuf);
     __ untested("Untested mach node encoding in AD file.");
 #else
-    // TODO: PPC port $archOpcode(ppc64Opcode_none);
 #endif
   %}
 
   enc_class enc_lbz(iRegIdst dst, memory mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lbz);
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
@@ -2702,7 +2522,6 @@ encode %{
 
   // Load acquire.
   enc_class enc_lbz_ac(iRegIdst dst, memory mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ lbz($dst$$Register, Idisp, $mem$$base$$Register);
@@ -2711,7 +2530,6 @@ encode %{
   %}
 
   enc_class enc_lhz(iRegIdst dst, memory mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lhz);
 
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
@@ -2720,7 +2538,6 @@ encode %{
 
   // Load acquire.
   enc_class enc_lhz_ac(iRegIdst dst, memory mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
 
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
@@ -2730,7 +2547,6 @@ encode %{
   %}
 
   enc_class enc_lwz(iRegIdst dst, memory mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lwz);
 
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
@@ -2739,7 +2555,6 @@ encode %{
 
   // Load acquire.
   enc_class enc_lwz_ac(iRegIdst dst, memory mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
 
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
@@ -2749,7 +2564,6 @@ encode %{
   %}
 
   enc_class enc_ld(iRegLdst dst, memoryAlg4 mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     // Operand 'ds' requires 4-alignment.
@@ -2759,7 +2573,6 @@ encode %{
 
   // Load acquire.
   enc_class enc_ld_ac(iRegLdst dst, memoryAlg4 mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     // Operand 'ds' requires 4-alignment.
@@ -2770,14 +2583,12 @@ encode %{
   %}
 
   enc_class enc_lfd(RegF dst, memory mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lfd);
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
   %}
 
   enc_class enc_load_long_constL(iRegLdst dst, immL src, iRegLdst toc) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
 
     C2_MacroAssembler _masm(&cbuf);
     int toc_offset = 0;
@@ -2801,7 +2612,6 @@ encode %{
   %}
 
   enc_class enc_load_long_constL_hi(iRegLdst dst, iRegLdst toc, immL src) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
 
     C2_MacroAssembler _masm(&cbuf);
 
@@ -3036,7 +2846,6 @@ encode %{
   %}
 
   enc_class enc_load_long_constP(iRegLdst dst, immP src, iRegLdst toc) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
 
     C2_MacroAssembler _masm(&cbuf);
     int toc_offset = 0;
@@ -3069,7 +2878,6 @@ encode %{
   %}
 
   enc_class enc_load_long_constP_hi(iRegLdst dst, immP src, iRegLdst toc) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
 
     C2_MacroAssembler _masm(&cbuf);
     if (!ra_->C->output()->in_scratch_emit_size()) {
@@ -3204,14 +3012,12 @@ encode %{
   %}
 
   enc_class enc_stw(iRegIsrc src, memory mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_stw);
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ stw($src$$Register, Idisp, $mem$$base$$Register);
   %}
 
   enc_class enc_std(iRegIsrc src, memoryAlg4 mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_std);
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     // Operand 'ds' requires 4-alignment.
@@ -3220,14 +3026,12 @@ encode %{
   %}
 
   enc_class enc_stfs(RegF src, memory mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_stfs);
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ stfs($src$$FloatRegister, Idisp, $mem$$base$$Register);
   %}
 
   enc_class enc_stfd(RegF src, memory mem) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_stfd);
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ stfd($src$$FloatRegister, Idisp, $mem$$base$$Register);
@@ -3236,7 +3040,6 @@ encode %{
   // Use release_store for card-marking to ensure that previous
   // oop-stores are visible before the card-mark change.
   enc_class enc_cms_card_mark(memory mem, iRegLdst releaseFieldAddr, flagsReg crx) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // FIXME: Implement this as a cmove and use a fixed condition code
     // register which is written on every transition to compiled code,
     // e.g. in call-stub and when returning from runtime stubs.
@@ -3252,18 +3055,8 @@ encode %{
     C2_MacroAssembler _masm(&cbuf);
     Label skip_storestore;
 
-#if 0 // TODO: PPC port
-    // Check CMSCollectorCardTableBarrierSetBSExt::_requires_release and do the
-    // StoreStore barrier conditionally.
-    __ lwz(R0, 0, $releaseFieldAddr$$Register);
-    __ cmpwi($crx$$CondRegister, R0, 0);
-    __ beq_predict_taken($crx$$CondRegister, skip_storestore);
-#endif
     __ li(R0, 0);
     __ membar(Assembler::StoreStore);
-#if 0 // TODO: PPC port
-    __ bind(skip_storestore);
-#endif
 
     // Do the store.
     if ($mem$$index == 0) {
@@ -3468,7 +3261,6 @@ encode %{
   %}
 
   enc_class enc_cmove_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src, cmpOp cmp) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
 
     C2_MacroAssembler _masm(&cbuf);
     int cc        = $cmp$$cmpcode;
@@ -3478,12 +3270,10 @@ encode %{
     // Branch if not (cmp crx).
     __ bc(cc_to_inverse_boint(cc), cc_to_biint(cc, flags_reg), done);
     __ mr($dst$$Register, $src$$Register);
-    // TODO PPC port __ endgroup_if_needed(_size == 12);
     __ bind(done);
   %}
 
   enc_class enc_cmove_imm(iRegIdst dst, flagsRegSrc crx, immI16 src, cmpOp cmp) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
 
     C2_MacroAssembler _masm(&cbuf);
     Label done;
@@ -3491,20 +3281,17 @@ encode %{
     // Branch if not (cmp crx).
     __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
     __ li($dst$$Register, $src$$constant);
-    // TODO PPC port __ endgroup_if_needed(_size == 12);
     __ bind(done);
   %}
 
   // This enc_class is needed so that scheduler gets proper
   // input mapping for latency computation.
   enc_class enc_andc(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_andc);
     C2_MacroAssembler _masm(&cbuf);
     __ andc($dst$$Register, $src1$$Register, $src2$$Register);
   %}
 
   enc_class enc_convI2B_regI__cmove(iRegIdst dst, iRegIsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
 
     C2_MacroAssembler _masm(&cbuf);
 
@@ -3517,7 +3304,6 @@ encode %{
   %}
 
   enc_class enc_convP2B_regP__cmove(iRegIdst dst, iRegPsrc src, flagsReg crx, immI16 zero, immI16 notzero) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
 
     C2_MacroAssembler _masm(&cbuf);
 
@@ -3530,30 +3316,25 @@ encode %{
   %}
 
   enc_class enc_cmove_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL mem ) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
 
     C2_MacroAssembler _masm(&cbuf);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     Label done;
     __ bso($crx$$CondRegister, done);
     __ ld($dst$$Register, Idisp, $mem$$base$$Register);
-    // TODO PPC port __ endgroup_if_needed(_size == 12);
     __ bind(done);
   %}
 
   enc_class enc_cmove_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
 
     C2_MacroAssembler _masm(&cbuf);
     Label done;
     __ bso($crx$$CondRegister, done);
     __ mffprd($dst$$Register, $src$$FloatRegister);
-    // TODO PPC port __ endgroup_if_needed(_size == 12);
     __ bind(done);
   %}
 
   enc_class enc_bc(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_bc);
 
     C2_MacroAssembler _masm(&cbuf);
     Label d;   // dummy
@@ -3583,7 +3364,6 @@ encode %{
   enc_class enc_bc_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
     // The scheduler doesn't know about branch shortening, so we set the opcode
     // to ppc64Opcode_bc in order to hide this detail from the scheduler.
-    // TODO: PPC port $archOpcode(ppc64Opcode_bc);
 
     C2_MacroAssembler _masm(&cbuf);
     Label d;    // dummy
@@ -3611,47 +3391,6 @@ encode %{
                   MacroAssembler::bc_far_optimize_on_relocate);
   %}
 
-  // Branch used with Power6 scheduling (can be shortened without changing the node).
-  enc_class enc_bc_short_far(flagsRegSrc crx, cmpOp cmp, Label lbl) %{
-    // The scheduler doesn't know about branch shortening, so we set the opcode
-    // to ppc64Opcode_bc in order to hide this detail from the scheduler.
-    // TODO: PPC port $archOpcode(ppc64Opcode_bc);
-
-    C2_MacroAssembler _masm(&cbuf);
-    Label d;   // dummy
-    __ bind(d);
-    Label* p = ($lbl$$label);
-    // `p' is `NULL' when this encoding class is used only to
-    // determine the size of the encoded instruction.
-    Label& l = (NULL == p)? d : *(p);
-    int cc = $cmp$$cmpcode;
-    int flags_reg = $crx$$reg;
-    int bhint = Assembler::bhintNoHint;
-
-    if (UseStaticBranchPredictionForUncommonPathsPPC64) {
-      if (_prob <= PROB_NEVER) {
-        bhint = Assembler::bhintIsNotTaken;
-      } else if (_prob >= PROB_ALWAYS) {
-        bhint = Assembler::bhintIsTaken;
-      }
-    }
-
-#if 0 // TODO: PPC port
-    if (_size == 8) {
-      // Tell the conditional far branch to optimize itself when being relocated.
-      __ bc_far(Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
-                    cc_to_biint(cc, flags_reg),
-                    l,
-                    MacroAssembler::bc_far_optimize_on_relocate);
-    } else {
-      __ bc    (Assembler::add_bhint_to_boint(bhint, cc_to_boint(cc)),
-                    cc_to_biint(cc, flags_reg),
-                    l);
-    }
-#endif
-    Unimplemented();
-  %}
-
   // Postalloc expand emitter for loading a replicatef float constant from
   // the method's TOC.
   // Enc_class needed as consttanttablebase is not supported by postalloc
@@ -3698,7 +3437,6 @@ encode %{
   // This enc_class is needed so that scheduler gets proper
   // input mapping for latency computation.
   enc_class enc_poll(immI dst, iRegLdst poll) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
     // Fake operand dst needed for PPC scheduler.
     assert($dst$$constant == 0x0, "dst must be 0x0");
 
@@ -3756,7 +3494,6 @@ encode %{
   //
   // Usage of r1 and r2 in the stubs allows to distinguish them.
   enc_class enc_java_static_call(method meth) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_bl);
 
     C2_MacroAssembler _masm(&cbuf);
     address entry_point = (address)$meth$$method;
@@ -3806,7 +3543,6 @@ encode %{
 
   // Second node of expanded dynamic call - the call.
   enc_class enc_java_dynamic_call_sched(method meth) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_bl);
 
     C2_MacroAssembler _masm(&cbuf);
 
@@ -3863,7 +3599,6 @@ encode %{
     call->_tf                = _tf;
     call->_entry_point       = _entry_point;
     call->_cnt               = _cnt;
-    call->_argsize           = _argsize;
     call->_oop_map           = _oop_map;
     call->_jvms              = _jvms;
     call->_jvmadj            = _jvmadj;
@@ -3910,7 +3645,6 @@ encode %{
   // Toc is only passed so that it can be used in ins_encode statement.
   // In the code we have to use $constanttablebase.
   enc_class enc_java_dynamic_call(method meth, iRegLdst toc) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     C2_MacroAssembler _masm(&cbuf);
     int start_offset = __ offset();
 
@@ -3968,7 +3702,6 @@ encode %{
 
   // a runtime call
   enc_class enc_java_to_runtime_call (method meth) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
 
     C2_MacroAssembler _masm(&cbuf);
     const address start_pc = __ pc();
@@ -4002,7 +3735,6 @@ encode %{
   // This enc_class is needed so that scheduler gets proper
   // input mapping for latency computation.
   enc_class enc_leaf_call_mtctr(iRegLsrc src) %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_mtctr);
     C2_MacroAssembler _masm(&cbuf);
     __ mtctr($src$$Register);
   %}
@@ -4067,7 +3799,6 @@ encode %{
     call->_tf          = _tf;
     call->_entry_point = _entry_point;
     call->_cnt         = _cnt;
-    call->_argsize     = _argsize;
     call->_oop_map     = _oop_map;
     guarantee(!_jvms, "You must clone the jvms and adapt the offsets by fix_jvms().");
     call->_jvms        = NULL;
@@ -4118,17 +3849,14 @@ encode %{
 // Definition of frame structure and management information.
 
 frame %{
-  // What direction does stack grow in (assumed to be same for native & Java).
-  stack_direction(TOWARDS_LOW);
-
   // These two registers define part of the calling convention between
   // compiled code and the interpreter.
 
   // Inline Cache Register or method for I2C.
   inline_cache_reg(R19); // R19_method
 
-  // Method Oop Register when calling interpreter.
-  interpreter_method_oop_reg(R19); // R19_method
+  // Method Register when calling interpreter.
+  interpreter_method_reg(R19); // R19_method
 
   // Optional: name the operand used by cisc-spilling to access
   // [stack_pointer + offset].
@@ -5037,15 +4765,15 @@ operand inline_cache_regP(iRegPdst reg) %{
   interface(REG_INTER);
 %}
 
-operand compiler_method_oop_regP(iRegPdst reg) %{
-  constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_oop_reg
+operand compiler_method_regP(iRegPdst reg) %{
+  constraint(ALLOC_IN_RC(rscratch1_bits64_reg)); // compiler_method_reg
   match(reg);
   format %{ %}
   interface(REG_INTER);
 %}
 
-operand interpreter_method_oop_regP(iRegPdst reg) %{
-  constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_oop_reg
+operand interpreter_method_regP(iRegPdst reg) %{
+  constraint(ALLOC_IN_RC(r19_bits64_reg)); // interpreter_method_reg
   match(reg);
   format %{ %}
   interface(REG_INTER);
@@ -5514,7 +5242,6 @@ instruct convB2I_reg_2(iRegIdst dst, iRegIsrc src) %{
   format %{ "EXTSB   $dst, $src \t// byte->int" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_extsb);
     __ extsb($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -5672,7 +5399,6 @@ instruct loadS(iRegIdst dst, memory mem) %{
   format %{ "LHA     $dst, $mem" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lha);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ lha($dst$$Register, Idisp, $mem$$base$$Register);
   %}
@@ -5689,7 +5415,6 @@ instruct loadS_ac(iRegIdst dst, memory mem) %{
             "ISYNC" %}
   size(12);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ lha($dst$$Register, Idisp, $mem$$base$$Register);
     __ twi_0($dst$$Register);
@@ -5796,7 +5521,6 @@ instruct loadI2L(iRegLdst dst, memoryAlg4 mem) %{
   format %{ "LWA     $dst, $mem \t// loadI2L" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lwa);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
   %}
@@ -5813,7 +5537,6 @@ instruct loadI2L_ac(iRegLdst dst, memoryAlg4 mem) %{
             "ISYNC" %}
   size(12);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lwa);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ lwa($dst$$Register, Idisp, $mem$$base$$Register);
     __ twi_0($dst$$Register);
@@ -6015,7 +5738,6 @@ instruct loadF(regF dst, memory mem) %{
   format %{ "LFS     $dst, $mem" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lfs);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
   %}
@@ -6035,7 +5757,6 @@ instruct loadF_ac(regF dst, memory mem, flagsRegCR0 cr0) %{
             "ISYNC" %}
   size(16);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     Label next;
     __ lfs($dst$$FloatRegister, Idisp, $mem$$base$$Register);
@@ -6072,7 +5793,6 @@ instruct loadD_ac(regD dst, memory mem, flagsRegCR0 cr0) %{
             "ISYNC" %}
   size(16);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     Label next;
     __ lfd($dst$$FloatRegister, Idisp, $mem$$base$$Register);
@@ -6107,7 +5827,6 @@ instruct loadToc_hi(iRegLdst dst) %{
   format %{ "ADDIS   $dst, R29, DISP.hi \t// load TOC hi" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
     __ calculate_address_from_global_toc_hi16only($dst$$Register, __ method_toc());
   %}
   ins_pipe(pipe_class_default);
@@ -6121,7 +5840,6 @@ instruct loadToc_lo(iRegLdst dst, iRegLdst src) %{
   format %{ "ADDI    $dst, $src, DISP.lo \t// load TOC lo" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
     __ calculate_address_from_global_toc_lo16only($dst$$Register, __ method_toc());
   %}
   ins_pipe(pipe_class_default);
@@ -6134,7 +5852,6 @@ instruct loadConI16(iRegIdst dst, immI16 src) %{
   format %{ "LI      $dst, $src" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
   %}
   ins_pipe(pipe_class_default);
@@ -6148,7 +5865,6 @@ instruct loadConIhi16(iRegIdst dst, immIhi16 src) %{
   format %{ "LIS     $dst, $src.hi" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
     // Lis sign extends 16-bit src then shifts it 16 bit to the left.
     __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
   %}
@@ -6165,7 +5881,6 @@ instruct loadConI32_lo16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
   format %{ "ORI     $dst, $src1.hi, $src2.lo" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
     __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
   %}
   ins_pipe(pipe_class_default);
@@ -6193,7 +5908,6 @@ instruct loadConL16(iRegLdst dst, immL16 src) %{
   format %{ "LI      $dst, $src \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, (int)((short) ($src$$constant & 0xFFFF)));
   %}
   ins_pipe(pipe_class_default);
@@ -6207,7 +5921,6 @@ instruct loadConL32hi16(iRegLdst dst, immL32hi16 src) %{
   format %{ "LIS     $dst, $src.hi \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
     __ lis($dst$$Register, (int)((short)(($src$$constant & 0xFFFF0000) >> 16)));
   %}
   ins_pipe(pipe_class_default);
@@ -6223,7 +5936,6 @@ instruct loadConL32_lo16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
   format %{ "ORI     $dst, $src1, $src2.lo" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
     __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
   %}
   ins_pipe(pipe_class_default);
@@ -6303,7 +6015,6 @@ instruct loadConL_lo(iRegLdst dst, immL src, iRegLdst base) %{
   format %{ "LD      $dst, offset, $base \t// load long $src from TOC (lo)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
     int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
     __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
   %}
@@ -6330,7 +6041,6 @@ instruct loadConN0(iRegNdst dst, immN_0 src) %{
   format %{ "LI      $dst, $src \t// compressed ptr" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, 0);
   %}
   ins_pipe(pipe_class_default);
@@ -6344,7 +6054,6 @@ instruct loadConN_hi(iRegNdst dst, immN src) %{
   format %{ "LIS     $dst, $src \t// narrow oop hi" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
     __ lis($dst$$Register, (int)(short)(($src$$constant >> 16) & 0xffff));
   %}
   ins_pipe(pipe_class_default);
@@ -6358,7 +6067,6 @@ instruct loadConN_lo(iRegNdst dst, iRegNsrc src1, immN src2) %{
   format %{ "ORI     $dst, $src1, $src2 \t// narrow oop lo" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
     int oop_index = __ oop_recorder()->find_index((jobject)$src2$$constant);
     RelocationHolder rspec = oop_Relocation::spec(oop_index);
@@ -6389,7 +6097,6 @@ instruct clearMs32b(iRegNdst dst, iRegNsrc src) %{
   format %{ "MASK    $dst, $src, 0xFFFFFFFF" %} // mask
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ clrldi($dst$$Register, $src$$Register, 0x20);
   %}
   ins_pipe(pipe_class_default);
@@ -6402,7 +6109,6 @@ instruct loadBase(iRegLdst dst) %{
 
   format %{ "LoadConst $dst, heapbase" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ load_const_optimized($dst$$Register, CompressedOops::base(), R0);
   %}
   ins_pipe(pipe_class_default);
@@ -6450,7 +6156,6 @@ instruct loadConNKlass_hi(iRegNdst dst, immNKlass_NM src) %{
   format %{ "LIS     $dst, $src \t// narrow klass hi" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
     intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src$$constant);
     __ lis($dst$$Register, (int)(short)((Csrc >> 16) & 0xffff));
   %}
@@ -6466,7 +6171,6 @@ instruct loadConNKlass_mask(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
   format %{ "MASK    $dst, $src2, 0xFFFFFFFF" %} // mask
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ clrldi($dst$$Register, $src2$$Register, 0x20);
   %}
   ins_pipe(pipe_class_default);
@@ -6482,7 +6186,6 @@ instruct loadConNKlass_lo(iRegNdst dst, immNKlass_NM src1, iRegNsrc src2) %{
   format %{ "ORI     $dst, $src1, $src2 \t// narrow klass lo" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
     intptr_t Csrc = CompressedKlassPointers::encode((Klass *)$src1$$constant);
     assert(__ oop_recorder() != NULL, "this assembler needs an OopRecorder");
     int klass_index = __ oop_recorder()->find_index((Klass *)$src1$$constant);
@@ -6540,7 +6243,6 @@ instruct loadConP0or1(iRegPdst dst, immP_0or1 src) %{
   format %{ "LI      $dst, $src \t// ptr" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
   %}
   ins_pipe(pipe_class_default);
@@ -6588,7 +6290,6 @@ instruct loadConP_lo(iRegPdst dst, immP_NM src, iRegLdst base) %{
   format %{ "LD      $dst, offset, $base \t// load ptr $src from TOC (lo)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ld);
     int offset = ra_->C->output()->in_scratch_emit_size() ? 0 : _const_toc_offset_hi_node->_const_toc_offset;
     __ ld($dst$$Register, MacroAssembler::largeoffset_si16_si16_lo(offset), $base$$Register);
   %}
@@ -6625,7 +6326,6 @@ instruct loadConF(regF dst, immF src, iRegLdst toc) %{
   format %{ "LFS     $dst, offset, $toc \t// load float $src from TOC" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lfs);
     address float_address = __ float_constant($src$$constant);
     if (float_address == NULL) {
       ciEnv::current()->record_out_of_memory_failure();
@@ -6648,7 +6348,6 @@ instruct loadConFComp(regF dst, immF src, iRegLdst toc) %{
             "ADDIS   $toc, $toc, -offset_hi"%}
   size(12);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     FloatRegister Rdst    = $dst$$FloatRegister;
     Register Rtoc         = $toc$$Register;
     address float_address = __ float_constant($src$$constant);
@@ -6689,7 +6388,6 @@ instruct loadConD(regD dst, immD src, iRegLdst toc) %{
   format %{ "LFD     $dst, offset, $toc \t// load double $src from TOC" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lfd);
     address float_address = __ double_constant($src$$constant);
     if (float_address == NULL) {
       ciEnv::current()->record_out_of_memory_failure();
@@ -6713,7 +6411,6 @@ instruct loadConDComp(regD dst, immD src, iRegLdst toc) %{
             "ADDIS   $toc, $toc, -offset_hi" %}
   size(12);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     FloatRegister Rdst    = $dst$$FloatRegister;
     Register      Rtoc    = $toc$$Register;
     address float_address = __ double_constant($src$$constant);
@@ -6756,7 +6453,6 @@ instruct prefetch_alloc_zero(indirectMemory mem, iRegLsrc src) %{
   format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many with zero" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst);
     __ dcbz($src$$Register, $mem$$base$$Register);
   %}
   ins_pipe(pipe_class_memory);
@@ -6770,7 +6466,6 @@ instruct prefetch_alloc_zero_no_offset(indirectMemory mem) %{
   format %{ "PREFETCH $mem, 2 \t// Prefetch write-many with zero" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst);
     __ dcbz($mem$$base$$Register);
   %}
   ins_pipe(pipe_class_memory);
@@ -6784,7 +6479,6 @@ instruct prefetch_alloc(indirectMemory mem, iRegLsrc src) %{
   format %{ "PREFETCH $mem, 2, $src \t// Prefetch write-many" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst);
     __ dcbtst($src$$Register, $mem$$base$$Register);
   %}
   ins_pipe(pipe_class_memory);
@@ -6798,7 +6492,6 @@ instruct prefetch_alloc_no_offset(indirectMemory mem) %{
   format %{ "PREFETCH $mem, 2 \t// Prefetch write-many" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_dcbtst);
     __ dcbtst($mem$$base$$Register);
   %}
   ins_pipe(pipe_class_memory);
@@ -6814,7 +6507,6 @@ instruct storeB(memory mem, iRegIsrc src) %{
   format %{ "STB     $src, $mem \t// byte" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_stb);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ stb($src$$Register, Idisp, $mem$$base$$Register);
   %}
@@ -6829,7 +6521,6 @@ instruct storeC(memory mem, iRegIsrc src) %{
   format %{ "STH     $src, $mem \t// short" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_sth);
     int Idisp = $mem$$disp + frame_slots_bias($mem$$base, ra_);
     __ sth($src$$Register, Idisp, $mem$$base$$Register);
   %}
@@ -6983,7 +6674,6 @@ instruct storeCM_G1(memory mem, immI_0 zero) %{
   format %{ "STB     #0, $mem \t// CMS card-mark byte store (G1)" %}
   size(8);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ li(R0, 0);
     //__ release(); // G1: oops are allowed to get visible after dirty marking
     guarantee($mem$$base$$Register != R1_SP, "use frame_slots_bias");
@@ -7005,7 +6695,6 @@ instruct encodeP_shift(iRegNdst dst, iRegNsrc src) %{
   format %{ "SRDI    $dst, $src, 3 \t// encode" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -7019,7 +6708,6 @@ instruct encodeP_sub(iRegPdst dst, iRegPdst src) %{
 
   format %{ "SUB     $dst, $src, oop_base \t// encode" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ sub_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
   %}
   ins_pipe(pipe_class_default);
@@ -7035,7 +6723,6 @@ instruct cond_sub_base(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
             "SUB     $dst, $src1, heapbase \t// encode: subtract base if != NULL\n"
             "done:" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Label done;
     __ beq($crx$$CondRegister, done);
     __ sub_const_optimized($dst$$Register, $src1$$Register, CompressedOops::base(), R0);
@@ -7054,7 +6741,6 @@ instruct cond_set_0_oop(iRegNdst dst, flagsRegSrc crx, iRegPsrc src1) %{
   size(4);
   ins_encode %{
     // This is a Power7 instruction for which no machine description exists.
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -7068,7 +6754,6 @@ instruct encodeP_Disjoint(iRegNdst dst, iRegPsrc src) %{
   format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with disjoint base" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ rldicl($dst$$Register, $src$$Register, 64-CompressedOops::shift(), 32);
   %}
   ins_pipe(pipe_class_default);
@@ -7107,7 +6792,6 @@ instruct encodeP_not_null_base_null(iRegNdst dst, iRegPsrc src) %{
   format %{ "SRDI    $dst, $src, #3 \t// encodeP, $src != NULL" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ srdi($dst$$Register, $src$$Register, CompressedOops::shift() & 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -7122,7 +6806,6 @@ instruct encodeP_narrow_oop_shift_0(iRegNdst dst, iRegPsrc src) %{
   format %{ "MR      $dst, $src \t// Ptr->Narrow" %}
   // variable size, 0 or 4.
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ mr_if_needed($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -7139,7 +6822,6 @@ instruct decodeN_shift(iRegPdst dst, iRegPsrc src) %{
   format %{ "SLDI    $dst, $src, #3 \t// DecodeN" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
     __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
   %}
   ins_pipe(pipe_class_default);
@@ -7153,7 +6835,6 @@ instruct decodeN_add(iRegPdst dst, iRegPdst src) %{
 
   format %{ "ADD     $dst, $src, heapbase \t// DecodeN, add oop base" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
   %}
   ins_pipe(pipe_class_default);
@@ -7172,7 +6853,6 @@ instruct cond_add_base(iRegPdst dst, flagsRegSrc crx, iRegPsrc src) %{
             "ADD     $dst, $src, heapbase \t// DecodeN: add oop base if $src != NULL\n"
             "done:" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Label done;
     __ beq($crx$$CondRegister, done);
     __ add_const_optimized($dst$$Register, $src$$Register, CompressedOops::base(), R0);
@@ -7193,7 +6873,6 @@ instruct cond_set_0_ptr(iRegPdst dst, flagsRegSrc crx, iRegPsrc src1) %{
   size(4);
   ins_encode %{
     // This is a Power7 instruction for which no machine description exists.
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ isel_0($dst$$Register, $crx$$CondRegister, Assembler::equal, $src1$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -7222,7 +6901,6 @@ instruct decodeN_nullBase(iRegPdst dst, iRegNsrc src) %{
   format %{ "SLDI    $dst, $src, #3 \t// DecodeN (zerobased)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
     __ sldi($dst$$Register, $src$$Register, CompressedOops::shift());
   %}
   ins_pipe(pipe_class_default);
@@ -7239,7 +6917,6 @@ instruct decodeN_mergeDisjoint(iRegPdst dst, iRegNsrc src, iRegLsrc base) %{
   format %{ "RLDIMI  $dst, $src, shift, 32-shift \t// DecodeN (disjoint base)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
     __ rldimi($dst$$Register, $src$$Register, CompressedOops::shift(), 32-CompressedOops::shift());
   %}
   ins_pipe(pipe_class_default);
@@ -7350,7 +7027,6 @@ instruct decodeN_unscaled(iRegPdst dst, iRegNsrc src) %{
   format %{ "MR      $dst, $src \t// DecodeN (unscaled)" %}
   // variable size, 0 or 4.
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ mr_if_needed($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -7365,7 +7041,6 @@ instruct decodeN2I_unscaled(iRegIdst dst, iRegNsrc src) %{
   format %{ "MR      $dst, $src \t// (int)DecodeN (unscaled)" %}
   // variable size, 0 or 4.
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ mr_if_needed($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -7384,7 +7059,6 @@ instruct encodePKlass_shift(iRegNdst dst, iRegNsrc src) %{
   format %{ "SRDI    $dst, $src, 3 \t// encode" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ srdi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
   %}
   ins_pipe(pipe_class_default);
@@ -7399,7 +7073,6 @@ instruct encodePKlass_sub_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
   format %{ "SUB     $dst, $base, $src \t// encode" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_subf);
     __ subf($dst$$Register, $base$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -7413,7 +7086,6 @@ instruct encodePKlass_Disjoint(iRegNdst dst, iRegPsrc src) %{
   format %{ "EXTRDI  $dst, $src, #32, #3 \t// encode with disjoint base" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ rldicl($dst$$Register, $src$$Register, 64-CompressedKlassPointers::shift(), 32);
   %}
   ins_pipe(pipe_class_default);
@@ -7473,7 +7145,6 @@ instruct decodeNKlass_shift(iRegPdst dst, iRegPsrc src) %{
   format %{ "SLDI    $dst, $src, #3 \t// DecodeNKlass" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
     __ sldi($dst$$Register, $src$$Register, CompressedKlassPointers::shift());
   %}
   ins_pipe(pipe_class_default);
@@ -7489,7 +7160,6 @@ instruct decodeNKlass_add_base(iRegPdst dst, iRegLsrc base, iRegPdst src) %{
   format %{ "ADD     $dst, $base, $src \t// DecodeNKlass, add klass base" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_add);
     __ add($dst$$Register, $base$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -7553,7 +7223,6 @@ instruct membar_acquire() %{
   format %{ "MEMBAR-acquire" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lwsync);
     __ acquire();
   %}
   ins_pipe(pipe_class_default);
@@ -7587,7 +7256,6 @@ instruct membar_release() %{
   format %{ "MEMBAR-release" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lwsync);
     __ release();
   %}
   ins_pipe(pipe_class_default);
@@ -7600,7 +7268,6 @@ instruct membar_storestore() %{
   format %{ "MEMBAR-store-store" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lwsync);
     __ membar(Assembler::StoreStore);
   %}
   ins_pipe(pipe_class_default);
@@ -7623,7 +7290,6 @@ instruct membar_volatile() %{
   format %{ "MEMBAR-volatile" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_sync);
     __ fence();
   %}
   ins_pipe(pipe_class_default);
@@ -7682,7 +7348,6 @@ instruct cmovI_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src)
   ins_encode %{
     // This is a Power7 instruction for which no machine description
     // exists. Anyways, the scheduler should be off on Power7.
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     int cc        = $cmp$$cmpcode;
     __ isel($dst$$Register, $crx$$CondRegister,
             (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
@@ -7699,7 +7364,7 @@ instruct cmovI_reg(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, iRegIsrc src) %{
 
   format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
   // Worst case is branch + move + stop, no stop without scheduler
-  size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
   ins_pipe(pipe_class_default);
 %}
@@ -7712,7 +7377,7 @@ instruct cmovI_imm(cmpOp cmp, flagsRegSrc crx, iRegIdst dst, immI16 src) %{
 
   format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
   // Worst case is branch + move + stop, no stop without scheduler
-  size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
   ins_pipe(pipe_class_default);
 %}
@@ -7728,7 +7393,6 @@ instruct cmovL_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src)
   ins_encode %{
     // This is a Power7 instruction for which no machine description
     // exists. Anyways, the scheduler should be off on Power7.
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     int cc        = $cmp$$cmpcode;
     __ isel($dst$$Register, $crx$$CondRegister,
             (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
@@ -7745,7 +7409,7 @@ instruct cmovL_reg(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, iRegLsrc src) %{
 
   format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
   ins_pipe(pipe_class_default);
 %}
@@ -7758,7 +7422,7 @@ instruct cmovL_imm(cmpOp cmp, flagsRegSrc crx, iRegLdst dst, immL16 src) %{
 
   format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
   ins_pipe(pipe_class_default);
 %}
@@ -7774,7 +7438,6 @@ instruct cmovN_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src)
   ins_encode %{
     // This is a Power7 instruction for which no machine description
     // exists. Anyways, the scheduler should be off on Power7.
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     int cc        = $cmp$$cmpcode;
     __ isel($dst$$Register, $crx$$CondRegister,
             (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
@@ -7792,7 +7455,7 @@ instruct cmovN_reg(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, iRegNsrc src) %{
 
   format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
   ins_pipe(pipe_class_default);
 %}
@@ -7805,7 +7468,7 @@ instruct cmovN_imm(cmpOp cmp, flagsRegSrc crx, iRegNdst dst, immN_0 src) %{
 
   format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
   ins_pipe(pipe_class_default);
 %}
@@ -7821,7 +7484,6 @@ instruct cmovP_reg_isel(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegPsrc src)
   ins_encode %{
     // This is a Power7 instruction for which no machine description
     // exists. Anyways, the scheduler should be off on Power7.
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     int cc        = $cmp$$cmpcode;
     __ isel($dst$$Register, $crx$$CondRegister,
             (Assembler::Condition)(cc & 3), /*invert*/((~cc) & 8), $src$$Register);
@@ -7838,7 +7500,7 @@ instruct cmovP_reg(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, iRegP_N2P src) %{
 
   format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_reg(dst, crx, src, cmp) );
   ins_pipe(pipe_class_default);
 %}
@@ -7851,7 +7513,7 @@ instruct cmovP_imm(cmpOp cmp, flagsRegSrc crx, iRegPdst dst, immP_0 src) %{
 
   format %{ "CMOVE   $cmp, $crx, $dst, $src\n\t" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_imm(dst, crx, src, cmp) );
   ins_pipe(pipe_class_default);
 %}
@@ -7864,15 +7526,13 @@ instruct cmovF_reg(cmpOp cmp, flagsRegSrc crx, regF dst, regF src) %{
 
   format %{ "CMOVEF  $cmp, $crx, $dst, $src\n\t" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8));
+  size(8);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmovef);
     Label done;
     assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
     // Branch if not (cmp crx).
     __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
     __ fmr($dst$$FloatRegister, $src$$FloatRegister);
-    // TODO PPC port __ endgroup_if_needed(_size == 12);
     __ bind(done);
   %}
   ins_pipe(pipe_class_default);
@@ -7886,15 +7546,13 @@ instruct cmovD_reg(cmpOp cmp, flagsRegSrc crx, regD dst, regD src) %{
 
   format %{ "CMOVEF  $cmp, $crx, $dst, $src\n\t" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8));
+  size(8);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmovef);
     Label done;
     assert((Assembler::bcondCRbiIs1 & ~Assembler::bcondCRbiIs0) == 8, "check encoding");
     // Branch if not (cmp crx).
     __ bc(cc_to_inverse_boint($cmp$$cmpcode), cc_to_biint($cmp$$cmpcode, $crx$$reg), done);
     __ fmr($dst$$FloatRegister, $src$$FloatRegister);
-    // TODO PPC port __ endgroup_if_needed(_size == 12);
     __ bind(done);
   %}
   ins_pipe(pipe_class_default);
@@ -7916,7 +7574,6 @@ instruct storeLConditional_regP_regL_regL(flagsReg crx, indirect mem_ptr, iRegLs
   effect(TEMP cr0);
   format %{ "CMPXCHGD if ($crx = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ cmpxchgd($crx$$CondRegister, R0, $oldVal$$Register, $newVal$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarAcq, MacroAssembler::cmpxchgx_hint_atomic_update(),
                 noreg, NULL, true);
@@ -7936,7 +7593,6 @@ instruct storePConditional_regP_regP_regP(flagsRegCR0 cr0, indirect mem_ptr, iRe
 
   format %{ "STDCX_  if ($cr0 = ($oldVal == *$mem_ptr)) *mem_ptr = $newVal; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_stdcx_);
     __ stdcx_($newVal$$Register, $mem_ptr$$Register);
   %}
   ins_pipe(pipe_class_memory);
@@ -7952,7 +7608,6 @@ instruct loadPLocked(iRegPdst dst, memory mem) %{
   format %{ "LDARX   $dst, $mem \t// loadPLocked\n\t" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ldarx);
     __ ldarx($dst$$Register, $mem$$Register, MacroAssembler::cmpxchgx_hint_atomic_update());
   %}
   ins_pipe(pipe_class_memory);
@@ -7972,7 +7627,6 @@ instruct compareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -7992,7 +7646,6 @@ instruct compareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIs
   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8012,7 +7665,6 @@ instruct compareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8032,7 +7684,6 @@ instruct compareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iRegIs
   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8051,7 +7702,6 @@ instruct compareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iRegIsrc
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8070,7 +7720,6 @@ instruct compareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iRegNsrc
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8089,7 +7738,6 @@ instruct compareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iRegLsrc
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8108,7 +7756,6 @@ instruct compareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iRegPsrc
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8130,7 +7777,6 @@ instruct weakCompareAndSwapB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
                 MacroAssembler::MemBarNone,
@@ -8145,7 +7791,6 @@ instruct weakCompareAndSwapB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR
   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGB $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
                 MacroAssembler::MemBarNone,
@@ -8160,7 +7805,6 @@ instruct weakCompareAndSwapB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
                 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
@@ -8175,7 +7819,6 @@ instruct weakCompareAndSwapB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr
   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgb(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
                 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
@@ -8190,7 +7833,6 @@ instruct weakCompareAndSwapS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
                 MacroAssembler::MemBarNone,
@@ -8205,7 +7847,6 @@ instruct weakCompareAndSwapS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR
   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGH $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
                 MacroAssembler::MemBarNone,
@@ -8220,7 +7861,6 @@ instruct weakCompareAndSwapS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
                 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
@@ -8235,7 +7875,6 @@ instruct weakCompareAndSwapS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr
   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP tmp2, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgh(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, $tmp2$$Register,
                 support_IRIW_for_not_multiple_copy_atomic_cpu ? MacroAssembler::MemBarAcq : MacroAssembler::MemBarFenceAfter,
@@ -8250,7 +7889,6 @@ instruct weakCompareAndSwapI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone,
@@ -8265,7 +7903,6 @@ instruct weakCompareAndSwapI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
     // value is never passed to caller.
@@ -8282,7 +7919,6 @@ instruct weakCompareAndSwapN_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGW $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgw(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone,
@@ -8297,7 +7933,6 @@ instruct weakCompareAndSwapN_acq_regP_regN_regN(iRegIdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
     // value is never passed to caller.
@@ -8314,7 +7949,6 @@ instruct weakCompareAndSwapL_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     // value is never passed to caller.
     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
@@ -8330,7 +7964,6 @@ instruct weakCompareAndSwapL_acq_regP_regL_regL(iRegIdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
     // value is never passed to caller.
@@ -8347,7 +7980,6 @@ instruct weakCompareAndSwapP_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGD $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgd(CCR0, R0, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone,
@@ -8362,7 +7994,6 @@ instruct weakCompareAndSwapP_acq_regP_regP_regP(iRegIdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0); // TEMP_DEF to avoid jump
   format %{ "weak CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as bool; ptr" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     // Acquire only needed in successful case. Weak node is allowed to report unsuccessful in additional rare cases and
     // value is never passed to caller.
@@ -8381,7 +8012,6 @@ instruct compareAndExchangeB_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8396,7 +8026,6 @@ instruct compareAndExchangeB4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR
   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
   format %{ "CMPXCHGB $res, $mem_ptr, $src1, $src2; as int" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8411,7 +8040,6 @@ instruct compareAndExchangeB_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8432,7 +8060,6 @@ instruct compareAndExchangeB4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr
   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
   format %{ "CMPXCHGB acq $res, $mem_ptr, $src1, $src2; as int" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgb(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8453,7 +8080,6 @@ instruct compareAndExchangeS_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8468,7 +8094,6 @@ instruct compareAndExchangeS4_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr, iR
   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
   format %{ "CMPXCHGH $res, $mem_ptr, $src1, $src2; as int" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8483,7 +8108,6 @@ instruct compareAndExchangeS_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, noreg, noreg,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8504,7 +8128,6 @@ instruct compareAndExchangeS4_acq_regP_regI_regI(iRegIdst res, rarg3RegP mem_ptr
   effect(TEMP_DEF res, USE_KILL src2, USE_KILL mem_ptr, TEMP tmp1, TEMP cr0);
   format %{ "CMPXCHGH acq $res, $mem_ptr, $src1, $src2; as int" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgh(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register, $tmp1$$Register, R0,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8525,7 +8148,6 @@ instruct compareAndExchangeI_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as int" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8540,7 +8162,6 @@ instruct compareAndExchangeI_acq_regP_regI_regI(iRegIdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as int" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8561,7 +8182,6 @@ instruct compareAndExchangeN_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGW $res, $mem_ptr, $src1, $src2; as narrow oop" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8576,7 +8196,6 @@ instruct compareAndExchangeN_acq_regP_regN_regN(iRegNdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGW acq $res, $mem_ptr, $src1, $src2; as narrow oop" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgw(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8597,7 +8216,6 @@ instruct compareAndExchangeL_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as long" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8612,7 +8230,6 @@ instruct compareAndExchangeL_acq_regP_regL_regL(iRegLdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as long" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8633,7 +8250,6 @@ instruct compareAndExchangeP_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr, iReg
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGD $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8648,7 +8264,6 @@ instruct compareAndExchangeP_acq_regP_regP_regP(iRegPdst res, iRegPdst mem_ptr,
   effect(TEMP_DEF res, TEMP cr0);
   format %{ "CMPXCHGD acq $res, $mem_ptr, $src1, $src2; as ptr; ptr" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     // CmpxchgX sets CCR0 to cmpX(src1, src2) and Rres to 'true'/'false'.
     __ cmpxchgd(CCR0, $res$$Register, $src1$$Register, $src2$$Register, $mem_ptr$$Register,
                 MacroAssembler::MemBarNone, MacroAssembler::cmpxchgx_hint_atomic_update(),
@@ -8906,7 +8521,6 @@ instruct addI_reg_reg(iRegIdst dst, iRegIsrc_iRegL2Isrc src1, iRegIsrc_iRegL2Isr
   format %{ "ADD     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_add);
     __ add($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -8919,7 +8533,6 @@ instruct addI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "ADD     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_add);
     __ add($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -8945,7 +8558,6 @@ instruct addI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
   format %{ "ADDI    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ addi($dst$$Register, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -8957,7 +8569,6 @@ instruct addI_reg_immhi16(iRegIdst dst, iRegIsrc src1, immIhi16 src2) %{
   format %{ "ADDIS   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
     __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
   %}
   ins_pipe(pipe_class_default);
@@ -8969,7 +8580,6 @@ instruct addL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "ADD     $dst, $src1, $src2 \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_add);
     __ add($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -8982,7 +8592,6 @@ instruct addL_reg_reg_2(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "ADD     $dst, $src1, $src2 \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_add);
     __ add($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9009,7 +8618,6 @@ instruct addI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "ADD     $dst, $src1, $src2 \t// long + l2i" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_add);
     __ add($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9022,7 +8630,6 @@ instruct addL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
   format %{ "ADDI    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ addi($dst$$Register, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -9036,7 +8643,6 @@ instruct addL_reg_immhi16(iRegLdst dst, iRegLsrc src1, immL32hi16 src2) %{
   format %{ "ADDIS   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
     __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
   %}
   ins_pipe(pipe_class_default);
@@ -9048,7 +8654,6 @@ instruct addP_reg_reg(iRegPdst dst, iRegP_N2P src1, iRegLsrc src2) %{
   format %{ "ADD     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_add);
     __ add($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9062,7 +8667,6 @@ instruct addP_reg_imm16(iRegPdst dst, iRegP_N2P src1, immL16 src2) %{
   format %{ "ADDI    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ addi($dst$$Register, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -9076,7 +8680,6 @@ instruct addP_reg_immhi16(iRegPdst dst, iRegP_N2P src1, immL32hi16 src2) %{
   format %{ "ADDIS   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addis);
     __ addis($dst$$Register, $src1$$Register, ($src2$$constant)>>16);
   %}
   ins_pipe(pipe_class_default);
@@ -9091,7 +8694,6 @@ instruct subI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "SUBF    $dst, $src2, $src1" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_subf);
     __ subf($dst$$Register, $src2$$Register, $src1$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9108,7 +8710,6 @@ instruct subI_imm16_reg(iRegIdst dst, immI16 src1, iRegIsrc src2) %{
 
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_subfic);
     __ subfic($dst$$Register, $src2$$Register, $src1$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -9124,7 +8725,6 @@ instruct signmask32I_regI(iRegIdst dst, iRegIsrc src) %{
   format %{ "SRAWI   $dst, $src, #31" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_srawi);
     __ srawi($dst$$Register, $src$$Register, 0x1f);
   %}
   ins_pipe(pipe_class_default);
@@ -9148,7 +8748,6 @@ instruct negI_regI(iRegIdst dst, immI_0 zero, iRegIsrc src2) %{
   format %{ "NEG     $dst, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_neg);
     __ neg($dst$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9160,7 +8759,6 @@ instruct subL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "SUBF    $dst, $src2, $src1 \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_subf);
     __ subf($dst$$Register, $src2$$Register, $src1$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9173,7 +8771,6 @@ instruct subI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "SUBF    $dst, $src2, $src1 \t// long + l2i" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_subf);
     __ subf($dst$$Register, $src2$$Register, $src1$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9189,7 +8786,6 @@ instruct signmask64I_regL(iRegIdst dst, iRegLsrc src) %{
   format %{ "SRADI   $dst, $src, #63" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_sradi);
     __ sradi($dst$$Register, $src$$Register, 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -9205,7 +8801,6 @@ instruct signmask64L_regL(iRegLdst dst, iRegLsrc src) %{
   format %{ "SRADI   $dst, $src, #63" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_sradi);
     __ sradi($dst$$Register, $src$$Register, 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -9230,7 +8825,6 @@ instruct negL_reg_reg(iRegLdst dst, immL_0 zero, iRegLsrc src2) %{
   format %{ "NEG     $dst, $src2 \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_neg);
     __ neg($dst$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9243,7 +8837,6 @@ instruct negI_con0_regL(iRegIdst dst, immL_0 zero, iRegLsrc src2) %{
   format %{ "NEG     $dst, $src2 \t// long + l2i" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_neg);
     __ neg($dst$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9260,7 +8853,6 @@ instruct mulI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "MULLW   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_mullw);
     __ mullw($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9274,7 +8866,6 @@ instruct mulI_reg_imm16(iRegIdst dst, iRegIsrc src1, immI16 src2) %{
   format %{ "MULLI   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_mulli);
     __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -9287,7 +8878,6 @@ instruct mulL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "MULLD   $dst $src1, $src2 \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_mulld);
     __ mulld($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9301,7 +8891,6 @@ instruct mulHighL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "MULHD   $dst $src1, $src2 \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_mulhd);
     __ mulhd($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9315,7 +8904,6 @@ instruct mulL_reg_imm16(iRegLdst dst, iRegLsrc src1, immL16 src2) %{
   format %{ "MULLI   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_mulli);
     __ mulli($dst$$Register, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -9329,7 +8917,6 @@ instruct divI_reg_immIvalueMinus1(iRegIdst dst, iRegIsrc src1, immI_minus1 src2)
   format %{ "NEG     $dst, $src1 \t// /-1" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_neg);
     __ neg($dst$$Register, $src1$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9346,7 +8933,6 @@ instruct divI_reg_regnotMinus1(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "DIVW    $dst, $src1, $src2 \t// /not-1" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_divw);
     __ divw($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9360,13 +8946,11 @@ instruct cmovI_bne_negI_reg(iRegIdst dst, flagsRegSrc crx, iRegIsrc src1) %{
 
   format %{ "CMOVE   $dst, neg($src1), $crx" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8));
+  size(8);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
     Label done;
     __ bne($crx$$CondRegister, done);
     __ neg($dst$$Register, $src1$$Register);
-    // TODO PPC port __ endgroup_if_needed(_size == 12);
     __ bind(done);
   %}
   ins_pipe(pipe_class_default);
@@ -9394,7 +8978,6 @@ instruct divL_reg_immLvalueMinus1(iRegLdst dst, iRegLsrc src1, immL_minus1 src2)
   format %{ "NEG     $dst, $src1 \t// /-1, long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_neg);
     __ neg($dst$$Register, $src1$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9409,7 +8992,6 @@ instruct divL_reg_regnotMinus1(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "DIVD    $dst, $src1, $src2 \t// /not-1, long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_divd);
     __ divd($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9423,13 +9005,11 @@ instruct cmovL_bne_negL_reg(iRegLdst dst, flagsRegSrc crx, iRegLsrc src1) %{
 
   format %{ "CMOVE   $dst, neg($src1), $crx" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT (InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8));
+  size(8);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
     Label done;
     __ bne($crx$$CondRegister, done);
     __ neg($dst$$Register, $src1$$Register);
-    // TODO PPC port __ endgroup_if_needed(_size == 12);
     __ bind(done);
   %}
   ins_pipe(pipe_class_default);
@@ -9499,7 +9079,6 @@ instruct maskI_reg_imm(iRegIdst dst, iRegIsrc src, uimmI6 mask) %{
   format %{ "MASK    $dst, $src, $mask \t// clear $mask upper bits" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ clrldi($dst$$Register, $src$$Register, $mask$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -9513,7 +9092,6 @@ instruct lShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "SLW     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_slw);
     __ slw($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9537,7 +9115,6 @@ instruct lShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
   format %{ "SLWI    $dst, $src1, ($src2 & 0x1f)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
     __ slwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
   %}
   ins_pipe(pipe_class_default);
@@ -9551,7 +9128,6 @@ instruct lShiftI_andI_immInegpow2_imm5(iRegIdst dst, iRegIsrc src1, immInegpow2
   format %{ "RLWINM  $dst, lShiftI(AndI($src1, $src2), $src3)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi
     long src2      = $src2$$constant;
     long src3      = $src3$$constant;
     long maskbits  = src3 + log2_long((jlong) (julong) (juint) -src2);
@@ -9572,7 +9148,6 @@ instruct lShiftI_andI_immInegpow2_rShiftI_imm5(iRegIdst dst, iRegIsrc src1, immI
   format %{ "RLWINM  $dst, lShiftI(AndI(RShiftI($src1, $src3), $src2), $src3)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm); // FIXME: assert that rlwinm is equal to addi
     long src2      = $src2$$constant;
     long src3      = $src3$$constant;
     long maskbits  = src3 + log2_long((jlong) (julong) (juint) -src2);
@@ -9593,7 +9168,6 @@ instruct lShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
   format %{ "SLD     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_sld);
     __ sld($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9617,7 +9191,6 @@ instruct lshiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
   format %{ "SLDI    $dst, $src1, ($src2 & 0x3f)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
     __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -9631,7 +9204,6 @@ instruct lShiftL_regI_immGE32(iRegLdst dst, iRegIsrc src1, uimmI6_ge32 src2) %{
   size(4);
   format %{ "SLDI    $dst, i2l($src1), $src2" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
     __ sldi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -9646,7 +9218,6 @@ instruct scaledPositiveI2L_lShiftL_convI2L_reg_imm6(iRegLdst dst, iRegIsrc src1,
   format %{ "SLDI    $dst, i2l(positive_int($src1)), $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldic);
     __ clrlsldi($dst$$Register, $src1$$Register, 0x20, $src2$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -9660,7 +9231,6 @@ instruct arShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "SRAW    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_sraw);
     __ sraw($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9685,7 +9255,6 @@ instruct arShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
   format %{ "SRAWI   $dst, $src1, ($src2 & 0x1f)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_srawi);
     __ srawi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
   %}
   ins_pipe(pipe_class_default);
@@ -9699,7 +9268,6 @@ instruct arShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
   format %{ "SRAD    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_srad);
     __ srad($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9725,7 +9293,6 @@ instruct arShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
   format %{ "SRADI   $dst, $src1, ($src2 & 0x3f)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_sradi);
     __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -9738,7 +9305,6 @@ instruct convL2I_arShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
   format %{ "SRADI   $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_sradi);
     __ sradi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -9752,7 +9318,6 @@ instruct urShiftI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "SRW     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_srw);
     __ srw($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9778,7 +9343,6 @@ instruct urShiftI_reg_imm(iRegIdst dst, iRegIsrc src1, immI src2) %{
   format %{ "SRWI    $dst, $src1, ($src2 & 0x1f)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
     __ srwi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x1f);
   %}
   ins_pipe(pipe_class_default);
@@ -9792,7 +9356,6 @@ instruct urShiftL_regL_regI(iRegLdst dst, iRegLsrc src1, iRegIsrc src2) %{
   format %{ "SRD     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_srd);
     __ srd($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9818,7 +9381,6 @@ instruct urShiftL_regL_immI(iRegLdst dst, iRegLsrc src1, immI src2) %{
   format %{ "SRDI    $dst, $src1, ($src2 & 0x3f)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -9831,7 +9393,6 @@ instruct convL2I_urShiftL_regL_immI(iRegIdst dst, iRegLsrc src1, immI src2) %{
   format %{ "SRDI    $dst, $src1, ($src2 & 0x3f) \t// long + l2i" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -9844,7 +9405,6 @@ instruct shrP_convP2X_reg_imm6(iRegLdst dst, iRegP_N2P src1, uimmI6 src2) %{
   format %{ "SRDI    $dst, $src1, $src2 \t// Cast ptr $src1 to long and shift" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ srdi($dst$$Register, $src1$$Register, ($src2$$constant) & 0x3f);
   %}
   ins_pipe(pipe_class_default);
@@ -9857,7 +9417,6 @@ instruct andI_urShiftI_regI_immI_immIpow2minus1(iRegIdst dst, iRegIsrc src1, imm
   format %{ "EXTRDI  $dst, $src1, shift=$src2, mask=$src3 \t// int bitfield extract" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     int rshift = ($src2$$constant) & 0x1f;
     int length = log2_long(((jlong) $src3$$constant) + 1);
     if (rshift + length > 32) {
@@ -9876,7 +9435,6 @@ instruct andL_urShiftL_regL_immI_immLpow2minus1(iRegLdst dst, iRegLsrc src1, imm
   format %{ "EXTRDI  $dst, $src1, shift=$src2, mask=$src3 \t// long bitfield extract" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     int rshift  = ($src2$$constant) & 0x3f;
     int length = log2_long(((jlong) $src3$$constant) + 1);
     if (rshift + length > 64) {
@@ -9894,7 +9452,6 @@ instruct sxtI_reg(iRegIdst dst, iRegIsrc src) %{
   format %{ "EXTSW   $dst, $src \t// int->int" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_extsw);
     __ extsw($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -9910,7 +9467,6 @@ instruct rotlI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 lshift, immI8 rshift)
   format %{ "ROTLWI  $dst, $src, $lshift" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
     __ rotlwi($dst$$Register, $src$$Register, $lshift$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -9924,7 +9480,6 @@ instruct rotrI_reg_immi8(iRegIdst dst, iRegIsrc src, immI8 rshift, immI8 lshift)
   format %{ "ROTRWI  $dst, $rshift" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
     __ rotrwi($dst$$Register, $src$$Register, $rshift$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -9939,7 +9494,6 @@ instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
   format %{ "FADDS   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fadds);
     __ fadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -9952,7 +9506,6 @@ instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
   format %{ "FADD    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fadd);
     __ fadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -9965,7 +9518,6 @@ instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
   format %{ "FSUBS   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fsubs);
     __ fsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -9977,7 +9529,6 @@ instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
   format %{ "FSUB    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fsub);
     __ fsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -9989,7 +9540,6 @@ instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
   format %{ "FMULS   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fmuls);
     __ fmuls($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10001,7 +9551,6 @@ instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
   format %{ "FMUL    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fmul);
     __ fmul($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10013,7 +9562,6 @@ instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
   format %{ "FDIVS   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fdivs);
     __ fdivs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10025,7 +9573,6 @@ instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
   format %{ "FDIV    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fdiv);
     __ fdiv($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10037,7 +9584,6 @@ instruct absF_reg(regF dst, regF src) %{
   format %{ "FABS    $dst, $src \t// float" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fabs);
     __ fabs($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10049,7 +9595,6 @@ instruct absD_reg(regD dst, regD src) %{
   format %{ "FABS    $dst, $src \t// double" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fabs);
     __ fabs($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10060,7 +9605,6 @@ instruct negF_reg(regF dst, regF src) %{
   format %{ "FNEG    $dst, $src \t// float" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fneg);
     __ fneg($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10071,7 +9615,6 @@ instruct negD_reg(regD dst, regD src) %{
   format %{ "FNEG    $dst, $src \t// double" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fneg);
     __ fneg($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10083,7 +9626,6 @@ instruct negF_absF_reg(regF dst, regF src) %{
   format %{ "FNABS   $dst, $src \t// float" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fnabs);
     __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10095,7 +9637,6 @@ instruct negD_absD_reg(regD dst, regD src) %{
   format %{ "FNABS   $dst, $src \t// double" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fnabs);
     __ fnabs($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10108,7 +9649,6 @@ instruct sqrtD_reg(regD dst, regD src) %{
   format %{ "FSQRT   $dst, $src" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fsqrt);
     __ fsqrt($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10123,7 +9663,6 @@ instruct sqrtF_reg(regF dst, regF src) %{
   format %{ "FSQRTS  $dst, $src" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fsqrts);
     __ fsqrts($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10160,7 +9699,6 @@ instruct maddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
   format %{ "FMADDS  $dst, $src1, $src2, $src3" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fmadds);
     __ fmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10173,7 +9711,6 @@ instruct maddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
   format %{ "FMADD   $dst, $src1, $src2, $src3" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fmadd);
     __ fmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10187,7 +9724,6 @@ instruct mnsubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
   format %{ "FNMSUBS $dst, $src1, $src2, $src3" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fnmsubs);
     __ fnmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10201,7 +9737,6 @@ instruct mnsubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
   format %{ "FNMSUB  $dst, $src1, $src2, $src3" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fnmsub);
     __ fnmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10215,7 +9750,6 @@ instruct mnaddF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
   format %{ "FNMADDS $dst, $src1, $src2, $src3" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fnmadds);
     __ fnmadds($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10229,7 +9763,6 @@ instruct mnaddD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
   format %{ "FNMADD  $dst, $src1, $src2, $src3" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fnmadd);
     __ fnmadd($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10242,7 +9775,6 @@ instruct msubF_reg_reg(regF dst, regF src1, regF src2, regF src3) %{
   format %{ "FMSUBS  $dst, $src1, $src2, $src3" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fmsubs);
     __ fmsubs($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10255,7 +9787,6 @@ instruct msubD_reg_reg(regD dst, regD src1, regD src2, regD src3) %{
   format %{ "FMSUB   $dst, $src1, $src2, $src3" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fmsub);
     __ fmsub($dst$$FloatRegister, $src1$$FloatRegister, $src2$$FloatRegister, $src3$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -10272,7 +9803,6 @@ instruct andI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "AND     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_and);
     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10285,7 +9815,6 @@ instruct andI_reg_immIhi16(iRegIdst dst, iRegIsrc src1, immIhi16  src2, flagsReg
   format %{ "ANDIS   $dst, $src1, $src2.hi" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_andis_);
     __ andis_($dst$$Register, $src1$$Register, (int)((unsigned short)(($src2$$constant & 0xFFFF0000) >> 16)));
   %}
   ins_pipe(pipe_class_default);
@@ -10299,7 +9828,6 @@ instruct andI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2, flagsRegCR0
   format %{ "ANDI    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
     // FIXME: avoid andi_ ?
     __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
   %}
@@ -10312,7 +9840,6 @@ instruct andI_reg_immInegpow2(iRegIdst dst, iRegIsrc src1, immInegpow2 src2) %{
   format %{ "ANDWI   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
     __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)(julong)(juint)-($src2$$constant)));
   %}
   ins_pipe(pipe_class_default);
@@ -10323,7 +9850,6 @@ instruct andI_reg_immIpow2minus1(iRegIdst dst, iRegIsrc src1, immIpow2minus1 src
   format %{ "ANDWI   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1)));
   %}
   ins_pipe(pipe_class_default);
@@ -10335,7 +9861,6 @@ instruct andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src1, immIpowerOf2 src2) %
   format %{ "ANDWI   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
     __ rlwinm($dst$$Register, $src1$$Register, 0,
               (31-log2_long((jlong) $src2$$constant)) & 0x1f, (31-log2_long((jlong) $src2$$constant)) & 0x1f);
   %}
@@ -10350,7 +9875,6 @@ instruct andL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "AND     $dst, $src1, $src2 \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_and);
     __ andr($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10364,7 +9888,6 @@ instruct andL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2, flagsRegCR0
   format %{ "ANDI    $dst, $src1, $src2 \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
     // FIXME: avoid andi_ ?
     __ andi_($dst$$Register, $src1$$Register, $src2$$constant);
   %}
@@ -10377,7 +9900,6 @@ instruct andL_reg_immLnegpow2(iRegLdst dst, iRegLsrc src1, immLnegpow2 src2) %{
   format %{ "ANDDI   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
     __ clrrdi($dst$$Register, $src1$$Register, log2_long((jlong)-$src2$$constant));
   %}
   ins_pipe(pipe_class_default);
@@ -10388,7 +9910,6 @@ instruct andL_reg_immLpow2minus1(iRegLdst dst, iRegLsrc src1, immLpow2minus1 src
   format %{ "ANDDI   $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1)));
   %}
   ins_pipe(pipe_class_default);
@@ -10402,7 +9923,6 @@ instruct convL2I_andL_reg_immLpow2minus1(iRegIdst dst, iRegLsrc src1, immLpow2mi
   format %{ "ANDDI   $dst, $src1, $src2 \t// long + l2i" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ clrldi($dst$$Register, $src1$$Register, 64-log2_long((((jlong) $src2$$constant)+1)));
   %}
   ins_pipe(pipe_class_default);
@@ -10416,7 +9936,6 @@ instruct orI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "OR      $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10429,7 +9948,6 @@ instruct orI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "OR      $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10455,7 +9973,6 @@ instruct orI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
   format %{ "ORI     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
     __ ori($dst$$Register, $src1$$Register, ($src2$$constant) & 0xFFFF);
   %}
   ins_pipe(pipe_class_default);
@@ -10469,7 +9986,6 @@ instruct orL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
   size(4);
   format %{ "OR      $dst, $src1, $src2 \t// long" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10483,7 +9999,6 @@ instruct orI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "OR      $dst, $src1, $src2 \t// long + l2i" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ or_unchecked($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10497,7 +10012,6 @@ instruct orL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 con) %{
   format %{ "ORI     $dst, $src1, $con \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_ori);
     __ ori($dst$$Register, $src1$$Register, ($con$$constant) & 0xFFFF);
   %}
   ins_pipe(pipe_class_default);
@@ -10511,7 +10025,6 @@ instruct xorI_reg_reg(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "XOR     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_xor);
     __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10524,7 +10037,6 @@ instruct xorI_reg_reg_2(iRegIdst dst, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "XOR     $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_xor);
     __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10550,7 +10062,6 @@ instruct xorI_reg_uimm16(iRegIdst dst, iRegIsrc src1, uimmI16 src2) %{
   format %{ "XORI    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_xori);
     __ xori($dst$$Register, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -10564,7 +10075,6 @@ instruct xorL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "XOR     $dst, $src1, $src2 \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_xor);
     __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10578,7 +10088,6 @@ instruct xorI_regL_regL(iRegIdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "XOR     $dst, $src1, $src2 \t// long + l2i" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_xor);
     __ xorr($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10592,7 +10101,6 @@ instruct xorL_reg_uimm16(iRegLdst dst, iRegLsrc src1, uimmL16 src2) %{
   format %{ "XORI    $dst, $src1, $src2 \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_xori);
     __ xori($dst$$Register, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -10605,7 +10113,6 @@ instruct notI_reg(iRegIdst dst, iRegIsrc src1, immI_minus1 src2) %{
   format %{ "NOT     $dst, $src1 ($src2)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_nor);
     __ nor($dst$$Register, $src1$$Register, $src1$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10618,7 +10125,6 @@ instruct notL_reg(iRegLdst dst, iRegLsrc src1, immL_minus1 src2) %{
   format %{ "NOT     $dst, $src1 ($src2) \t// long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_nor);
     __ nor($dst$$Register, $src1$$Register, $src1$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10644,7 +10150,6 @@ instruct andcL_reg_reg(iRegLdst dst, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "ANDC    $dst, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_andc);
     __ andc($dst$$Register, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10771,7 +10276,6 @@ instruct moveI2F_stack_reg(regF dst, stackSlotI src) %{
   format %{ "LFS     $dst, $src \t// MoveI2F" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_lfs);
     int Idisp = $src$$disp + frame_slots_bias($src$$base, ra_);
     __ lfs($dst$$FloatRegister, Idisp, $src$$base$$Register);
   %}
@@ -10859,7 +10363,6 @@ instruct moveReg(iRegLdst dst, iRegIsrc src) %{
   format %{ "MR      $dst, $src \t// replicate " %}
   // variable size, 0 or 4.
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ mr_if_needed($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -10874,7 +10377,6 @@ instruct castX2P(iRegPdst dst, iRegLsrc src) %{
   format %{ "MR      $dst, $src \t// Long->Ptr" %}
   // variable size, 0 or 4.
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ mr_if_needed($dst$$Register, $src$$Register);
   %}
  ins_pipe(pipe_class_default);
@@ -10887,7 +10389,6 @@ instruct castP2X(iRegLdst dst, iRegP_N2P src) %{
   format %{ "MR      $dst, $src \t// Ptr->Long" %}
   // variable size, 0 or 4.
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ mr_if_needed($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -11002,7 +10503,6 @@ instruct convI2Bool_andI_reg_immIpowerOf2(iRegIdst dst, iRegIsrc src, immIpowerO
   format %{ "RLWINM  $dst, $src, $mask \t// convI2B(AndI($src, $mask))" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rlwinm);
     __ rlwinm($dst$$Register, $src$$Register, (32-log2_long((jlong)$mask$$constant)) & 0x1f, 31, 31);
   %}
   ins_pipe(pipe_class_default);
@@ -11104,7 +10604,6 @@ instruct cmpLTMask_reg_immI0(iRegIdst dst, iRegIsrc src1, immI_0 src2) %{
   format %{ "SRAWI   $dst, $src1, $src2 \t// CmpLTMask" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_srawi);
     __ srawi($dst$$Register, $src1$$Register, 0x1f);
   %}
   ins_pipe(pipe_class_default);
@@ -11122,7 +10621,6 @@ instruct convB2I_reg(iRegIdst dst, iRegIsrc src, immI_24 amount) %{
   format %{ "EXTSB   $dst, $src \t// byte->int" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_extsb);
     __ extsb($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -11144,7 +10642,6 @@ instruct convS2I_reg(iRegIdst dst, iRegIsrc src, immI_16 amount) %{
   format %{ "EXTSH   $dst, $src \t// short->int" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_extsh);
     __ extsh($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -11157,7 +10654,6 @@ instruct sxtI_L2L_reg(iRegLdst dst, iRegLsrc src) %{
   format %{ "EXTSW   $dst, $src \t// long->long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_extsw);
     __ extsw($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -11168,7 +10664,6 @@ instruct convL2I_reg(iRegIdst dst, iRegLsrc src) %{
   format %{ "MR      $dst, $src \t// long->int" %}
   // variable size, 0 or 4
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_or);
     __ mr_if_needed($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -11182,7 +10677,6 @@ instruct convD2IRaw_regD(regD dst, regD src) %{
   format %{ "FCTIWZ $dst, $src \t// convD2I, $src != NaN" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);;
     __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -11197,7 +10691,7 @@ instruct cmovI_bso_stackSlotL(iRegIdst dst, flagsRegSrc crx, stackSlotL src) %{
 
   format %{ "cmovI   $crx, $dst, $src" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
   ins_pipe(pipe_class_default);
 %}
@@ -11211,7 +10705,7 @@ instruct cmovI_bso_reg(iRegIdst dst, flagsRegSrc crx, regD src) %{
 
   format %{ "cmovI   $crx, $dst, $src" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_bso_reg(dst, crx, src) );
   ins_pipe(pipe_class_default);
 %}
@@ -11364,7 +10858,6 @@ instruct convF2IRaw_regF(regF dst, regF src) %{
   format %{ "FCTIWZ $dst, $src \t// convF2I, $src != NaN" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);
     __ fctiwz($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -11409,7 +10902,6 @@ instruct convI2L_reg(iRegLdst dst, iRegIsrc src) %{
   format %{ "EXTSW   $dst, $src \t// int->long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_extsw);
     __ extsw($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -11423,7 +10915,6 @@ instruct zeroExtendL_regI(iRegLdst dst, iRegIsrc src, immL_32bits mask) %{
   format %{ "CLRLDI  $dst, $src, #32 \t// zero-extend int to long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ clrldi($dst$$Register, $src$$Register, 32);
   %}
   ins_pipe(pipe_class_default);
@@ -11437,7 +10928,6 @@ instruct zeroExtendL_regL(iRegLdst dst, iRegLsrc src, immL_32bits mask) %{
   format %{ "CLRLDI  $dst, $src, #32 \t// zero-extend int to long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicl);
     __ clrldi($dst$$Register, $src$$Register, 32);
   %}
   ins_pipe(pipe_class_default);
@@ -11451,7 +10941,6 @@ instruct convF2LRaw_regF(regF dst, regF src) %{
   format %{ "FCTIDZ $dst, $src \t// convF2L, $src != NaN" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);
     __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -11466,7 +10955,7 @@ instruct cmovL_bso_stackSlotL(iRegLdst dst, flagsRegSrc crx, stackSlotL src) %{
 
   format %{ "cmovL   $crx, $dst, $src" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_bso_stackSlotL(dst, crx, src) );
   ins_pipe(pipe_class_default);
 %}
@@ -11480,7 +10969,7 @@ instruct cmovL_bso_reg(iRegLdst dst, flagsRegSrc crx, regD src) %{
 
   format %{ "cmovL   $crx, $dst, $src" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT Compile::current()->do_hb_scheduling()*/ ? 12 : 8));
+  size(8);
   ins_encode( enc_cmove_bso_reg(dst, crx, src) );
   ins_pipe(pipe_class_default);
 %}
@@ -11627,7 +11116,6 @@ instruct convD2LRaw_regD(regD dst, regD src) %{
   format %{ "FCTIDZ $dst, $src \t// convD2L $src != NaN" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fctiwz);
     __ fctidz($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -11676,7 +11164,6 @@ instruct convL2DRaw_regD(regD dst, regD src) %{
   format %{ "FCFID $dst, $src \t// convL2D" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fcfid);
     __ fcfid($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -11688,7 +11175,6 @@ instruct convD2F_reg(regF dst, regD src) %{
   format %{ "FRSP    $dst, $src \t// convD2F" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_frsp);
     __ frsp($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -11721,7 +11207,6 @@ instruct convL2FRaw_regF(regF dst, regD src) %{
   format %{ "FCFIDS $dst, $src \t// convL2F" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fcfid);
     __ fcfids($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -11850,7 +11335,6 @@ instruct convF2D_reg(regD dst, regF src) %{
   format %{ "FMR     $dst, $src \t// float->double" %}
   // variable size, 0 or 4
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fmr);
     __ fmr_if_needed($dst$$FloatRegister, $src$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -11865,7 +11349,6 @@ instruct cmpI_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
   size(4);
   format %{ "CMPW    $crx, $src1, $src2" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmp);
     __ cmpw($crx$$CondRegister, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_compare);
@@ -11876,7 +11359,6 @@ instruct cmpI_reg_imm16(flagsReg crx, iRegIsrc src1, immI16 src2) %{
   format %{ "CMPWI   $crx, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpi);
     __ cmpwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_compare);
@@ -11889,7 +11371,6 @@ instruct testI_reg_imm(flagsRegCR0 cr0, iRegIsrc src1, uimmI16 src2, immI_0 zero
   format %{ "ANDI    R0, $src1, $src2 \t// BTST int" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
     __ andi_(R0, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_compare);
@@ -11900,7 +11381,6 @@ instruct cmpL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "CMPD    $crx, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmp);
     __ cmpd($crx$$CondRegister, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_compare);
@@ -11911,7 +11391,6 @@ instruct cmpL_reg_imm16(flagsReg crx, iRegLsrc src1, immL16 src2) %{
   format %{ "CMPDI   $crx, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpi);
     __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_compare);
@@ -11923,7 +11402,6 @@ instruct cmpUL_reg_reg(flagsReg crx, iRegLsrc src1, iRegLsrc src2) %{
   format %{ "CMPLD   $crx, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
     __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_compare);
@@ -11934,7 +11412,6 @@ instruct cmpUL_reg_imm16(flagsReg crx, iRegLsrc src1, uimmL16 src2) %{
   format %{ "CMPLDI  $crx, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpli);
     __ cmpldi($crx$$CondRegister, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_compare);
@@ -11946,7 +11423,6 @@ instruct testL_reg_reg(flagsRegCR0 cr0, iRegLsrc src1, iRegLsrc src2, immL_0 zer
   format %{ "AND     R0, $src1, $src2 \t// BTST long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_and_);
     __ and_(R0, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_compare);
@@ -11958,7 +11434,6 @@ instruct testL_reg_imm(flagsRegCR0 cr0, iRegLsrc src1, uimmL16 src2, immL_0 zero
   format %{ "ANDI    R0, $src1, $src2 \t// BTST long" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_andi_);
     __ andi_(R0, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_compare);
@@ -11973,16 +11448,14 @@ instruct cmovI_conIvalueMinus1_conIvalue1(iRegIdst dst, flagsRegSrc crx) %{
 
   format %{ "cmovI   $crx, $dst, -1, 0, +1" %}
   // Worst case is branch + move + branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORTInsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 20 : 16));
+  size(16);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmove);
     Label done;
     // li(Rdst, 0);              // equal -> 0
     __ beq($crx$$CondRegister, done);
     __ li($dst$$Register, 1);    // greater -> +1
     __ bgt($crx$$CondRegister, done);
     __ li($dst$$Register, -1);   // unordered or less -> -1
-    // TODO: PPC port__ endgroup_if_needed(_size == 20);
     __ bind(done);
   %}
   ins_pipe(pipe_class_compare);
@@ -12071,7 +11544,6 @@ instruct rangeCheck_iReg_uimm15(cmpOp cmp, iRegIsrc src_length, uimmI15 index, l
   format %{ "TWI     $index $cmp $src_length \t// RangeCheck => trap $labl" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_twi);
     if ($cmp$$cmpcode == 0x1 /* less_equal */) {
       __ trap_range_check_le($src_length$$Register, $index$$constant);
     } else {
@@ -12098,7 +11570,6 @@ instruct rangeCheck_iReg_iReg(cmpOp cmp, iRegIsrc src_index, iRegIsrc src_length
   format %{ "TW      $src_index $cmp $src_length \t// RangeCheck => trap $labl" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_tw);
     if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
       __ trap_range_check_ge($src_index$$Register, $src_length$$Register);
     } else {
@@ -12125,7 +11596,6 @@ instruct rangeCheck_uimm15_iReg(cmpOp cmp, iRegIsrc src_index, uimmI15 length, l
   format %{ "TWI     $src_index $cmp $length \t// RangeCheck => trap $labl" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_twi);
     if ($cmp$$cmpcode == 0x0 /* greater_equal */) {
       __ trap_range_check_ge($src_index$$Register, $length$$constant);
     } else {
@@ -12143,7 +11613,6 @@ instruct compU_reg_reg(flagsReg crx, iRegIsrc src1, iRegIsrc src2) %{
   format %{ "CMPLW   $crx, $src1, $src2 \t// unsigned" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
     __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_compare);
@@ -12154,7 +11623,6 @@ instruct compU_reg_uimm16(flagsReg crx, iRegIsrc src1, uimmI16 src2) %{
   size(4);
   format %{ "CMPLWI  $crx, $src1, $src2" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpli);
     __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_compare);
@@ -12176,7 +11644,6 @@ instruct zeroCheckN_iReg_imm0(cmpOp cmp, iRegNsrc value, immN_0 zero, label labl
   format %{ "TDI     $value $cmp $zero \t// ZeroCheckN => trap $labl" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
     if ($cmp$$cmpcode == 0xA) {
       __ trap_null_check($value$$Register);
     } else {
@@ -12197,7 +11664,6 @@ instruct cmpN_reg_reg(flagsReg crx, iRegNsrc src1, iRegNsrc src2) %{
   ins_cost(2);
   format %{ "CMPLW   $crx, $src1, $src2 \t// compressed ptr" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
     __ cmplw($crx$$CondRegister, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_compare);
@@ -12211,7 +11677,6 @@ instruct cmpN_reg_imm0(flagsReg crx, iRegNsrc src1, immN_0 src2) %{
   format %{ "CMPLWI  $crx, $src1, $src2 \t// compressed ptr" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpli);
     __ cmplwi($crx$$CondRegister, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_compare);
@@ -12233,7 +11698,6 @@ instruct zeroCheckP_reg_imm0(cmpOp cmp, iRegP_N2P value, immP_0 zero, label labl
   format %{ "TDI     $value $cmp $zero \t// ZeroCheckP => trap $labl" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
     if ($cmp$$cmpcode == 0xA) {
       __ trap_null_check($value$$Register);
     } else {
@@ -12252,7 +11716,6 @@ instruct cmpP_reg_reg(flagsReg crx, iRegP_N2P src1, iRegP_N2P src2) %{
   format %{ "CMPLD   $crx, $src1, $src2 \t// ptr" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
     __ cmpld($crx$$CondRegister, $src1$$Register, $src2$$Register);
   %}
   ins_pipe(pipe_class_compare);
@@ -12263,7 +11726,6 @@ instruct cmpP_reg_null(flagsReg crx, iRegP_N2P src1, immP_0or1 src2) %{
   format %{ "CMPLDI   $crx, $src1, $src2 \t// ptr" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpl);
     __ cmpldi($crx$$CondRegister, $src1$$Register, (int)((short)($src2$$constant & 0xFFFF)));
   %}
   ins_pipe(pipe_class_compare);
@@ -12280,7 +11742,6 @@ instruct cmpP_reg_imm16(flagsReg crx, iRegPsrc src1, immL16 src2) %{
   format %{ "CMPDI   $crx, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmpi);
     __ cmpdi($crx$$CondRegister, $src1$$Register, $src2$$constant);
   %}
   ins_pipe(pipe_class_compare);
@@ -12297,7 +11758,6 @@ instruct cmpFUnordered_reg_reg(flagsReg crx, regF src1, regF src2) %{
   format %{ "cmpFUrd $crx, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu);
     __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -12312,14 +11772,12 @@ instruct cmov_bns_less(flagsReg crx) %{
 
   format %{ "cmov    $crx" %}
   // Worst case is branch + move + stop, no stop without scheduler.
-  size((false /* TODO: PPC PORT(InsertEndGroupPPC64 && Compile::current()->do_hb_scheduling())*/ ? 16 : 12));
+  size(12);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cmovecr);
     Label done;
     __ bns($crx$$CondRegister, done);        // not unordered -> keep crx
     __ li(R0, 0);
     __ cmpwi($crx$$CondRegister, R0, 1);     // unordered -> set crx to 'less'
-    // TODO PPC port __ endgroup_if_needed(_size == 16);
     __ bind(done);
   %}
   ins_pipe(pipe_class_default);
@@ -12412,7 +11870,6 @@ instruct cmpDUnordered_reg_reg(flagsReg crx, regD src1, regD src2) %{
   format %{ "cmpFUrd $crx, $src1, $src2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fcmpu);
     __ fcmpu($crx$$CondRegister, $src1$$FloatRegister, $src2$$FloatRegister);
   %}
   ins_pipe(pipe_class_default);
@@ -12617,7 +12074,6 @@ instruct branch(label labl) %{
   format %{ "B       $labl" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_b);
      Label d;    // dummy
      __ bind(d);
      Label* p = $labl$$label;
@@ -12657,7 +12113,6 @@ instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
   // Same match rule as `branchCon'.
   match(If cmp crx);
   effect(USE crx, USE lbl);
-  predicate(!false /* TODO: PPC port HB_Schedule*/);
   // Higher cost than `branchCon'.
   ins_cost(5*BRANCH_COST);
 
@@ -12670,26 +12125,6 @@ instruct branchConFar(cmpOp cmp, flagsRegSrc crx, label lbl) %{
   ins_pipe(pipe_class_default);
 %}
 
-// Conditional Branch used with Power6 scheduler (can be far or short).
-instruct branchConSched(cmpOp cmp, flagsRegSrc crx, label lbl) %{
-  // Same match rule as `branchCon'.
-  match(If cmp crx);
-  effect(USE crx, USE lbl);
-  predicate(false /* TODO: PPC port HB_Schedule*/);
-  // Higher cost than `branchCon'.
-  ins_cost(5*BRANCH_COST);
-
-  // Actually size doesn't depend on alignment but on shortening.
-  ins_variable_size_depending_on_alignment(true);
-  // long variant.
-  ins_short_branch(0);
-
-  format %{ "B_FAR$cmp $crx, $lbl" %}
-  size(8); // worst case
-  ins_encode( enc_bc_short_far(crx, cmp, lbl) );
-  ins_pipe(pipe_class_default);
-%}
-
 instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
   match(CountedLoopEnd cmp crx);
   effect(USE labl);
@@ -12707,7 +12142,6 @@ instruct branchLoopEnd(cmpOp cmp, flagsRegSrc crx, label labl) %{
 instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
   match(CountedLoopEnd cmp crx);
   effect(USE labl);
-  predicate(!false /* TODO: PPC port HB_Schedule */);
   ins_cost(BRANCH_COST);
 
   // Long variant.
@@ -12719,25 +12153,6 @@ instruct branchLoopEndFar(cmpOp cmp, flagsRegSrc crx, label labl) %{
   ins_pipe(pipe_class_default);
 %}
 
-// Conditional Branch used with Power6 scheduler (can be far or short).
-instruct branchLoopEndSched(cmpOp cmp, flagsRegSrc crx, label labl) %{
-  match(CountedLoopEnd cmp crx);
-  effect(USE labl);
-  predicate(false /* TODO: PPC port HB_Schedule */);
-  // Higher cost than `branchCon'.
-  ins_cost(5*BRANCH_COST);
-
-  // Actually size doesn't depend on alignment but on shortening.
-  ins_variable_size_depending_on_alignment(true);
-  // Long variant.
-  ins_short_branch(0);
-
-  format %{ "B_FAR$cmp $crx, $labl \t// counted loop end" %}
-  size(8); // worst case
-  ins_encode( enc_bc_short_far(crx, cmp, labl) );
-  ins_pipe(pipe_class_default);
-%}
-
 // ============================================================================
 // Java runtime operations, intrinsics and other complex operations.
 
@@ -12757,7 +12172,6 @@ instruct partialSubtypeCheck(iRegPdst result, iRegP_N2P subklass, iRegP_N2P supe
 
   format %{ "PartialSubtypeCheck $result = ($subklass instanceOf $superklass) tmp: $tmp_klass, $tmp_arrayptr" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ check_klass_subtype_slow_path($subklass$$Register, $superklass$$Register, $tmp_arrayptr$$Register,
                                      $tmp_klass$$Register, NULL, $result$$Register);
   %}
@@ -12773,7 +12187,6 @@ instruct cmpFastLock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1, iR
 
   format %{ "FASTLOCK  $oop, $box, $tmp1, $tmp2" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
                                  $tmp1$$Register, $tmp2$$Register, /*tmp3*/ R0,
                                  UseBiasedLocking && !UseOptoBiasInlining);
@@ -12792,7 +12205,6 @@ instruct cmpFastLock_tm(flagsReg crx, iRegPdst oop, rarg2RegP box, iRegPdst tmp1
 
   format %{ "FASTLOCK  $oop, $box, $tmp1, $tmp2, $tmp3 (TM)" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ compiler_fast_lock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
                                  $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
                                  /*Biased Locking*/ false,
@@ -12813,7 +12225,6 @@ instruct cmpFastUnlock(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp1,
 
   format %{ "FASTUNLOCK  $oop, $box, $tmp1, $tmp2" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
                                    $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
                                    UseBiasedLocking && !UseOptoBiasInlining,
@@ -12832,7 +12243,6 @@ instruct cmpFastUnlock_tm(flagsReg crx, iRegPdst oop, iRegPdst box, iRegPdst tmp
 
   format %{ "FASTUNLOCK  $oop, $box, $tmp1, $tmp2 (TM)" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ compiler_fast_unlock_object($crx$$CondRegister, $oop$$Register, $box$$Register,
                                    $tmp1$$Register, $tmp2$$Register, $tmp3$$Register,
                                    /*Biased Locking*/ false, /*TM*/ true);
@@ -12850,7 +12260,6 @@ instruct align_addr(iRegPdst dst, iRegPsrc src, immLnegpow2 mask) %{
   format %{ "ANDDI   $dst, $src, $mask \t// next aligned address" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldicr);
     __ clrrdi($dst$$Register, $src$$Register, log2_long((jlong)-$mask$$constant));
   %}
   ins_pipe(pipe_class_default);
@@ -12863,7 +12272,6 @@ instruct array_size(iRegLdst dst, iRegPsrc end, iRegPsrc start) %{
   format %{ "SUB     $dst, $end, $start \t// array size in bytes" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_subf);
     __ subf($dst$$Register, $start$$Register, $end$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -12877,7 +12285,6 @@ instruct inlineCallClearArrayShort(immLmax30 cnt, rarg2RegP base, Universe dummy
 
   format %{ "ClearArray $cnt, $base" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ clear_memory_constlen($base$$Register, $cnt$$constant, R0); // kills base, R0
   %}
   ins_pipe(pipe_class_default);
@@ -12891,7 +12298,6 @@ instruct inlineCallClearArrayLarge(immL cnt, rarg2RegP base, Universe dummy, iRe
 
   format %{ "ClearArray $cnt, $base \t// KILL $tmp" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ clear_memory_doubleword($base$$Register, $tmp$$Register, R0, $cnt$$constant); // kills base, R0
   %}
   ins_pipe(pipe_class_default);
@@ -12905,7 +12311,6 @@ instruct inlineCallClearArray(rarg1RegL cnt, rarg2RegP base, Universe dummy, reg
 
   format %{ "ClearArray $cnt, $base" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ clear_memory_doubleword($base$$Register, $cnt$$Register, R0); // kills cnt, base, R0
   %}
   ins_pipe(pipe_class_default);
@@ -12919,7 +12324,6 @@ instruct string_compareL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4Re
   ins_cost(300);
   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ string_compare($str1$$Register, $str2$$Register,
                       $cnt1$$Register, $cnt2$$Register,
                       $tmp$$Register,
@@ -12936,7 +12340,6 @@ instruct string_compareU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4Re
   ins_cost(300);
   format %{ "String Compare char[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ string_compare($str1$$Register, $str2$$Register,
                       $cnt1$$Register, $cnt2$$Register,
                       $tmp$$Register,
@@ -12953,7 +12356,6 @@ instruct string_compareLU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4R
   ins_cost(300);
   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ string_compare($str1$$Register, $str2$$Register,
                       $cnt1$$Register, $cnt2$$Register,
                       $tmp$$Register,
@@ -12970,7 +12372,6 @@ instruct string_compareUL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt1, rarg4R
   ins_cost(300);
   format %{ "String Compare byte[] $str1,$cnt1,$str2,$cnt2 -> $result \t// KILL $tmp" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ string_compare($str2$$Register, $str1$$Register,
                       $cnt2$$Register, $cnt1$$Register,
                       $tmp$$Register,
@@ -12987,7 +12388,6 @@ instruct string_equalsL(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst
   ins_cost(300);
   format %{ "String Equals byte[] $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ array_equals(false, $str1$$Register, $str2$$Register,
                     $cnt$$Register, $tmp$$Register,
                     $result$$Register, true /* byte */);
@@ -13003,7 +12403,6 @@ instruct string_equalsU(rarg1RegP str1, rarg2RegP str2, rarg3RegI cnt, iRegIdst
   ins_cost(300);
   format %{ "String Equals char[]  $str1,$str2,$cnt -> $result \t// KILL $tmp" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ array_equals(false, $str1$$Register, $str2$$Register,
                     $cnt$$Register, $tmp$$Register,
                     $result$$Register, false /* byte */);
@@ -13019,7 +12418,6 @@ instruct array_equalsB(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
   ins_cost(300);
   format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ array_equals(true, $ary1$$Register, $ary2$$Register,
                     $tmp1$$Register, $tmp2$$Register,
                     $result$$Register, true /* byte */);
@@ -13035,7 +12433,6 @@ instruct array_equalsC(rarg1RegP ary1, rarg2RegP ary2, iRegIdst result,
   ins_cost(300);
   format %{ "Array Equals $ary1,$ary2 -> $result \t// KILL $tmp1,$tmp2" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ array_equals(true, $ary1$$Register, $ary2$$Register,
                     $tmp1$$Register, $tmp2$$Register,
                     $result$$Register, false /* byte */);
@@ -13057,7 +12454,6 @@ instruct indexOf_imm1_char_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt
             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
 
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     immPOper *needleOper = (immPOper *)$needleImm;
     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
@@ -13091,7 +12487,6 @@ instruct indexOf_imm1_char_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt
             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
 
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     immPOper *needleOper = (immPOper *)$needleImm;
     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
@@ -13118,7 +12513,6 @@ instruct indexOf_imm1_char_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycn
             "-> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
 
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     immPOper *needleOper = (immPOper *)$needleImm;
     const TypeOopPtr *t = needleOper->type()->isa_oopptr();
     ciTypeArray* needle_values = t->const_oop()->as_type_array();  // Pointer to live char *
@@ -13146,7 +12540,6 @@ instruct indexOf_imm1_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Node *ndl = in(operand_index($needle));  // The node that defines needle.
     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
     guarantee(needle_values, "sanity");
@@ -13181,7 +12574,6 @@ instruct indexOf_imm1_L(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Node *ndl = in(operand_index($needle));  // The node that defines needle.
     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
     guarantee(needle_values, "sanity");
@@ -13209,7 +12601,6 @@ instruct indexOf_imm1_UL(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
   format %{ "String IndexOf SCL1 $haystack[0..$haycnt], $needle[0..$needlecntImm]"
             " -> $result \t// KILL $haycnt, $needle, $tmp1, $tmp2, $cr0, $cr1" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Node *ndl = in(operand_index($needle));  // The node that defines needle.
     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
     guarantee(needle_values, "sanity");
@@ -13232,7 +12623,6 @@ instruct indexOfChar_U(iRegIdst result, iRegPsrc haystack, iRegIsrc haycnt,
   format %{ "String IndexOfChar $haystack[0..$haycnt], $ch"
             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $cr0, $cr1" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ string_indexof_char($result$$Register,
                            $haystack$$Register, $haycnt$$Register,
                            $ch$$Register, 0 /* this is not used if the character is already in a register */,
@@ -13257,7 +12647,6 @@ instruct indexOf_imm_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Node *ndl = in(operand_index($needle));  // The node that defines needle.
     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
 
@@ -13285,7 +12674,6 @@ instruct indexOf_imm_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt,
   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Node *ndl = in(operand_index($needle));  // The node that defines needle.
     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
 
@@ -13313,7 +12701,6 @@ instruct indexOf_imm_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt
   format %{ "String IndexOf SCL $haystack[0..$haycnt], $needle[0..$needlecntImm]"
             " -> $result \t// KILL $haycnt, $tmp1, $tmp2, $tmp3, $tmp4, $tmp5, $cr0, $cr1" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Node *ndl = in(operand_index($needle));  // The node that defines needle.
     ciTypeArray* needle_values = ndl->bottom_type()->is_aryptr()->const_oop()->as_type_array();
 
@@ -13338,7 +12725,6 @@ instruct indexOf_U(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRe
   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ string_indexof($result$$Register,
                       $haystack$$Register, $haycnt$$Register,
                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
@@ -13360,7 +12746,6 @@ instruct indexOf_L(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iRe
   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ string_indexof($result$$Register,
                       $haystack$$Register, $haycnt$$Register,
                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
@@ -13382,7 +12767,6 @@ instruct indexOf_UL(iRegIdst result, iRegPsrc haystack, rscratch1RegI haycnt, iR
   format %{ "String IndexOf $haystack[0..$haycnt], $needle[0..$needlecnt]"
              " -> $result \t// KILL $haycnt, $needlecnt, $tmp1, $tmp2, $tmp3, $tmp4, $cr0, $cr1" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ string_indexof($result$$Register,
                       $haystack$$Register, $haycnt$$Register,
                       $needle$$Register, NULL, $needlecnt$$Register, 0,  // needlecnt not constant.
@@ -13400,7 +12784,6 @@ instruct string_compress(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst re
   ins_cost(300);
   format %{ "String Compress $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Label Lskip, Ldone;
     __ li($result$$Register, 0);
     __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
@@ -13423,7 +12806,6 @@ instruct string_inflate(Universe dummy, rarg1RegP src, rarg2RegP dst, iRegIsrc l
   ins_cost(300);
   format %{ "String Inflate $src,$dst,$len \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Label Ldone;
     __ string_inflate_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
                          $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register);
@@ -13444,7 +12826,6 @@ instruct has_negatives(rarg1RegP ary1, iRegIsrc len, iRegIdst result, iRegLdst t
   ins_cost(300);
   format %{ "has negatives byte[] $ary1,$len -> $result \t// KILL $tmp1, $tmp2" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ has_negatives($ary1$$Register, $len$$Register, $result$$Register,
                      $tmp1$$Register, $tmp2$$Register);
   %}
@@ -13460,7 +12841,6 @@ instruct encode_iso_array(rarg1RegP src, rarg2RegP dst, iRegIsrc len, iRegIdst r
   ins_cost(300);
   format %{ "Encode array $src,$dst,$len -> $result \t// KILL $tmp1, $tmp2, $tmp3, $tmp4, $tmp5" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     Label Lslow, Lfailure1, Lfailure2, Ldone;
     __ string_compress_16($src$$Register, $dst$$Register, $len$$Register, $tmp1$$Register,
                           $tmp2$$Register, $tmp3$$Register, $tmp4$$Register, $tmp5$$Register, Lfailure1);
@@ -13517,7 +12897,6 @@ instruct minI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegC
   ins_cost(DEFAULT_COST*2);
 
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ cmpw(CCR0, $src1$$Register, $src2$$Register);
     __ isel($dst$$Register, CCR0, Assembler::less, /*invert*/false, $src1$$Register, $src2$$Register);
   %}
@@ -13551,7 +12930,6 @@ instruct maxI_reg_reg_isel(iRegIdst dst, iRegIsrc src1, iRegIsrc src2, flagsRegC
   ins_cost(DEFAULT_COST*2);
 
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ cmpw(CCR0, $src1$$Register, $src2$$Register);
     __ isel($dst$$Register, CCR0, Assembler::greater, /*invert*/false, $src1$$Register, $src2$$Register);
   %}
@@ -13569,7 +12947,6 @@ instruct popCountI(iRegIdst dst, iRegIsrc src) %{
   format %{ "POPCNTW $dst, $src" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_popcntb);
     __ popcntw($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -13584,7 +12961,6 @@ instruct popCountL(iRegIdst dst, iRegLsrc src) %{
   format %{ "POPCNTD $dst, $src" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_popcntb);
     __ popcntd($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -13598,7 +12974,6 @@ instruct countLeadingZerosI(iRegIdst dst, iRegIsrc src) %{
   format %{ "CNTLZW  $dst, $src" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cntlzw);
     __ cntlzw($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -13612,7 +12987,6 @@ instruct countLeadingZerosL(iRegIdst dst, iRegLsrc src) %{
   format %{ "CNTLZD  $dst, $src" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd);
     __ cntlzd($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -13626,7 +13000,6 @@ instruct countLeadingZerosP(iRegIdst dst, iRegPsrc src) %{
   format %{ "CNTLZD  $dst, $src" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_cntlzd);
     __ cntlzd($dst$$Register, $src$$Register);
   %}
   ins_pipe(pipe_class_default);
@@ -13703,7 +13076,6 @@ instruct insrwi_a(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{
   format %{ "INSRWI  $dst, $src, $pos, $shift" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi);
     __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -13717,7 +13089,6 @@ instruct insrwi(iRegIdst dst, iRegIsrc src, immI16 pos, immI16 shift) %{
   format %{ "INSRWI  $dst, $src, $pos, $shift" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rlwimi);
     __ insrwi($dst$$Register, $src$$Register, $shift$$constant, $pos$$constant);
   %}
   ins_pipe(pipe_class_default);
@@ -14112,7 +13483,6 @@ instruct repl32(iRegLdst dst) %{
   format %{ "INSRDI  $dst, #0, $dst, #32 \t// replicate" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
     __ insrdi($dst$$Register, $dst$$Register, 32, 0);
   %}
   ins_pipe(pipe_class_default);
@@ -14126,7 +13496,6 @@ instruct repl48(iRegLdst dst) %{
   format %{ "INSRDI  $dst, #0, $dst, #48 \t// replicate" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
     __ insrdi($dst$$Register, $dst$$Register, 48, 0);
   %}
   ins_pipe(pipe_class_default);
@@ -14140,7 +13509,6 @@ instruct repl56(iRegLdst dst) %{
   format %{ "INSRDI  $dst, #0, $dst, #56 \t// replicate" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_rldimi);
     __ insrdi($dst$$Register, $dst$$Register, 56, 0);
   %}
   ins_pipe(pipe_class_default);
@@ -14163,7 +13531,6 @@ instruct repl8B_immI0(iRegLdst dst, immI_0 zero) %{
   format %{ "LI      $dst, #0 \t// replicate8B" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
   %}
   ins_pipe(pipe_class_default);
@@ -14175,7 +13542,6 @@ instruct repl8B_immIminus1(iRegLdst dst, immI_minus1 src) %{
   format %{ "LI      $dst, #-1 \t// replicate8B" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
   %}
   ins_pipe(pipe_class_default);
@@ -14237,7 +13603,6 @@ instruct repl4S_immI0(iRegLdst dst, immI_0 zero) %{
   format %{ "LI      $dst, #0 \t// replicate4S" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
   %}
   ins_pipe(pipe_class_default);
@@ -14249,7 +13614,6 @@ instruct repl4S_immIminus1(iRegLdst dst, immI_minus1 src) %{
   format %{ "LI      $dst, -1 \t// replicate4S" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
   %}
   ins_pipe(pipe_class_default);
@@ -14311,7 +13675,6 @@ instruct repl2I_immI0(iRegLdst dst, immI_0 zero) %{
   format %{ "LI      $dst, #0 \t// replicate2I" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, (int)((short)($zero$$constant & 0xFFFF)));
   %}
   ins_pipe(pipe_class_default);
@@ -14323,7 +13686,6 @@ instruct repl2I_immIminus1(iRegLdst dst, immI_minus1 src) %{
   format %{ "LI      $dst, -1 \t// replicate2I" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, (int)((short)($src$$constant & 0xFFFF)));
   %}
   ins_pipe(pipe_class_default);
@@ -14401,7 +13763,6 @@ instruct repl2F_immF0(iRegLdst dst, immF_0 zero) %{
 
   format %{ "LI      $dst, #0 \t// replicate2F" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_addi);
     __ li($dst$$Register, 0x0);
   %}
   ins_pipe(pipe_class_default);
@@ -14849,7 +14210,6 @@ instruct overflowAddL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
 
   format %{ "add_    $op1, $op2\t# overflow check long" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ li(R0, 0);
     __ mtxer(R0); // clear XER.SO
     __ addo_(R0, $op1$$Register, $op2$$Register);
@@ -14862,7 +14222,6 @@ instruct overflowSubL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
 
   format %{ "subfo_  R0, $op2, $op1\t# overflow check long" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ li(R0, 0);
     __ mtxer(R0); // clear XER.SO
     __ subfo_(R0, $op2$$Register, $op1$$Register);
@@ -14875,7 +14234,6 @@ instruct overflowNegL_reg(flagsRegCR0 cr0, immL_0 zero, iRegLsrc op2) %{
 
   format %{ "nego_   R0, $op2\t# overflow check long" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ li(R0, 0);
     __ mtxer(R0); // clear XER.SO
     __ nego_(R0, $op2$$Register);
@@ -14888,7 +14246,6 @@ instruct overflowMulL_reg_reg(flagsRegCR0 cr0, iRegLsrc op1, iRegLsrc op2) %{
 
   format %{ "mulldo_ R0, $op1, $op2\t# overflow check long" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ li(R0, 0);
     __ mtxer(R0); // clear XER.SO
     __ mulldo_(R0, $op1$$Register, $op2$$Register);
@@ -15153,7 +14510,6 @@ instruct CallLeafDirect(method meth) %{
   format %{ "BCTRL     \t// leaf call $meth ==> " %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_bctrl);
     __ bctrl();
   %}
   ins_pipe(pipe_class_call);
@@ -15202,7 +14558,6 @@ instruct TailCalljmpInd(iRegPdstNoScratch jump_target, inline_cache_regP method_
             "BCTR         \t// tail call" %}
   size(8);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ mtctr($jump_target$$Register);
     __ bctr();
   %}
@@ -15215,7 +14570,6 @@ instruct Ret() %{
   format %{ "BLR      \t// branch to link register" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_blr);
     // LR is restored in MachEpilogNode. Just do the RET here.
     __ blr();
   %}
@@ -15237,7 +14591,6 @@ instruct tailjmpInd(iRegPdstNoScratch jump_target, rarg1RegP ex_oop) %{
             "BCTR     \t// TailJump, exception oop: $ex_oop" %}
   size(12);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     __ ld(R4_ARG2/* issuing pc */, _abi(lr), R1_SP);
     __ mtctr($jump_target$$Register);
     __ bctr();
@@ -15266,7 +14619,6 @@ instruct RethrowException() %{
 
   format %{ "Jmp     rethrow_stub" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_compound);
     cbuf.set_insts_mark();
     __ b64_patchable((address)OptoRuntime::rethrow_stub(), relocInfo::runtime_call_type);
   %}
@@ -15281,7 +14633,6 @@ instruct ShouldNotReachHere() %{
   format %{ "ShouldNotReachHere" %}
   ins_encode %{
     if (is_reachable()) {
-      // TODO: PPC port $archOpcode(ppc64Opcode_tdi);
       __ stop(_halt_reason);
     }
   %}
@@ -15315,7 +14666,6 @@ instruct endGroup() %{
   format %{ "End Bundle (ori r1, r1, 0)" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_endgroup);
     __ endgroup();
   %}
   ins_pipe(pipe_class_default);
@@ -15331,7 +14681,6 @@ instruct fxNop() %{
   format %{ "fxNop" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fmr);
     __ nop();
   %}
   ins_pipe(pipe_class_default);
@@ -15345,7 +14694,6 @@ instruct fpNop0() %{
   format %{ "fpNop0" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fmr);
     __ fpnop0();
   %}
   ins_pipe(pipe_class_default);
@@ -15359,7 +14707,6 @@ instruct fpNop1() %{
   format %{ "fpNop1" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_fmr);
     __ fpnop1();
   %}
   ins_pipe(pipe_class_default);
@@ -15370,7 +14717,6 @@ instruct brNop0() %{
   size(4);
   format %{ "brNop0" %}
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_mcrf);
     __ brnop0();
   %}
   ins_is_nop(true);
@@ -15385,7 +14731,6 @@ instruct brNop1() %{
   format %{ "brNop1" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_mcrf);
     __ brnop1();
   %}
   ins_pipe(pipe_class_default);
@@ -15399,7 +14744,6 @@ instruct brNop2() %{
   format %{ "brNop2" %}
   size(4);
   ins_encode %{
-    // TODO: PPC port $archOpcode(ppc64Opcode_mcrf);
     __ brnop2();
   %}
   ins_pipe(pipe_class_default);
diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.cpp b/src/hotspot/cpu/ppc/vm_version_ppc.cpp
index 9b729b5baa9..a1f2df08454 100644
--- a/src/hotspot/cpu/ppc/vm_version_ppc.cpp
+++ b/src/hotspot/cpu/ppc/vm_version_ppc.cpp
@@ -29,6 +29,7 @@
 #include "asm/macroAssembler.inline.hpp"
 #include "compiler/disassembler.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
@@ -116,13 +117,6 @@ void VM_Version::initialize() {
     FLAG_SET_ERGO(TrapBasedRangeChecks, false);
   }
 
-  // On Power6 test for section size.
-  if (PowerArchitecturePPC64 == 6) {
-    determine_section_size();
-  // TODO: PPC port } else {
-  // TODO: PPC port PdScheduling::power6SectorSize = 0x20;
-  }
-
   if (PowerArchitecturePPC64 >= 8) {
     if (FLAG_IS_DEFAULT(SuperwordUseVSX)) {
       FLAG_SET_ERGO(SuperwordUseVSX, true);
@@ -567,240 +561,6 @@ void VM_Version::print_features() {
   }
 }
 
-#ifdef COMPILER2
-// Determine section size on power6: If section size is 8 instructions,
-// there should be a difference between the two testloops of ~15 %. If
-// no difference is detected the section is assumed to be 32 instructions.
-void VM_Version::determine_section_size() {
-
-  int unroll = 80;
-
-  const int code_size = (2* unroll * 32 + 100)*BytesPerInstWord;
-
-  // Allocate space for the code.
-  ResourceMark rm;
-  CodeBuffer cb("detect_section_size", code_size, 0);
-  MacroAssembler* a = new MacroAssembler(&cb);
-
-  uint32_t *code = (uint32_t *)a->pc();
-  // Emit code.
-  void (*test1)() = (void(*)())(void *)a->function_entry();
-
-  Label l1;
-
-  a->li(R4, 1);
-  a->sldi(R4, R4, 28);
-  a->b(l1);
-  a->align(CodeEntryAlignment);
-
-  a->bind(l1);
-
-  for (int i = 0; i < unroll; i++) {
-    // Schleife 1
-    // ------- sector 0 ------------
-    // ;; 0
-    a->nop();                   // 1
-    a->fpnop0();                // 2
-    a->fpnop1();                // 3
-    a->addi(R4,R4, -1); // 4
-
-    // ;;  1
-    a->nop();                   // 5
-    a->fmr(F6, F6);             // 6
-    a->fmr(F7, F7);             // 7
-    a->endgroup();              // 8
-    // ------- sector 8 ------------
-
-    // ;;  2
-    a->nop();                   // 9
-    a->nop();                   // 10
-    a->fmr(F8, F8);             // 11
-    a->fmr(F9, F9);             // 12
-
-    // ;;  3
-    a->nop();                   // 13
-    a->fmr(F10, F10);           // 14
-    a->fmr(F11, F11);           // 15
-    a->endgroup();              // 16
-    // -------- sector 16 -------------
-
-    // ;;  4
-    a->nop();                   // 17
-    a->nop();                   // 18
-    a->fmr(F15, F15);           // 19
-    a->fmr(F16, F16);           // 20
-
-    // ;;  5
-    a->nop();                   // 21
-    a->fmr(F17, F17);           // 22
-    a->fmr(F18, F18);           // 23
-    a->endgroup();              // 24
-    // ------- sector 24  ------------
-
-    // ;;  6
-    a->nop();                   // 25
-    a->nop();                   // 26
-    a->fmr(F19, F19);           // 27
-    a->fmr(F20, F20);           // 28
-
-    // ;;  7
-    a->nop();                   // 29
-    a->fmr(F21, F21);           // 30
-    a->fmr(F22, F22);           // 31
-    a->brnop0();                // 32
-
-    // ------- sector 32 ------------
-  }
-
-  // ;; 8
-  a->cmpdi(CCR0, R4, unroll);   // 33
-  a->bge(CCR0, l1);             // 34
-  a->blr();
-
-  // Emit code.
-  void (*test2)() = (void(*)())(void *)a->function_entry();
-  // uint32_t *code = (uint32_t *)a->pc();
-
-  Label l2;
-
-  a->li(R4, 1);
-  a->sldi(R4, R4, 28);
-  a->b(l2);
-  a->align(CodeEntryAlignment);
-
-  a->bind(l2);
-
-  for (int i = 0; i < unroll; i++) {
-    // Schleife 2
-    // ------- sector 0 ------------
-    // ;; 0
-    a->brnop0();                  // 1
-    a->nop();                     // 2
-    //a->cmpdi(CCR0, R4, unroll);
-    a->fpnop0();                  // 3
-    a->fpnop1();                  // 4
-    a->addi(R4,R4, -1);           // 5
-
-    // ;; 1
-
-    a->nop();                     // 6
-    a->fmr(F6, F6);               // 7
-    a->fmr(F7, F7);               // 8
-    // ------- sector 8 ---------------
-
-    // ;; 2
-    a->endgroup();                // 9
-
-    // ;; 3
-    a->nop();                     // 10
-    a->nop();                     // 11
-    a->fmr(F8, F8);               // 12
-
-    // ;; 4
-    a->fmr(F9, F9);               // 13
-    a->nop();                     // 14
-    a->fmr(F10, F10);             // 15
-
-    // ;; 5
-    a->fmr(F11, F11);             // 16
-    // -------- sector 16 -------------
-
-    // ;; 6
-    a->endgroup();                // 17
-
-    // ;; 7
-    a->nop();                     // 18
-    a->nop();                     // 19
-    a->fmr(F15, F15);             // 20
-
-    // ;; 8
-    a->fmr(F16, F16);             // 21
-    a->nop();                     // 22
-    a->fmr(F17, F17);             // 23
-
-    // ;; 9
-    a->fmr(F18, F18);             // 24
-    // -------- sector 24 -------------
-
-    // ;; 10
-    a->endgroup();                // 25
-
-    // ;; 11
-    a->nop();                     // 26
-    a->nop();                     // 27
-    a->fmr(F19, F19);             // 28
-
-    // ;; 12
-    a->fmr(F20, F20);             // 29
-    a->nop();                     // 30
-    a->fmr(F21, F21);             // 31
-
-    // ;; 13
-    a->fmr(F22, F22);             // 32
-  }
-
-  // -------- sector 32 -------------
-  // ;; 14
-  a->cmpdi(CCR0, R4, unroll); // 33
-  a->bge(CCR0, l2);           // 34
-
-  a->blr();
-  uint32_t *code_end = (uint32_t *)a->pc();
-  a->flush();
-
-  cb.insts()->set_end((u_char*)code_end);
-
-  double loop1_seconds,loop2_seconds, rel_diff;
-  uint64_t start1, stop1;
-
-  start1 = os::current_thread_cpu_time(false);
-  (*test1)();
-  stop1 = os::current_thread_cpu_time(false);
-  loop1_seconds = (stop1- start1) / (1000 *1000 *1000.0);
-
-
-  start1 = os::current_thread_cpu_time(false);
-  (*test2)();
-  stop1 = os::current_thread_cpu_time(false);
-
-  loop2_seconds = (stop1 - start1) / (1000 *1000 *1000.0);
-
-  rel_diff = (loop2_seconds - loop1_seconds) / loop1_seconds *100;
-
-  if (PrintAssembly || PrintStubCode) {
-    ttyLocker ttyl;
-    tty->print_cr("Decoding section size detection stub at " INTPTR_FORMAT " before execution:", p2i(code));
-    // Use existing decode function. This enables the [MachCode] format which is needed to DecodeErrorFile.
-    Disassembler::decode(&cb, (u_char*)code, (u_char*)code_end, tty);
-    tty->print_cr("Time loop1 :%f", loop1_seconds);
-    tty->print_cr("Time loop2 :%f", loop2_seconds);
-    tty->print_cr("(time2 - time1) / time1 = %f %%", rel_diff);
-
-    if (rel_diff > 12.0) {
-      tty->print_cr("Section Size 8 Instructions");
-    } else{
-      tty->print_cr("Section Size 32 Instructions or Power5");
-    }
-  }
-
-#if 0 // TODO: PPC port
-  // Set sector size (if not set explicitly).
-  if (FLAG_IS_DEFAULT(Power6SectorSize128PPC64)) {
-    if (rel_diff > 12.0) {
-      PdScheduling::power6SectorSize = 0x20;
-    } else {
-      PdScheduling::power6SectorSize = 0x80;
-    }
-  } else if (Power6SectorSize128PPC64) {
-    PdScheduling::power6SectorSize = 0x80;
-  } else {
-    PdScheduling::power6SectorSize = 0x20;
-  }
-#endif
-  if (UsePower6SchedulerPPC64) Unimplemented();
-}
-#endif // COMPILER2
-
 void VM_Version::determine_features() {
 #if defined(ABI_ELFv2)
   // 1 InstWord per call for the blr instruction.
diff --git a/src/hotspot/cpu/ppc/vm_version_ppc.hpp b/src/hotspot/cpu/ppc/vm_version_ppc.hpp
index fa94a71d992..984bfd0140d 100644
--- a/src/hotspot/cpu/ppc/vm_version_ppc.hpp
+++ b/src/hotspot/cpu/ppc/vm_version_ppc.hpp
@@ -84,8 +84,7 @@ class VM_Version: public Abstract_VM_Version {
   static void print_features();
   static void determine_features(); // also measures cache line size
   static void config_dscr(); // Power 8: Configure Data Stream Control Register.
-  static void determine_section_size();
-  static void power6_micro_bench();
+
 public:
   // Initialization
   static void initialize();
diff --git a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp
index 3c468e751d5..24c8178f1dc 100644
--- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp
+++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp
@@ -1258,7 +1258,7 @@ void LIR_Assembler::emit_static_call_stub() {
 
   __ relocate(static_stub_Relocation::spec(call_pc));
 
-  // See also Matcher::interpreter_method_oop_reg().
+  // See also Matcher::interpreter_method_reg().
   AddressLiteral meta = __ allocate_metadata_address(NULL);
   bool success = __ load_const_from_toc(Z_method, meta);
 
diff --git a/src/hotspot/cpu/s390/globals_s390.hpp b/src/hotspot/cpu/s390/globals_s390.hpp
index ac9e096ee64..d8f97b9c93b 100644
--- a/src/hotspot/cpu/s390/globals_s390.hpp
+++ b/src/hotspot/cpu/s390/globals_s390.hpp
@@ -75,13 +75,11 @@ define_pd_global(bool, CompactStrings, true);
 // 8146801 (Short Array Allocation): No performance work done here yet.
 define_pd_global(intx, InitArrayShortSize, 1*BytesPerLong);
 
-#define ARCH_FLAGS(develop,      \
-                   product,      \
-                   diagnostic,   \
-                   experimental, \
-                   notproduct,   \
-                   range,        \
-                   constraint)   \
+#define ARCH_FLAGS(develop,                                                   \
+                   product,                                                   \
+                   notproduct,                                                \
+                   range,                                                     \
+                   constraint)                                                \
                                                                               \
   /* Reoptimize code-sequences of calls at runtime, e.g. replace an */        \
   /* indirect call by a direct call.                                */        \
@@ -117,4 +115,6 @@ define_pd_global(intx, InitArrayShortSize, 1*BytesPerLong);
   product(bool, TraceTraps, false, "Trace all traps the signal handler"       \
           "handles.")
 
+// end of ARCH_FLAGS
+
 #endif // CPU_S390_GLOBALS_S390_HPP
diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad
index 4235d009e8d..bb98182d781 100644
--- a/src/hotspot/cpu/s390/s390.ad
+++ b/src/hotspot/cpu/s390/s390.ad
@@ -278,8 +278,8 @@ alloc_class chunk2(
 // information in this architecture description.
 
 // 1) reg_class inline_cache_reg           (as defined in frame section)
-// 2) reg_class compiler_method_oop_reg    (as defined in frame section)
-// 2) reg_class interpreter_method_oop_reg (as defined in frame section)
+// 2) reg_class compiler_method_reg        (as defined in frame section)
+// 2) reg_class interpreter_method_reg     (as defined in frame section)
 // 3) reg_class stack_slots(/* one chunk of stack-based "registers" */)
 
 // Integer Register Classes
@@ -1569,11 +1569,6 @@ const bool Matcher::match_rule_supported_vector(int opcode, int vlen, BasicType
   return ret_value;  // Per default match rules are supported.
 }
 
-int Matcher::regnum_to_fpu_offset(int regnum) {
-  ShouldNotReachHere();
-  return regnum - 32; // The FP registers are in the second chunk.
-}
-
 const bool Matcher::has_predicated_vectors(void) {
   return false;
 }
@@ -2456,9 +2451,6 @@ source %{
 // Definition of frame structure and management information.
 
 frame %{
-  // What direction does stack grow in (assumed to be same for native & Java).
-  stack_direction(TOWARDS_LOW);
-
   // These two registers define part of the calling convention between
   // compiled code and the interpreter.
 
@@ -2471,10 +2463,10 @@ frame %{
   // interpreter_arg_ptr_reg(Z_R6);
 
   // Temporary in compiled entry-points
-  // compiler_method_oop_reg(Z_R1);//Z_R1_scratch
+  // compiler_method_reg(Z_R1);//Z_R1_scratch
 
-  // Method Oop Register when calling interpreter
-  interpreter_method_oop_reg(Z_R9);//Z_method
+  // Method Register when calling interpreter
+  interpreter_method_reg(Z_R9);//Z_method
 
   // Optional: name the operand used by cisc-spilling to access
   // [stack_pointer + offset].
@@ -3539,15 +3531,15 @@ operand inline_cache_regP(iRegP reg) %{
   interface(REG_INTER);
 %}
 
-operand compiler_method_oop_regP(iRegP reg) %{
-  constraint(ALLOC_IN_RC(z_r1_RegP)); // compiler_method_oop_reg
+operand compiler_method_regP(iRegP reg) %{
+  constraint(ALLOC_IN_RC(z_r1_RegP)); // compiler_method_reg
   match(reg);
   format %{ %}
   interface(REG_INTER);
 %}
 
-operand interpreter_method_oop_regP(iRegP reg) %{
-  constraint(ALLOC_IN_RC(z_r9_regP)); // interpreter_method_oop_reg
+operand interpreter_method_regP(iRegP reg) %{
+  constraint(ALLOC_IN_RC(z_r9_regP)); // interpreter_method_reg
   match(reg);
   format %{ %}
   interface(REG_INTER);
diff --git a/src/hotspot/cpu/s390/vm_version_s390.cpp b/src/hotspot/cpu/s390/vm_version_s390.cpp
index 663b8d1dc44..3460a767fac 100644
--- a/src/hotspot/cpu/s390/vm_version_s390.cpp
+++ b/src/hotspot/cpu/s390/vm_version_s390.cpp
@@ -29,6 +29,7 @@
 #include "compiler/disassembler.hpp"
 #include "code/compiledIC.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/vm_version.hpp"
diff --git a/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp b/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp
index 808ed1ee404..d96ea768914 100644
--- a/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp
+++ b/src/hotspot/cpu/x86/gc/shared/barrierSetNMethod_x86.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -128,9 +128,7 @@ void BarrierSetNMethod::deoptimize(nmethod* nm, address* return_address_ptr) {
 
   LogTarget(Trace, nmethod, barrier) out;
   if (out.is_enabled()) {
-    Thread* thread = Thread::current();
-    assert(thread->is_Java_thread(), "must be JavaThread");
-    JavaThread* jth = (JavaThread*) thread;
+    JavaThread* jth = JavaThread::current();
     ResourceMark mark;
     log_trace(nmethod, barrier)("deoptimize(nmethod: %p, return_addr: %p, osr: %d, thread: %p(%s), making rsp: %p) -> %p",
                                nm, (address *) return_address_ptr, nm->is_osr_method(), jth,
diff --git a/src/hotspot/cpu/x86/globals_x86.hpp b/src/hotspot/cpu/x86/globals_x86.hpp
index 502eeb9a451..57acc05031c 100644
--- a/src/hotspot/cpu/x86/globals_x86.hpp
+++ b/src/hotspot/cpu/x86/globals_x86.hpp
@@ -89,13 +89,11 @@ define_pd_global(bool, PreserveFramePointer, false);
 
 define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
 
-#define ARCH_FLAGS(develop, \
-                   product, \
-                   diagnostic, \
-                   experimental, \
-                   notproduct, \
-                   range, \
-                   constraint) \
+#define ARCH_FLAGS(develop,                                                 \
+                   product,                                                 \
+                   notproduct,                                              \
+                   range,                                                   \
+                   constraint)                                              \
                                                                             \
   develop(bool, IEEEPrecision, true,                                        \
           "Enables IEEE precision (for INTEL only)")                        \
@@ -114,7 +112,7 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
   product(bool, UseCLMUL, false,                                            \
           "Control whether CLMUL instructions can be used on x86/x64")      \
                                                                             \
-  diagnostic(bool, UseIncDec, true,                                         \
+  product(bool, UseIncDec, true, DIAGNOSTIC,                                \
           "Use INC, DEC instructions on x86")                               \
                                                                             \
   product(bool, UseNewLongLShift, false,                                    \
@@ -148,7 +146,7 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
   product(bool, UseRTMLocking, false,                                       \
           "Enable RTM lock eliding for inflated locks in compiled code")    \
                                                                             \
-  experimental(bool, UseRTMForStackLocks, false,                            \
+  product(bool, UseRTMForStackLocks, false, EXPERIMENTAL,                   \
           "Enable RTM lock eliding for stack locks in compiled code")       \
                                                                             \
   product(bool, UseRTMDeopt, false,                                         \
@@ -158,33 +156,33 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
           "Number of RTM retries on lock abort or busy")                    \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(int, RTMSpinLoopCount, 100,                                  \
+  product(int, RTMSpinLoopCount, 100, EXPERIMENTAL,                         \
           "Spin count for lock to become free before RTM retry")            \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(int, RTMAbortThreshold, 1000,                                \
+  product(int, RTMAbortThreshold, 1000, EXPERIMENTAL,                       \
           "Calculate abort ratio after this number of aborts")              \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(int, RTMLockingThreshold, 10000,                             \
+  product(int, RTMLockingThreshold, 10000, EXPERIMENTAL,                    \
           "Lock count at which to do RTM lock eliding without "             \
           "abort ratio calculation")                                        \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(int, RTMAbortRatio, 50,                                      \
+  product(int, RTMAbortRatio, 50, EXPERIMENTAL,                             \
           "Lock abort ratio at which to stop use RTM lock eliding")         \
           range(0, 100) /* natural range */                                 \
                                                                             \
-  experimental(int, RTMTotalCountIncrRate, 64,                              \
+  product(int, RTMTotalCountIncrRate, 64, EXPERIMENTAL,                     \
           "Increment total RTM attempted lock count once every n times")    \
           range(1, max_jint)                                                \
           constraint(RTMTotalCountIncrRateConstraintFunc,AfterErgo)         \
                                                                             \
-  experimental(intx, RTMLockingCalculationDelay, 0,                         \
+  product(intx, RTMLockingCalculationDelay, 0, EXPERIMENTAL,                \
           "Number of milliseconds to wait before start calculating aborts " \
           "for RTM locking")                                                \
                                                                             \
-  experimental(bool, UseRTMXendForLockBusy, true,                           \
+  product(bool, UseRTMXendForLockBusy, true, EXPERIMENTAL,                  \
           "Use RTM Xend instead of Xabort when lock busy")                  \
                                                                             \
   /* assembler */                                                           \
@@ -203,21 +201,23 @@ define_pd_global(intx, InitArrayShortSize, 8*BytesPerLong);
   product(bool, UseBMI2Instructions, false,                                 \
           "Use BMI2 instructions")                                          \
                                                                             \
-  diagnostic(bool, UseLibmIntrinsic, true,                                  \
+  product(bool, UseLibmIntrinsic, true, DIAGNOSTIC,                         \
           "Use Libm Intrinsics")                                            \
                                                                             \
   /* Minimum array size in bytes to use AVX512 intrinsics */                \
   /* for copy, inflate and fill which don't bail out early based on any */  \
   /* condition. When this value is set to zero compare operations like */   \
   /* compare, vectorizedMismatch, compress can also use AVX512 intrinsics.*/\
-  diagnostic(int, AVX3Threshold, 4096,                                      \
+  product(int, AVX3Threshold, 4096, DIAGNOSTIC,                             \
              "Minimum array size in bytes to use AVX512 intrinsics"         \
              "for copy, inflate and fill. When this value is set as zero"   \
              "compare operations can also use AVX512 intrinsics.")          \
              range(0, max_jint)                                             \
                                                                             \
-  diagnostic(bool, IntelJccErratumMitigation, true,                         \
+  product(bool, IntelJccErratumMitigation, true, DIAGNOSTIC,                \
              "Turn off JVM mitigations related to Intel micro code "        \
              "mitigations for the Intel JCC erratum")
 
+// end of ARCH_FLAGS
+
 #endif // CPU_X86_GLOBALS_X86_HPP
diff --git a/src/hotspot/cpu/x86/rdtsc_x86.cpp b/src/hotspot/cpu/x86/rdtsc_x86.cpp
index 1fafbe1c68c..a4e743cc2df 100644
--- a/src/hotspot/cpu/x86/rdtsc_x86.cpp
+++ b/src/hotspot/cpu/x86/rdtsc_x86.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "rdtsc_x86.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/orderAccess.hpp"
 #include "runtime/thread.inline.hpp"
 #include "vm_version_ext_x86.hpp"
diff --git a/src/hotspot/cpu/x86/vm_version_x86.cpp b/src/hotspot/cpu/x86/vm_version_x86.cpp
index 0fd3cc9b4f0..dd3bc57c9ac 100644
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp
@@ -29,6 +29,7 @@
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
diff --git a/src/hotspot/cpu/x86/vm_version_x86.hpp b/src/hotspot/cpu/x86/vm_version_x86.hpp
index 2fce29a52e4..5e61fd34c7b 100644
--- a/src/hotspot/cpu/x86/vm_version_x86.hpp
+++ b/src/hotspot/cpu/x86/vm_version_x86.hpp
@@ -27,7 +27,6 @@
 
 #include "memory/universe.hpp"
 #include "runtime/abstract_vm_version.hpp"
-#include "runtime/globals_extension.hpp"
 
 class VM_Version : public Abstract_VM_Version {
   friend class VMStructs;
diff --git a/src/hotspot/cpu/x86/x86_32.ad b/src/hotspot/cpu/x86/x86_32.ad
index 4fccb028b5c..e572f3ca895 100644
--- a/src/hotspot/cpu/x86/x86_32.ad
+++ b/src/hotspot/cpu/x86/x86_32.ad
@@ -131,8 +131,8 @@ alloc_class chunk0( ECX,   EBX,   EBP,   EDI,   EAX,   EDX,   ESI, ESP,
 // Several register classes are automatically defined based upon information in
 // this architecture description.
 // 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
-// 2) reg_class compiler_method_oop_reg    ( /* as def'd in frame section */ )
-// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
+// 2) reg_class compiler_method_reg        ( /* as def'd in frame section */ )
+// 2) reg_class interpreter_method_reg     ( /* as def'd in frame section */ )
 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
 //
 // Class for no registers (empty set).
@@ -1371,10 +1371,6 @@ uint MachUEPNode::size(PhaseRegAlloc *ra_) const {
 
 //=============================================================================
 
-int Matcher::regnum_to_fpu_offset(int regnum) {
-  return regnum - 32; // The FP registers are in the second chunk
-}
-
 // This is UltraSparc specific, true just means we have fast l2f conversion
 const bool Matcher::convL2FSupported(void) {
   return true;
@@ -1931,7 +1927,7 @@ encode %{
 //   enc_class Java_Interpreter_Call (label labl) %{    // JAVA INTERPRETER CALL
 //     // int ic_reg     = Matcher::inline_cache_reg();
 //     // int ic_encode  = Matcher::_regEncode[ic_reg];
-//     // int imo_reg    = Matcher::interpreter_method_oop_reg();
+//     // int imo_reg    = Matcher::interpreter_method_reg();
 //     // int imo_encode = Matcher::_regEncode[imo_reg];
 //
 //     // // Interpreter expects method_ptr in EBX, currently a callee-saved register,
@@ -3191,13 +3187,10 @@ encode %{
 //         the region from SP to FP meets the minimum stack alignment.
 
 frame %{
-  // What direction does stack grow in (assumed to be same for C & Java)
-  stack_direction(TOWARDS_LOW);
-
   // These three registers define part of the calling convention
   // between compiled code and the interpreter.
   inline_cache_reg(EAX);                // Inline Cache Register
-  interpreter_method_oop_reg(EBX);      // Method Oop Register when calling interpreter
+  interpreter_method_reg(EBX);          // Method Register when calling interpreter
 
   // Optional: name the operand used by cisc-spilling to access [stack_pointer + offset]
   cisc_spilling_operand_name(indOffset32);
diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad
index f26f6fa62b4..9664b4a3041 100644
--- a/src/hotspot/cpu/x86/x86_64.ad
+++ b/src/hotspot/cpu/x86/x86_64.ad
@@ -161,8 +161,8 @@ alloc_class chunk0(R10,         R10_H,
 // Several register classes are automatically defined based upon information in
 // this architecture description.
 // 1) reg_class inline_cache_reg           ( /* as def'd in frame section */ )
-// 2) reg_class compiler_method_oop_reg    ( /* as def'd in frame section */ )
-// 2) reg_class interpreter_method_oop_reg ( /* as def'd in frame section */ )
+// 2) reg_class compiler_method_reg        ( /* as def'd in frame section */ )
+// 2) reg_class interpreter_method_reg     ( /* as def'd in frame section */ )
 // 3) reg_class stack_slots( /* one chunk of stack-based "registers" */ )
 //
 
@@ -1578,11 +1578,6 @@ uint MachUEPNode::size(PhaseRegAlloc* ra_) const
 
 //=============================================================================
 
-int Matcher::regnum_to_fpu_offset(int regnum)
-{
-  return regnum - 32; // The FP registers are in the second chunk
-}
-
 // This is UltraSparc specific, true just means we have fast l2f conversion
 const bool Matcher::convL2FSupported(void) {
   return true;
@@ -2740,13 +2735,10 @@ encode %{
 
 frame
 %{
-  // What direction does stack grow in (assumed to be same for C & Java)
-  stack_direction(TOWARDS_LOW);
-
   // These three registers define part of the calling convention
   // between compiled code and the interpreter.
   inline_cache_reg(RAX);                // Inline Cache Register
-  interpreter_method_oop_reg(RBX);      // Method Oop Register when
+  interpreter_method_reg(RBX);          // Method Register when
                                         // calling interpreter
 
   // Optional: name the operand used by cisc-spilling to access
diff --git a/src/hotspot/cpu/zero/frame_zero.cpp b/src/hotspot/cpu/zero/frame_zero.cpp
index 0158812cc64..bd900de5741 100644
--- a/src/hotspot/cpu/zero/frame_zero.cpp
+++ b/src/hotspot/cpu/zero/frame_zero.cpp
@@ -94,7 +94,7 @@ void frame::patch_pc(Thread* thread, address pc) {
     // We borrow this call to set the thread pointer in the interpreter
     // state; the hook to set up deoptimized frames isn't supplied it.
     assert(pc == NULL, "should be");
-    get_interpreterState()->set_thread((JavaThread *) thread);
+    get_interpreterState()->set_thread(thread->as_Java_thread());
   }
 }
 
diff --git a/src/hotspot/cpu/zero/globals_zero.hpp b/src/hotspot/cpu/zero/globals_zero.hpp
index a05504eea3b..7028276a1d8 100644
--- a/src/hotspot/cpu/zero/globals_zero.hpp
+++ b/src/hotspot/cpu/zero/globals_zero.hpp
@@ -73,19 +73,18 @@ define_pd_global(bool, PreserveFramePointer, false);
 // No performance work done here yet.
 define_pd_global(bool, CompactStrings, false);
 
-#define ARCH_FLAGS(develop, \
-                   product, \
-                   diagnostic, \
-                   experimental, \
-                   notproduct, \
-                   range, \
-                   constraint)  \
+#define ARCH_FLAGS(develop,                                                 \
+                   product,                                                 \
+                   notproduct,                                              \
+                   range,                                                   \
+                   constraint)                                              \
                                                                             \
   product(bool, UseFastEmptyMethods, true,                                  \
           "Use fast method entry code for empty methods")                   \
                                                                             \
   product(bool, UseFastAccessorMethods, true,                               \
-          "Use fast method entry code for accessor methods")                \
-                                                                            \
+          "Use fast method entry code for accessor methods")
+
+// end of ARCH_FLAGS
 
 #endif // CPU_ZERO_GLOBALS_ZERO_HPP
diff --git a/src/hotspot/cpu/zero/interpreterFrame_zero.hpp b/src/hotspot/cpu/zero/interpreterFrame_zero.hpp
index 4e96d7b3481..a8066080d54 100644
--- a/src/hotspot/cpu/zero/interpreterFrame_zero.hpp
+++ b/src/hotspot/cpu/zero/interpreterFrame_zero.hpp
@@ -57,8 +57,8 @@ class InterpreterFrame : public ZeroFrame {
  protected:
   enum Layout {
     istate_off = jf_header_words +
-      (align_up_(sizeof(BytecodeInterpreter),
-                 wordSize) >> LogBytesPerWord) - 1,
+      (align_up(sizeof(BytecodeInterpreter),
+                wordSize) >> LogBytesPerWord) - 1,
     header_words
   };
 
diff --git a/src/hotspot/cpu/zero/methodHandles_zero.cpp b/src/hotspot/cpu/zero/methodHandles_zero.cpp
index a644a63251a..4929712d127 100644
--- a/src/hotspot/cpu/zero/methodHandles_zero.cpp
+++ b/src/hotspot/cpu/zero/methodHandles_zero.cpp
@@ -38,7 +38,7 @@
 
 void MethodHandles::invoke_target(Method* method, TRAPS) {
 
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   ZeroStack *stack = thread->zero_stack();
   InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
   interpreterState istate = frame->interpreter_state();
@@ -55,7 +55,7 @@ void MethodHandles::invoke_target(Method* method, TRAPS) {
 
 oop MethodHandles::popFromStack(TRAPS) {
 
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
   interpreterState istate = frame->interpreter_state();
   intptr_t* topOfStack = istate->stack();
@@ -70,7 +70,7 @@ oop MethodHandles::popFromStack(TRAPS) {
 
 void MethodHandles::throw_AME(Klass* rcvr, Method* interface_method, TRAPS) {
 
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   // Set up the frame anchor if it isn't already
   bool has_last_Java_frame = thread->has_last_Java_frame();
   if (!has_last_Java_frame) {
@@ -101,7 +101,7 @@ void MethodHandles::throw_AME(Klass* rcvr, Method* interface_method, TRAPS) {
 
 int MethodHandles::method_handle_entry_invokeBasic(Method* method, intptr_t UNUSED, TRAPS) {
 
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
   interpreterState istate = frame->interpreter_state();
   intptr_t* topOfStack = istate->stack();
@@ -132,7 +132,7 @@ int MethodHandles::method_handle_entry_linkToStaticOrSpecial(Method* method, int
 }
 
 int MethodHandles::method_handle_entry_linkToInterface(Method* method, intptr_t UNUSED, TRAPS) {
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
   interpreterState istate = frame->interpreter_state();
 
@@ -172,7 +172,7 @@ int MethodHandles::method_handle_entry_linkToInterface(Method* method, intptr_t
 }
 
 int MethodHandles::method_handle_entry_linkToVirtual(Method* method, intptr_t UNUSED, TRAPS) {
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
 
   InterpreterFrame *frame = thread->top_zero_frame()->as_interpreter_frame();
   interpreterState istate = frame->interpreter_state();
diff --git a/src/hotspot/cpu/zero/stack_zero.cpp b/src/hotspot/cpu/zero/stack_zero.cpp
index 11a5c636a53..ee61f2d2f2b 100644
--- a/src/hotspot/cpu/zero/stack_zero.cpp
+++ b/src/hotspot/cpu/zero/stack_zero.cpp
@@ -46,7 +46,7 @@ int ZeroStack::suggest_size(Thread *thread) const {
 }
 
 void ZeroStack::handle_overflow(TRAPS) {
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
 
   // Set up the frame anchor if it isn't already
   bool has_last_Java_frame = thread->has_last_Java_frame();
diff --git a/src/hotspot/cpu/zero/stubGenerator_zero.cpp b/src/hotspot/cpu/zero/stubGenerator_zero.cpp
index a290eef2021..d0513de976e 100644
--- a/src/hotspot/cpu/zero/stubGenerator_zero.cpp
+++ b/src/hotspot/cpu/zero/stubGenerator_zero.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2010, 2015 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -72,7 +72,7 @@ class StubGenerator: public StubCodeGenerator {
     intptr_t*        parameters,
     int              parameter_words,
     TRAPS) {
-    JavaThread *thread = (JavaThread *) THREAD;
+    JavaThread *thread = THREAD->as_Java_thread();
     ZeroStack *stack = thread->zero_stack();
 
     // Make sure we have no pending exceptions
@@ -316,7 +316,7 @@ EntryFrame *EntryFrame::build(const intptr_t*  parameters,
                               JavaCallWrapper* call_wrapper,
                               TRAPS) {
 
-  ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack();
+  ZeroStack *stack = THREAD->as_Java_thread()->zero_stack();
   stack->overflow_check(header_words + parameter_words, CHECK_NULL);
 
   stack->push(0); // next_frame, filled in later
diff --git a/src/hotspot/cpu/zero/vm_version_zero.cpp b/src/hotspot/cpu/zero/vm_version_zero.cpp
index 6f8519aba53..bc38c7d81cf 100644
--- a/src/hotspot/cpu/zero/vm_version_zero.cpp
+++ b/src/hotspot/cpu/zero/vm_version_zero.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -26,6 +26,7 @@
 #include "precompiled.hpp"
 #include "assembler_zero.inline.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/stubCodeGenerator.hpp"
 #include "runtime/vm_version.hpp"
diff --git a/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp b/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp
index 40f8b5f1840..9aae3e751e5 100644
--- a/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp
+++ b/src/hotspot/cpu/zero/zeroInterpreter_zero.cpp
@@ -106,7 +106,7 @@ InterpreterCodelet* ZeroInterpreter::codelet_containing(address pc) {
   fixup_after_potential_safepoint()
 
 int ZeroInterpreter::normal_entry(Method* method, intptr_t UNUSED, TRAPS) {
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
 
   // Allocate and initialize our frame.
   InterpreterFrame *frame = InterpreterFrame::build(method, CHECK_0);
@@ -144,7 +144,7 @@ intptr_t narrow(BasicType type, intptr_t result) {
 
 
 void ZeroInterpreter::main_loop(int recurse, TRAPS) {
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   ZeroStack *stack = thread->zero_stack();
 
   // If we are entering from a deopt we may need to call
@@ -277,7 +277,7 @@ int ZeroInterpreter::native_entry(Method* method, intptr_t UNUSED, TRAPS) {
   // Make sure method is native and not abstract
   assert(method->is_native() && !method->is_abstract(), "should be");
 
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   ZeroStack *stack = thread->zero_stack();
 
   // Allocate and initialize our frame
@@ -546,7 +546,7 @@ int ZeroInterpreter::native_entry(Method* method, intptr_t UNUSED, TRAPS) {
 }
 
 int ZeroInterpreter::accessor_entry(Method* method, intptr_t UNUSED, TRAPS) {
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   ZeroStack *stack = thread->zero_stack();
   intptr_t *locals = stack->sp();
 
@@ -679,7 +679,7 @@ int ZeroInterpreter::accessor_entry(Method* method, intptr_t UNUSED, TRAPS) {
 }
 
 int ZeroInterpreter::empty_entry(Method* method, intptr_t UNUSED, TRAPS) {
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   ZeroStack *stack = thread->zero_stack();
 
   // Drop into the slow path if we need a safepoint check
@@ -698,7 +698,7 @@ int ZeroInterpreter::empty_entry(Method* method, intptr_t UNUSED, TRAPS) {
 // Slots < insert_before will have the same slot number after the insert.
 // Slots >= insert_before will become old_slot + num_slots.
 void ZeroInterpreter::insert_vmslots(int insert_before, int num_slots, TRAPS) {
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   ZeroStack *stack = thread->zero_stack();
 
   // Allocate the space
@@ -712,7 +712,7 @@ void ZeroInterpreter::insert_vmslots(int insert_before, int num_slots, TRAPS) {
 }
 
 void ZeroInterpreter::remove_vmslots(int first_slot, int num_slots, TRAPS) {
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   ZeroStack *stack = thread->zero_stack();
   intptr_t *vmslots = stack->sp();
 
@@ -745,7 +745,7 @@ JRT_ENTRY(void, ZeroInterpreter::throw_exception(JavaThread* thread,
 JRT_END
 
 InterpreterFrame *InterpreterFrame::build(Method* const method, TRAPS) {
-  JavaThread *thread = (JavaThread *) THREAD;
+  JavaThread *thread = THREAD->as_Java_thread();
   ZeroStack *stack = thread->zero_stack();
 
   // Calculate the size of the frame we'll build, including
@@ -821,7 +821,7 @@ InterpreterFrame *InterpreterFrame::build(Method* const method, TRAPS) {
 }
 
 InterpreterFrame *InterpreterFrame::build(int size, TRAPS) {
-  ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack();
+  ZeroStack *stack = THREAD->as_Java_thread()->zero_stack();
 
   int size_in_words = size >> LogBytesPerWord;
   assert(size_in_words * wordSize == size, "unaligned");
diff --git a/src/hotspot/os/aix/globals_aix.hpp b/src/hotspot/os/aix/globals_aix.hpp
index 1c434b5d976..b6b67a4f3bb 100644
--- a/src/hotspot/os/aix/globals_aix.hpp
+++ b/src/hotspot/os/aix/globals_aix.hpp
@@ -27,18 +27,16 @@
 #define OS_AIX_GLOBALS_AIX_HPP
 
 //
-// Defines Aix specific flags. They are not available on other platforms.
+// Declare Aix specific flags. They are not available on other platforms.
 //
 // (Please keep the switches sorted alphabetically.)
-#define RUNTIME_OS_FLAGS(develop, \
-                         develop_pd, \
-                         product, \
-                         product_pd, \
-                         diagnostic, \
-                         diagnostic_pd, \
-                         notproduct, \
-                         range, \
-                         constraint) \
+#define RUNTIME_OS_FLAGS(develop,                                                   \
+                         develop_pd,                                                \
+                         product,                                                   \
+                         product_pd,                                                \
+                         notproduct,                                                \
+                         range,                                                     \
+                         constraint)                                                \
                                                                                     \
   /* Whether to allow the VM to run if EXTSHM=ON. EXTSHM is an environment */       \
   /* variable used on AIX to activate certain hacks which allow more shm segments */\
@@ -77,9 +75,9 @@
   /* explicit commit behaviour. This flag, if true, causes the VM to touch     */   \
   /* memory on os::commit_memory() (which normally is a noop).                 */   \
   product(bool, UseExplicitCommit, false,                                           \
-          "Explicit commit for virtual memory.")                                    \
-                                                                                    \
+          "Explicit commit for virtual memory.")
 
+// end of RUNTIME_OS_FLAGS
 
 //
 // Defines Aix-specific default values. The flags are available on all
diff --git a/src/hotspot/os/aix/os_aix.cpp b/src/hotspot/os/aix/os_aix.cpp
index 64face5268a..43e7f292421 100644
--- a/src/hotspot/os/aix/os_aix.cpp
+++ b/src/hotspot/os/aix/os_aix.cpp
@@ -54,6 +54,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
diff --git a/src/hotspot/os/bsd/globals_bsd.hpp b/src/hotspot/os/bsd/globals_bsd.hpp
index 344a04d63c3..6c8939a6dc0 100644
--- a/src/hotspot/os/bsd/globals_bsd.hpp
+++ b/src/hotspot/os/bsd/globals_bsd.hpp
@@ -26,18 +26,18 @@
 #define OS_BSD_GLOBALS_BSD_HPP
 
 //
-// Defines Bsd specific flags. They are not available on other platforms.
+// Declare Bsd specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, \
-                         develop_pd, \
-                         product, \
-                         product_pd, \
-                         diagnostic, \
-                         diagnostic_pd, \
-                         notproduct, \
-                         range, \
+#define RUNTIME_OS_FLAGS(develop,     \
+                         develop_pd,  \
+                         product,     \
+                         product_pd,  \
+                         notproduct,  \
+                         range,       \
                          constraint)
 
+// end of RUNTIME_OS_FLAGS
+
 //
 // Defines Bsd-specific default values. The flags are available on all
 // platforms, but they may have different default values on other platforms.
diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp
index 943133e27e5..1a8f0a4558e 100644
--- a/src/hotspot/os/bsd/os_bsd.cpp
+++ b/src/hotspot/os/bsd/os_bsd.cpp
@@ -45,6 +45,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
diff --git a/src/hotspot/os/linux/globals_linux.hpp b/src/hotspot/os/linux/globals_linux.hpp
index 2baf2b805dc..f2a889285af 100644
--- a/src/hotspot/os/linux/globals_linux.hpp
+++ b/src/hotspot/os/linux/globals_linux.hpp
@@ -26,17 +26,15 @@
 #define OS_LINUX_GLOBALS_LINUX_HPP
 
 //
-// Defines Linux specific flags. They are not available on other platforms.
+// Declare Linux specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, \
-                         develop_pd, \
-                         product, \
-                         product_pd, \
-                         diagnostic, \
-                         diagnostic_pd, \
-                         notproduct, \
-                         range, \
-                         constraint) \
+#define RUNTIME_OS_FLAGS(develop,                                       \
+                         develop_pd,                                    \
+                         product,                                       \
+                         product_pd,                                    \
+                         notproduct,                                    \
+                         range,                                         \
+                         constraint)                                    \
                                                                         \
   product(bool, UseOprofile, false,                                     \
         "enable support for Oprofile profiler")                         \
@@ -70,19 +68,21 @@
           "Increase the thread stack size to include space for glibc "  \
           "static thread-local storage (TLS) if true")                  \
                                                                         \
-  diagnostic(bool, DumpPrivateMappingsInCore, true,                     \
+  product(bool, DumpPrivateMappingsInCore, true, DIAGNOSTIC,            \
           "If true, sets bit 2 of /proc/PID/coredump_filter, thus "     \
           "resulting in file-backed private mappings of the process to "\
           "be dumped into the corefile.")                               \
                                                                         \
-  diagnostic(bool, DumpSharedMappingsInCore, true,                      \
+  product(bool, DumpSharedMappingsInCore, true, DIAGNOSTIC,             \
           "If true, sets bit 3 of /proc/PID/coredump_filter, thus "     \
           "resulting in file-backed shared mappings of the process to " \
           "be dumped into the corefile.")                               \
                                                                         \
-  diagnostic(bool, UseCpuAllocPath, false,                              \
+  product(bool, UseCpuAllocPath, false, DIAGNOSTIC,                     \
              "Use CPU_ALLOC code path in os::active_processor_count ")
 
+// end of RUNTIME_OS_FLAGS
+
 //
 // Defines Linux-specific default values. The flags are available on all
 // platforms, but they may have different default values on other platforms.
diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp
index e3a9cfa386b..5c610cdf7e9 100644
--- a/src/hotspot/os/linux/os_linux.cpp
+++ b/src/hotspot/os/linux/os_linux.cpp
@@ -46,6 +46,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/java.hpp"
@@ -1040,13 +1041,12 @@ bool os::create_attached_thread(JavaThread* thread) {
     // enabling yellow zone first will crash JVM on SuSE Linux), so there
     // is no gap between the last two virtual memory regions.
 
-    JavaThread *jt = (JavaThread *)thread;
-    address addr = jt->stack_reserved_zone_base();
+    address addr = thread->stack_reserved_zone_base();
     assert(addr != NULL, "initialization problem?");
-    assert(jt->stack_available(addr) > 0, "stack guard should not be enabled");
+    assert(thread->stack_available(addr) > 0, "stack guard should not be enabled");
 
     osthread->set_expanding_stack();
-    os::Linux::manually_expand_stack(jt, addr);
+    os::Linux::manually_expand_stack(thread, addr);
     osthread->clear_expanding_stack();
   }
 
@@ -1781,7 +1781,6 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
                 "'execstack -c <libfile>', or link it with '-z noexecstack'.",
                 filename);
 
-        assert(Thread::current()->is_Java_thread(), "must be Java thread");
         JavaThread *jt = JavaThread::current();
         if (jt->thread_state() != _thread_in_native) {
           // This happens when a compiler thread tries to load a hsdis-<arch>.so file
diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp
index 40ed3d877c2..39d2d2732ad 100644
--- a/src/hotspot/os/posix/os_posix.cpp
+++ b/src/hotspot/os/posix/os_posix.cpp
@@ -26,6 +26,7 @@
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "os_posix.inline.hpp"
+#include "runtime/globals_extension.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
@@ -2073,9 +2074,7 @@ void Parker::park(bool isAbsolute, jlong time) {
   // since we are doing a lock-free update to _counter.
   if (Atomic::xchg(&_counter, 0) > 0) return;
 
-  Thread* thread = Thread::current();
-  assert(thread->is_Java_thread(), "Must be JavaThread");
-  JavaThread *jt = (JavaThread *)thread;
+  JavaThread *jt = JavaThread::current();
 
   // Optional optimization -- avoid state transitions if there's
   // an interrupt pending.
@@ -2120,7 +2119,7 @@ void Parker::park(bool isAbsolute, jlong time) {
     return;
   }
 
-  OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
+  OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
   jt->set_suspend_equivalent();
   // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
 
diff --git a/src/hotspot/os/windows/globals_windows.hpp b/src/hotspot/os/windows/globals_windows.hpp
index f91951097c9..a712e102a76 100644
--- a/src/hotspot/os/windows/globals_windows.hpp
+++ b/src/hotspot/os/windows/globals_windows.hpp
@@ -26,18 +26,18 @@
 #define OS_WINDOWS_GLOBALS_WINDOWS_HPP
 
 //
-// Defines Windows specific flags. They are not available on other platforms.
+// Declare Windows specific flags. They are not available on other platforms.
 //
-#define RUNTIME_OS_FLAGS(develop, \
-                         develop_pd, \
-                         product, \
-                         product_pd, \
-                         diagnostic, \
-                         diagnostic_pd, \
-                         notproduct, \
-                         range, \
+#define RUNTIME_OS_FLAGS(develop,     \
+                         develop_pd,  \
+                         product,     \
+                         product_pd,  \
+                         notproduct,  \
+                         range,       \
                          constraint)
 
+// end of RUNTIME_OS_FLAGS
+
 
 //
 // Defines Windows-specific default values. The flags are available on all
diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp
index fd85dddc556..99ed8f22db0 100644
--- a/src/hotspot/os/windows/os_windows.cpp
+++ b/src/hotspot/os/windows/os_windows.cpp
@@ -48,6 +48,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/javaCalls.hpp"
@@ -2136,19 +2137,19 @@ int os::signal_wait() {
 
 LONG Handle_Exception(struct _EXCEPTION_POINTERS* exceptionInfo,
                       address handler) {
-  JavaThread* thread = (JavaThread*) Thread::current_or_null();
+  Thread* thread = Thread::current_or_null();
   // Save pc in thread
 #ifdef _M_AMD64
   // Do not blow up if no thread info available.
-  if (thread) {
-    thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
+  if (thread != NULL) {
+    thread->as_Java_thread()->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Rip);
   }
   // Set pc to handler
   exceptionInfo->ContextRecord->Rip = (DWORD64)handler;
 #else
   // Do not blow up if no thread info available.
-  if (thread) {
-    thread->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
+  if (thread != NULL) {
+    thread->as_Java_thread()->set_saved_exception_pc((address)(DWORD_PTR)exceptionInfo->ContextRecord->Eip);
   }
   // Set pc to handler
   exceptionInfo->ContextRecord->Eip = (DWORD)(DWORD_PTR)handler;
@@ -2477,7 +2478,7 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
   }
 
   if (t != NULL && t->is_Java_thread()) {
-    JavaThread* thread = (JavaThread*) t;
+    JavaThread* thread = t->as_Java_thread();
     bool in_java = thread->thread_state() == _thread_in_Java;
     bool in_native = thread->thread_state() == _thread_in_native;
     bool in_vm = thread->thread_state() == _thread_in_vm;
@@ -2570,7 +2571,6 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) {
 
     if (exception_code == EXCEPTION_IN_PAGE_ERROR) {
       CompiledMethod* nm = NULL;
-      JavaThread* thread = (JavaThread*)t;
       if (in_java) {
         CodeBlob* cb = CodeCache::find_blob_unsafe(pc);
         nm = (cb != NULL) ? cb->as_compiled_method_or_null() : NULL;
diff --git a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp
index e5e4bbc434e..f22a7390d28 100644
--- a/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp
+++ b/src/hotspot/os_cpu/aix_ppc/os_aix_ppc.cpp
@@ -228,7 +228,7 @@ JVM_handle_aix_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrec
   if (os::Aix::signal_handlers_are_installed) {
     if (t != NULL) {
       if(t->is_Java_thread()) {
-        thread = (JavaThread*)t;
+        thread = t->as_Java_thread();
       }
       else if(t->is_VM_thread()) {
         vmthread = (VMThread *)t;
diff --git a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp
index fd616151715..c2437d56350 100644
--- a/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp
+++ b/src/hotspot/os_cpu/bsd_x86/os_bsd_x86.cpp
@@ -457,7 +457,7 @@ JVM_handle_bsd_signal(int sig,
   if (os::Bsd::signal_handlers_are_installed) {
     if (t != NULL ){
       if(t->is_Java_thread()) {
-        thread = (JavaThread*)t;
+        thread = t->as_Java_thread();
       }
       else if(t->is_VM_thread()){
         vmthread = (VMThread *)t;
diff --git a/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp b/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp
index 3522cad9e1f..3d7dc7e4b5a 100644
--- a/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp
+++ b/src/hotspot/os_cpu/bsd_x86/thread_bsd_x86.cpp
@@ -46,13 +46,10 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
 }
 
 bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
-  assert(this->is_Java_thread(), "must be JavaThread");
-  JavaThread* jt = (JavaThread *)this;
-
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than ucontext info.
-  if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
-    *fr_addr = jt->pd_last_frame();
+  if (has_last_Java_frame() && frame_anchor()->walkable()) {
+    *fr_addr = pd_last_frame();
     return true;
   }
 
@@ -77,11 +74,11 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
     }
 
     frame ret_frame(ret_sp, ret_fp, addr);
-    if (!ret_frame.safe_for_sender(jt)) {
+    if (!ret_frame.safe_for_sender(this)) {
 #if COMPILER2_OR_JVMCI
       // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr);
-      if (!ret_frame2.safe_for_sender(jt)) {
+      if (!ret_frame2.safe_for_sender(this)) {
         // nothing else to try if the frame isn't good
         return false;
       }
diff --git a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp
index 4db293eca15..b404c840a6a 100644
--- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp
+++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp
@@ -156,7 +156,7 @@ JVM_handle_bsd_signal(int sig,
   if (os::Bsd::signal_handlers_are_installed) {
     if (t != NULL ){
       if(t->is_Java_thread()) {
-        thread = (JavaThread*)t;
+        thread = t->as_Java_thread();
       }
       else if(t->is_VM_thread()){
         vmthread = (VMThread *)t;
diff --git a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp
index 0075e7e841c..18651ae81b1 100644
--- a/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp
+++ b/src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp
@@ -237,7 +237,7 @@ JVM_handle_linux_signal(int sig,
   if (os::Linux::signal_handlers_are_installed) {
     if (t != NULL ){
       if(t->is_Java_thread()) {
-        thread = (JavaThread*)t;
+        thread = t->as_Java_thread();
       }
       else if(t->is_VM_thread()){
         vmthread = (VMThread *)t;
diff --git a/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp b/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp
index c09244ed754..799d2cf87d1 100644
--- a/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp
+++ b/src/hotspot/os_cpu/linux_aarch64/thread_linux_aarch64.cpp
@@ -47,13 +47,10 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
 }
 
 bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
-  assert(this->is_Java_thread(), "must be JavaThread");
-  JavaThread* jt = (JavaThread *)this;
-
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than ucontext info.
-  if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
-    *fr_addr = jt->pd_last_frame();
+  if (has_last_Java_frame() && frame_anchor()->walkable()) {
+    *fr_addr = pd_last_frame();
     return true;
   }
 
@@ -78,10 +75,10 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
     }
 
     frame ret_frame(ret_sp, ret_fp, addr);
-    if (!ret_frame.safe_for_sender(jt)) {
+    if (!ret_frame.safe_for_sender(this)) {
 #ifdef COMPILER2
       frame ret_frame2(ret_sp, NULL, addr);
-      if (!ret_frame2.safe_for_sender(jt)) {
+      if (!ret_frame2.safe_for_sender(this)) {
         // nothing else to try if the frame isn't good
         return false;
       }
@@ -100,4 +97,3 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
 }
 
 void JavaThread::cache_global_variables() { }
-
diff --git a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
index eb54fd091da..a04f79a4eae 100644
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
+++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
@@ -296,7 +296,7 @@ extern "C" int JVM_handle_linux_signal(int sig, siginfo_t* info,
   if (os::Linux::signal_handlers_are_installed) {
     if (t != NULL ){
       if(t->is_Java_thread()) {
-        thread = (JavaThread*)t;
+        thread = t->as_Java_thread();
       }
       else if(t->is_VM_thread()){
         vmthread = (VMThread *)t;
diff --git a/src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp
index 8776e9198bc..6fd8a2fbde5 100644
--- a/src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp
+++ b/src/hotspot/os_cpu/linux_arm/thread_linux_arm.cpp
@@ -74,20 +74,16 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
 }
 
 bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
-  assert(this->is_Java_thread(), "must be JavaThread");
-
-  JavaThread* jt = (JavaThread *)this;
-
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than ucontext info.
-  if (jt->has_last_Java_frame()) {
-    *fr_addr = jt->pd_last_frame();
+  if (has_last_Java_frame()) {
+    *fr_addr = pd_last_frame();
     return true;
   }
 
   // Could be in a code section that plays with the stack, like
   // MacroAssembler::verify_heapbase()
-  if (jt->in_top_frame_unsafe_section()) {
+  if (in_top_frame_unsafe_section()) {
     return false;
   }
 
@@ -112,11 +108,11 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
     }
 
     frame ret_frame(ret_sp, ret_fp, addr);
-    if (!ret_frame.safe_for_sender(jt)) {
+    if (!ret_frame.safe_for_sender(this)) {
 #ifdef COMPILER2
       // C2 uses ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr);
-      if (!ret_frame2.safe_for_sender(jt)) {
+      if (!ret_frame2.safe_for_sender(this)) {
         // nothing else to try if the frame isn't good
         return false;
       }
diff --git a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp
index 0f5251df602..c747ba12d64 100644
--- a/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp
+++ b/src/hotspot/os_cpu/linux_ppc/os_linux_ppc.cpp
@@ -280,7 +280,7 @@ JVM_handle_linux_signal(int sig,
   if (os::Linux::signal_handlers_are_installed) {
     if (t != NULL) {
       if(t->is_Java_thread()) {
-        thread = (JavaThread*)t;
+        thread = t->as_Java_thread();
       } else if(t->is_VM_thread()) {
         vmthread = (VMThread *)t;
       }
diff --git a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp
index ca7c68f646b..f853f7a439a 100644
--- a/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp
+++ b/src/hotspot/os_cpu/linux_ppc/thread_linux_ppc.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2019 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -42,7 +42,6 @@ frame JavaThread::pd_last_frame() {
 }
 
 bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
-  assert(this->is_Java_thread(), "must be JavaThread");
 
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than ucontext info.
diff --git a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp
index e803c6fdce8..0d3a36f94ce 100644
--- a/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp
+++ b/src/hotspot/os_cpu/linux_s390/os_linux_s390.cpp
@@ -280,7 +280,7 @@ JVM_handle_linux_signal(int sig,
   if (os::Linux::signal_handlers_are_installed) {
     if (t != NULL) {
       if(t->is_Java_thread()) {
-        thread = (JavaThread*)t;
+        thread = t->as_Java_thread();
       } else if(t->is_VM_thread()) {
         vmthread = (VMThread *)t;
       }
diff --git a/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp b/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp
index 4f14f9969f7..aebadb25518 100644
--- a/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp
+++ b/src/hotspot/os_cpu/linux_s390/thread_linux_s390.cpp
@@ -42,7 +42,6 @@ frame JavaThread::pd_last_frame() {
 }
 
 bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, bool isInJava) {
-  assert(this->is_Java_thread(), "must be JavaThread");
 
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than ucontext info.
diff --git a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
index 37eb6db2e83..598383ca9db 100644
--- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
+++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
@@ -276,7 +276,7 @@ JVM_handle_linux_signal(int sig,
   if (os::Linux::signal_handlers_are_installed) {
     if (t != NULL ){
       if(t->is_Java_thread()) {
-        thread = (JavaThread*)t;
+        thread = t->as_Java_thread();
       }
       else if(t->is_VM_thread()){
         vmthread = (VMThread *)t;
diff --git a/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp
index f2e5ef10310..b72127907b2 100644
--- a/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp
+++ b/src/hotspot/os_cpu/linux_x86/thread_linux_x86.cpp
@@ -47,13 +47,10 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
 }
 
 bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
-  assert(this->is_Java_thread(), "must be JavaThread");
-  JavaThread* jt = (JavaThread *)this;
-
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than ucontext info.
-  if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
-    *fr_addr = jt->pd_last_frame();
+  if (has_last_Java_frame() && frame_anchor()->walkable()) {
+    *fr_addr = pd_last_frame();
     return true;
   }
 
@@ -78,11 +75,11 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
     }
 
     frame ret_frame(ret_sp, ret_fp, addr);
-    if (!ret_frame.safe_for_sender(jt)) {
+    if (!ret_frame.safe_for_sender(this)) {
 #if COMPILER2_OR_JVMCI
       // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_sp, NULL, addr);
-      if (!ret_frame2.safe_for_sender(jt)) {
+      if (!ret_frame2.safe_for_sender(this)) {
         // nothing else to try if the frame isn't good
         return false;
       }
@@ -101,4 +98,3 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
 }
 
 void JavaThread::cache_global_variables() { }
-
diff --git a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp
index d9e2382bf2c..e2de18263f0 100644
--- a/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp
+++ b/src/hotspot/os_cpu/linux_zero/os_linux_zero.cpp
@@ -152,7 +152,7 @@ JVM_handle_linux_signal(int sig,
   if (os::Linux::signal_handlers_are_installed) {
     if (t != NULL ){
       if(t->is_Java_thread()) {
-        thread = (JavaThread*)t;
+        thread = t->as_Java_thread();
       }
       else if(t->is_VM_thread()){
         vmthread = (VMThread *)t;
diff --git a/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp b/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp
index a1f0ff39150..048574596f4 100644
--- a/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp
+++ b/src/hotspot/os_cpu/windows_x86/thread_windows_x86.cpp
@@ -47,15 +47,10 @@ bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext,
 }
 
 bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava) {
-
-  assert(this->is_Java_thread(), "must be JavaThread");
-
-  JavaThread* jt = (JavaThread *)this;
-
   // If we have a last_Java_frame, then we should use it even if
   // isInJava == true.  It should be more reliable than CONTEXT info.
-  if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) {
-    *fr_addr = jt->pd_last_frame();
+  if (has_last_Java_frame() && frame_anchor()->walkable()) {
+    *fr_addr = pd_last_frame();
     return true;
   }
 
@@ -75,11 +70,11 @@ bool JavaThread::pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava)
       return false;
     }
 
-    if (!ret_frame.safe_for_sender(jt)) {
+    if (!ret_frame.safe_for_sender(this)) {
 #if COMPILER2_OR_JVMCI
       // C2 and JVMCI use ebp as a general register see if NULL fp helps
       frame ret_frame2(ret_frame.sp(), NULL, ret_frame.pc());
-      if (!ret_frame2.safe_for_sender(jt)) {
+      if (!ret_frame2.safe_for_sender(this)) {
         // nothing else to try if the frame isn't good
         return false;
       }
diff --git a/src/hotspot/share/adlc/adlparse.cpp b/src/hotspot/share/adlc/adlparse.cpp
index 547b378c466..198ee4eb586 100644
--- a/src/hotspot/share/adlc/adlparse.cpp
+++ b/src/hotspot/share/adlc/adlparse.cpp
@@ -985,9 +985,6 @@ void ADLParser::frame_parse(void) {
             parse_err(SYNERR, "missing identifier inside frame block.\n");
             return;
       }
-      if (strcmp(token,"stack_direction")==0) {
-        stack_dir_parse(frame);
-      }
       if (strcmp(token,"sync_stack_slots")==0) {
         sync_stack_slots_parse(frame);
       }
@@ -1005,7 +1002,11 @@ void ADLParser::frame_parse(void) {
         skipws();
       }
       if (strcmp(token,"interpreter_method_oop_reg")==0) {
-        interpreter_method_oop_parse(frame, false);
+        parse_err(WARN, "Using obsolete Token, interpreter_method_oop_reg");
+        skipws();
+      }
+      if (strcmp(token,"interpreter_method_reg")==0) {
+        interpreter_method_parse(frame, false);
       }
       if (strcmp(token,"cisc_spilling_operand_name")==0) {
         cisc_spilling_operand_name_parse(frame, false);
@@ -1109,21 +1110,6 @@ void ADLParser::frame_parse(void) {
   // skipws();
 }
 
-//------------------------------stack_dir_parse--------------------------------
-void ADLParser::stack_dir_parse(FrameForm *frame) {
-  char *direction = parse_one_arg("stack direction entry");
-  if (strcmp(direction, "TOWARDS_LOW") == 0) {
-    frame->_direction = false;
-  }
-  else if (strcmp(direction, "TOWARDS_HIGH") == 0) {
-    frame->_direction = true;
-  }
-  else {
-    parse_err(SYNERR, "invalid value inside stack direction entry.\n");
-    return;
-  }
-}
-
 //------------------------------sync_stack_slots_parse-------------------------
 void ADLParser::sync_stack_slots_parse(FrameForm *frame) {
     // Assign value into frame form
@@ -1148,9 +1134,9 @@ void ADLParser::inline_cache_parse(FrameForm *frame, bool native) {
   frame->_inline_cache_reg = parse_one_arg("inline cache reg entry");
 }
 
-//------------------------------interpreter_method_oop_parse------------------
-void ADLParser::interpreter_method_oop_parse(FrameForm *frame, bool native) {
-  frame->_interpreter_method_oop_reg = parse_one_arg("method reg entry");
+//------------------------------interpreter_method_parse------------------
+void ADLParser::interpreter_method_parse(FrameForm *frame, bool native) {
+  frame->_interpreter_method_reg = parse_one_arg("method reg entry");
 }
 
 //------------------------------cisc_spilling_operand_parse---------------------
diff --git a/src/hotspot/share/adlc/adlparse.hpp b/src/hotspot/share/adlc/adlparse.hpp
index b1d27bd50d1..f73c3a5c365 100644
--- a/src/hotspot/share/adlc/adlparse.hpp
+++ b/src/hotspot/share/adlc/adlparse.hpp
@@ -110,13 +110,12 @@ class ADLParser {
   void enc_class_parse_block(EncClass* encoding, char* ec_name);
 
   // Parse the components of the frame section
-  void stack_dir_parse(FrameForm *frame);   // Parse the stack direction entry
   void sync_stack_slots_parse(FrameForm *frame);
   void frame_pointer_parse(FrameForm *frame, bool native);
   void interpreter_frame_pointer_parse(FrameForm *frame, bool native);
   void inline_cache_parse(FrameForm *frame, bool native);
   void interpreter_arg_ptr_parse(FrameForm *frame, bool native);
-  void interpreter_method_oop_parse(FrameForm *frame, bool native);
+  void interpreter_method_parse(FrameForm *frame, bool native);
   void cisc_spilling_operand_name_parse(FrameForm *frame, bool native);
   void stack_alignment_parse(FrameForm *frame);
   void return_addr_parse(FrameForm *frame, bool native);
diff --git a/src/hotspot/share/adlc/formsopt.hpp b/src/hotspot/share/adlc/formsopt.hpp
index 7051c8909ea..0ee97160e3a 100644
--- a/src/hotspot/share/adlc/formsopt.hpp
+++ b/src/hotspot/share/adlc/formsopt.hpp
@@ -334,10 +334,9 @@ class FrameForm : public Form {
 
 public:
   // Public Data
-  bool  _direction;                // Direction of stack growth
   char *_sync_stack_slots;
   char *_inline_cache_reg;
-  char *_interpreter_method_oop_reg;
+  char *_interpreter_method_reg;
   char *_interpreter_frame_pointer_reg;
   char *_cisc_spilling_operand_name;
   char *_frame_pointer;
diff --git a/src/hotspot/share/adlc/output_c.cpp b/src/hotspot/share/adlc/output_c.cpp
index 5c4dafb6c11..674748dd1aa 100644
--- a/src/hotspot/share/adlc/output_c.cpp
+++ b/src/hotspot/share/adlc/output_c.cpp
@@ -4143,9 +4143,6 @@ void ArchDesc::buildInstructMatchCheck(FILE *fp_cpp) const {
 // Output the methods to Matcher which specify frame behavior
 void ArchDesc::buildFrameMethods(FILE *fp_cpp) {
   fprintf(fp_cpp,"\n\n");
-  // Stack Direction
-  fprintf(fp_cpp,"bool Matcher::stack_direction() const { return %s; }\n\n",
-          _frame->_direction ? "true" : "false");
   // Sync Stack Slots
   fprintf(fp_cpp,"int Compile::sync_stack_slots() const { return %s; }\n\n",
           _frame->_sync_stack_slots);
@@ -4195,12 +4192,12 @@ void ArchDesc::buildFrameMethods(FILE *fp_cpp) {
   fprintf(fp_cpp,"int Matcher::inline_cache_reg_encode() {");
   fprintf(fp_cpp," return _regEncode[inline_cache_reg()]; }\n\n");
 
-  // Interpreter's Method Oop Register, mask definition, and encoding
-  fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_method_oop_reg() {");
+  // Interpreter's Method Register, mask definition, and encoding
+  fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_method_reg() {");
   fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
-          _frame->_interpreter_method_oop_reg);
-  fprintf(fp_cpp,"int Matcher::interpreter_method_oop_reg_encode() {");
-  fprintf(fp_cpp," return _regEncode[interpreter_method_oop_reg()]; }\n\n");
+          _frame->_interpreter_method_reg);
+  fprintf(fp_cpp,"int Matcher::interpreter_method_reg_encode() {");
+  fprintf(fp_cpp," return _regEncode[interpreter_method_reg()]; }\n\n");
 
   // Interpreter's Frame Pointer Register, mask definition, and encoding
   fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_frame_pointer_reg() {");
diff --git a/src/hotspot/share/aot/aotLoader.cpp b/src/hotspot/share/aot/aotLoader.cpp
index 59dd56ab8fc..d1150589b97 100644
--- a/src/hotspot/share/aot/aotLoader.cpp
+++ b/src/hotspot/share/aot/aotLoader.cpp
@@ -31,6 +31,7 @@
 #include "oops/compressedOops.hpp"
 #include "oops/method.hpp"
 #include "runtime/arguments.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/timerTrace.hpp"
diff --git a/src/hotspot/share/c1/c1_globals.hpp b/src/hotspot/share/c1/c1_globals.hpp
index 51801875565..4c32940bc3e 100644
--- a/src/hotspot/share/c1/c1_globals.hpp
+++ b/src/hotspot/share/c1/c1_globals.hpp
@@ -32,17 +32,15 @@
 #include OS_HEADER(c1_globals)
 
 //
-// Defines all global flags used by the client compiler.
+// Declare all global flags used by the client compiler.
 //
-#define C1_FLAGS(develop, \
-                 develop_pd, \
-                 product, \
-                 product_pd, \
-                 diagnostic, \
-                 diagnostic_pd, \
-                 notproduct, \
-                 range, \
-                 constraint) \
+#define C1_FLAGS(develop,                                                   \
+                 develop_pd,                                                \
+                 product,                                                   \
+                 product_pd,                                                \
+                 notproduct,                                                \
+                 range,                                                     \
+                 constraint)                                                \
                                                                             \
   /* Printing */                                                            \
   notproduct(bool, PrintC1Statistics, false,                                \
@@ -158,7 +156,7 @@
   product(bool, InlineSynchronizedMethods, true,                            \
           "Inline synchronized methods")                                    \
                                                                             \
-  diagnostic(bool, InlineNIOCheckIndex, true,                               \
+  product(bool, InlineNIOCheckIndex, true, DIAGNOSTIC,                      \
           "Intrinsify java.nio.Buffer.checkIndex")                          \
                                                                             \
   develop(bool, CanonicalizeNodes, true,                                    \
@@ -337,7 +335,8 @@
           "Update MethodData*s in Tier1-generated code")                    \
                                                                             \
   develop(bool, PrintCFGToFile, false,                                      \
-          "print control flow graph to a separate file during compilation") \
-                                                                            \
+          "print control flow graph to a separate file during compilation")
+
+// end of C1_FLAGS
 
 #endif // SHARE_C1_C1_GLOBALS_HPP
diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp
index bd178fd2046..9eeeea27f0d 100644
--- a/src/hotspot/share/ci/ciEnv.cpp
+++ b/src/hotspot/share/ci/ciEnv.cpp
@@ -453,10 +453,10 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass,
     Klass* kls;
     if (!require_local) {
       kls = SystemDictionary::find_constrained_instance_or_array_klass(sym, loader,
-                                                                       KILL_COMPILE_ON_FATAL_(fail_type));
+                                                                       CHECK_AND_CLEAR_(fail_type));
     } else {
       kls = SystemDictionary::find_instance_or_array_klass(sym, loader, domain,
-                                                           KILL_COMPILE_ON_FATAL_(fail_type));
+                                                           CHECK_AND_CLEAR_(fail_type));
     }
     found_klass = kls;
   }
diff --git a/src/hotspot/share/ci/ciField.cpp b/src/hotspot/share/ci/ciField.cpp
index 23ba2f1ba60..df4dfc9ae63 100644
--- a/src/hotspot/share/ci/ciField.cpp
+++ b/src/hotspot/share/ci/ciField.cpp
@@ -400,7 +400,7 @@ bool ciField::will_link(ciMethod* accessing_method,
                      _name->get_symbol(), _signature->get_symbol(),
                      methodHandle(THREAD, accessing_method->get_Method()));
   fieldDescriptor result;
-  LinkResolver::resolve_field(result, link_info, bc, false, KILL_COMPILE_ON_FATAL_(false));
+  LinkResolver::resolve_field(result, link_info, bc, false, CHECK_AND_CLEAR_(false));
 
   // update the hit-cache, unless there is a problem with memory scoping:
   if (accessing_method->holder()->is_shared() || !is_shared()) {
diff --git a/src/hotspot/share/ci/ciMethod.cpp b/src/hotspot/share/ci/ciMethod.cpp
index ac9293dbb01..3fc9a0f6ebd 100644
--- a/src/hotspot/share/ci/ciMethod.cpp
+++ b/src/hotspot/share/ci/ciMethod.cpp
@@ -1241,7 +1241,7 @@ bool ciMethod::has_unloaded_classes_in_signature() {
   {
     EXCEPTION_MARK;
     methodHandle m(THREAD, get_Method());
-    bool has_unloaded = Method::has_unloaded_classes_in_signature(m, (JavaThread *)THREAD);
+    bool has_unloaded = Method::has_unloaded_classes_in_signature(m, thread);
     if( HAS_PENDING_EXCEPTION ) {
       CLEAR_PENDING_EXCEPTION;
       return true;     // Declare that we may have unloaded classes
diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp
index 5939966b330..b9fec53b08b 100644
--- a/src/hotspot/share/ci/ciReplay.cpp
+++ b/src/hotspot/share/ci/ciReplay.cpp
@@ -38,6 +38,7 @@
 #include "oops/method.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "utilities/copy.hpp"
diff --git a/src/hotspot/share/ci/ciUtilities.inline.hpp b/src/hotspot/share/ci/ciUtilities.inline.hpp
index 5c6293145a4..8b752cd812a 100644
--- a/src/hotspot/share/ci/ciUtilities.inline.hpp
+++ b/src/hotspot/share/ci/ciUtilities.inline.hpp
@@ -66,27 +66,4 @@
 #define GUARDED_VM_QUICK_ENTRY(action)      \
   {if (IS_IN_VM) { action } else { VM_QUICK_ENTRY_MARK; { action }}}
 
-// Redefine this later.
-#define KILL_COMPILE_ON_FATAL_(result)           \
-  THREAD);                                       \
-  if (HAS_PENDING_EXCEPTION) {                   \
-    if (PENDING_EXCEPTION->klass() ==            \
-        SystemDictionary::ThreadDeath_klass()) { \
-      /* Kill the compilation. */                \
-      fatal("unhandled ci exception");           \
-      return (result);                           \
-    }                                            \
-    CLEAR_PENDING_EXCEPTION;                     \
-    return (result);                             \
-  }                                              \
-  (void)(0
-
-#define KILL_COMPILE_ON_ANY                      \
-  THREAD);                                       \
-  if (HAS_PENDING_EXCEPTION) {                   \
-    fatal("unhandled ci exception");             \
-    CLEAR_PENDING_EXCEPTION;                     \
-  }                                              \
-(void)(0
-
 #endif // SHARE_CI_CIUTILITIES_INLINE_HPP
diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp
index 7c1f51e1f34..7b34ef939c5 100644
--- a/src/hotspot/share/classfile/classLoader.cpp
+++ b/src/hotspot/share/classfile/classLoader.cpp
@@ -1644,12 +1644,14 @@ void ClassLoader::create_javabase() {
 
   {
     MutexLocker ml(THREAD, Module_lock);
-    ModuleEntry* jb_module = null_cld_modules->locked_create_entry(Handle(),
+    if (ModuleEntryTable::javabase_moduleEntry() == NULL) {  // may have been inited by CDS.
+      ModuleEntry* jb_module = null_cld_modules->locked_create_entry(Handle(),
                                false, vmSymbols::java_base(), NULL, NULL, null_cld);
-    if (jb_module == NULL) {
-      vm_exit_during_initialization("Unable to create ModuleEntry for " JAVA_BASE_NAME);
+      if (jb_module == NULL) {
+        vm_exit_during_initialization("Unable to create ModuleEntry for " JAVA_BASE_NAME);
+      }
+      ModuleEntryTable::set_javabase_moduleEntry(jb_module);
     }
-    ModuleEntryTable::set_javabase_moduleEntry(jb_module);
   }
 }
 
diff --git a/src/hotspot/share/classfile/classLoaderDataShared.cpp b/src/hotspot/share/classfile/classLoaderDataShared.cpp
new file mode 100644
index 00000000000..da562f52d50
--- /dev/null
+++ b/src/hotspot/share/classfile/classLoaderDataShared.cpp
@@ -0,0 +1,202 @@
+ /*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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/classLoaderData.inline.hpp"
+#include "classfile/classLoaderDataShared.hpp"
+#include "classfile/moduleEntry.hpp"
+#include "classfile/packageEntry.hpp"
+#include "logging/log.hpp"
+#include "memory/metaspaceShared.hpp"
+#include "runtime/handles.inline.hpp"
+
+#if INCLUDE_CDS_JAVA_HEAP
+
+class ArchivedClassLoaderData {
+  Array<PackageEntry*>* _packages;
+  Array<ModuleEntry*>* _modules;
+
+  void assert_valid(ClassLoaderData* loader_data) {
+    // loader_data may be NULL if the boot layer has loaded no modules for the platform or
+    // system loaders (e.g., if you create a custom JDK image with only java.base).
+    if (loader_data != NULL) {
+      assert(!loader_data->has_class_mirror_holder(),
+             "loaders for non-strong hidden classes or unsafe anonymous classes not supported");
+    }
+  }
+public:
+  ArchivedClassLoaderData() : _packages(NULL), _modules(NULL) {}
+
+  void iterate_symbols(ClassLoaderData* loader_data, MetaspaceClosure* closure);
+  void allocate(ClassLoaderData* loader_data);
+  void init_archived_entries(ClassLoaderData* loader_data);
+  void init_archived_oops(ClassLoaderData* loader_data);
+
+  void serialize(SerializeClosure* f) {
+    f->do_ptr((void**)&_packages);
+    f->do_ptr((void**)&_modules);
+  }
+
+  void restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops);
+};
+
+static ArchivedClassLoaderData _archived_boot_loader_data;
+static ArchivedClassLoaderData _archived_platform_loader_data;
+static ArchivedClassLoaderData _archived_system_loader_data;
+static ModuleEntry* _archived_javabase_moduleEntry = NULL;
+
+void ArchivedClassLoaderData::iterate_symbols(ClassLoaderData* loader_data, MetaspaceClosure* closure) {
+  assert(DumpSharedSpaces, "must be");
+  assert_valid(loader_data);
+  if (loader_data != NULL) {
+    loader_data->packages()->iterate_symbols(closure);
+    loader_data->modules() ->iterate_symbols(closure);
+  }
+}
+
+void ArchivedClassLoaderData::allocate(ClassLoaderData* loader_data) {
+  assert(DumpSharedSpaces, "must be");
+  assert_valid(loader_data);
+  if (loader_data != NULL) {
+    // We can't create hashtables at dump time because the hashcode depends on the
+    // address of the Symbols, which may be relocated at runtime due to ASLR.
+    // So we store the packages/modules in Arrays. At runtime, we create
+    // the hashtables using these arrays.
+    _packages = loader_data->packages()->allocate_archived_entries();
+    _modules  = loader_data->modules() ->allocate_archived_entries();
+  }
+}
+
+void ArchivedClassLoaderData::init_archived_entries(ClassLoaderData* loader_data) {
+  assert(DumpSharedSpaces, "must be");
+  assert_valid(loader_data);
+  if (loader_data != NULL) {
+    loader_data->packages()->init_archived_entries(_packages);
+    loader_data->modules() ->init_archived_entries(_modules);
+  }
+}
+
+void ArchivedClassLoaderData::init_archived_oops(ClassLoaderData* loader_data) {
+  assert(DumpSharedSpaces, "must be");
+  assert_valid(loader_data);
+  if (loader_data != NULL) {
+    loader_data->modules()->init_archived_oops(_modules);
+  }
+}
+
+void ArchivedClassLoaderData::restore(ClassLoaderData* loader_data, bool do_entries, bool do_oops) {
+  assert(UseSharedSpaces, "must be");
+  assert_valid(loader_data);
+  if (_modules != NULL) { // Could be NULL if we have archived no modules for platform/system loaders
+    ModuleEntryTable* modules = loader_data->modules();
+    PackageEntryTable* packages = loader_data->packages();
+
+    MutexLocker m1(Module_lock);
+    if (do_entries) {
+      modules->load_archived_entries(loader_data, _modules);
+      packages->load_archived_entries(_packages);
+    }
+    if (do_oops) {
+      modules->restore_archived_oops(loader_data, _modules);
+    }
+  }
+}
+
+// ------------------------------
+
+static ClassLoaderData* null_class_loader_data() {
+  ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+  assert(loader_data != NULL, "must be");
+  return loader_data;
+}
+
+static ClassLoaderData* java_platform_loader_data_or_null() {
+  return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_platform_loader());
+}
+
+static ClassLoaderData* java_system_loader_data_or_null() {
+  return ClassLoaderData::class_loader_data_or_null(SystemDictionary::java_system_loader());
+}
+
+void ClassLoaderDataShared::iterate_symbols(MetaspaceClosure* closure) {
+  assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
+  _archived_boot_loader_data.iterate_symbols    (null_class_loader_data(), closure);
+  _archived_platform_loader_data.iterate_symbols(java_platform_loader_data_or_null(), closure);
+  _archived_system_loader_data.iterate_symbols  (java_system_loader_data_or_null(), closure);
+}
+
+void ClassLoaderDataShared::allocate_archived_tables() {
+  assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
+  _archived_boot_loader_data.allocate    (null_class_loader_data());
+  _archived_platform_loader_data.allocate(java_platform_loader_data_or_null());
+  _archived_system_loader_data.allocate  (java_system_loader_data_or_null());
+}
+
+void ClassLoaderDataShared::init_archived_tables() {
+  assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
+  _archived_boot_loader_data.init_archived_entries    (null_class_loader_data());
+  _archived_platform_loader_data.init_archived_entries(java_platform_loader_data_or_null());
+  _archived_system_loader_data.init_archived_entries  (java_system_loader_data_or_null());
+  _archived_javabase_moduleEntry = ModuleEntry::get_archived_entry(ModuleEntryTable::javabase_moduleEntry());
+}
+
+void ClassLoaderDataShared::init_archived_oops() {
+  assert(DumpSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
+  _archived_boot_loader_data.init_archived_oops    (null_class_loader_data());
+  _archived_platform_loader_data.init_archived_oops(java_platform_loader_data_or_null());
+  _archived_system_loader_data.init_archived_oops  (java_system_loader_data_or_null());
+}
+
+void ClassLoaderDataShared::serialize(SerializeClosure* f) {
+  _archived_boot_loader_data.serialize(f);
+  _archived_platform_loader_data.serialize(f);
+  _archived_system_loader_data.serialize(f);
+  f->do_ptr((void**)&_archived_javabase_moduleEntry);
+
+  if (f->reading() && MetaspaceShared::use_full_module_graph()) {
+    // Must be done before ClassLoader::create_javabase()
+    _archived_boot_loader_data.restore(null_class_loader_data(), true, false);
+    ModuleEntryTable::set_javabase_moduleEntry(_archived_javabase_moduleEntry);
+    log_info(cds)("use_full_module_graph = true; java.base = " INTPTR_FORMAT,
+                  p2i(_archived_javabase_moduleEntry));
+  }
+}
+
+oop ClassLoaderDataShared::restore_archived_oops_for_null_class_loader_data() {
+  assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
+  _archived_boot_loader_data.restore(null_class_loader_data(), false, true);
+  return _archived_javabase_moduleEntry->module();
+}
+
+void ClassLoaderDataShared::restore_java_platform_loader_from_archive(ClassLoaderData* loader_data) {
+  assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
+  _archived_platform_loader_data.restore(loader_data, true, true);
+}
+
+void ClassLoaderDataShared::restore_java_system_loader_from_archive(ClassLoaderData* loader_data) {
+  assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
+  _archived_system_loader_data.restore(loader_data, true, true);
+}
+
+#endif // INCLUDE_CDS_JAVA_HEAP
diff --git a/src/hotspot/share/classfile/classLoaderDataShared.hpp b/src/hotspot/share/classfile/classLoaderDataShared.hpp
new file mode 100644
index 00000000000..03d8f51ae3b
--- /dev/null
+++ b/src/hotspot/share/classfile/classLoaderDataShared.hpp
@@ -0,0 +1,47 @@
+ /*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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_CLASSLOADERDATASHARED_HPP
+#define SHARE_CLASSFILE_CLASSLOADERDATASHARED_HPP
+
+#include "memory/allStatic.hpp"
+#include "oops/oopsHierarchy.hpp"
+
+class ClassLoaderData;
+class MetaspaceClosure;
+class SerializeClosure;
+
+class ClassLoaderDataShared : AllStatic {
+public:
+  static void allocate_archived_tables();
+  static void iterate_symbols(MetaspaceClosure* closure);
+  static void init_archived_tables();
+  static void init_archived_oops();
+  static void serialize(SerializeClosure* f);
+  static oop  restore_archived_oops_for_null_class_loader_data();
+  static void restore_java_platform_loader_from_archive(ClassLoaderData* loader_data);
+  static void restore_java_system_loader_from_archive(ClassLoaderData* loader_data);
+};
+
+#endif // SHARE_CLASSFILE_CLASSLOADERDATASHARED_HPP
diff --git a/src/hotspot/share/classfile/classLoaderExt.cpp b/src/hotspot/share/classfile/classLoaderExt.cpp
index a5aa7563f2b..666b45404e0 100644
--- a/src/hotspot/share/classfile/classLoaderExt.cpp
+++ b/src/hotspot/share/classfile/classLoaderExt.cpp
@@ -270,7 +270,7 @@ InstanceKlass* ClassLoaderExt::load_class(Symbol* name, const char* path, TRAPS)
   }
   {
     PerfClassTraceTime vmtimer(perf_sys_class_lookup_time(),
-                               ((JavaThread*) THREAD)->get_thread_stat()->perf_timers_addr(),
+                               THREAD->as_Java_thread()->get_thread_stat()->perf_timers_addr(),
                                PerfClassTraceTime::CLASS_LOAD);
     stream = e->open_stream(file_name, CHECK_NULL);
   }
diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp
index 8b3afbc94c4..abaf2fb4f6e 100644
--- a/src/hotspot/share/classfile/javaClasses.cpp
+++ b/src/hotspot/share/classfile/javaClasses.cpp
@@ -408,8 +408,7 @@ Handle java_lang_String::create_from_platform_dependent_str(const char* str, TRA
 
   jstring js = NULL;
   {
-    assert(THREAD->is_Java_thread(), "must be java thread");
-    JavaThread* thread = (JavaThread*)THREAD;
+    JavaThread* thread = THREAD->as_Java_thread();
     HandleMark hm(thread);
     ThreadToNativeFromVM ttn(thread);
     js = (_to_java_string_fn)(thread->jni_environment(), str);
@@ -435,8 +434,7 @@ char* java_lang_String::as_platform_dependent_str(Handle java_string, TRAPS) {
   }
 
   char *native_platform_string;
-  { JavaThread* thread = (JavaThread*)THREAD;
-    assert(thread->is_Java_thread(), "must be java thread");
+  { JavaThread* thread = THREAD->as_Java_thread();
     jstring js = (jstring) JNIHandles::make_local(thread, java_string());
     bool is_copy;
     HandleMark hm(thread);
@@ -2416,7 +2414,7 @@ void java_lang_Throwable::fill_in_stack_trace(Handle throwable, const methodHand
   clear_stacktrace(throwable());
 
   int max_depth = MaxJavaStackTraceDepth;
-  JavaThread* thread = (JavaThread*)THREAD;
+  JavaThread* thread = THREAD->as_Java_thread();
 
   BacktraceBuilder bt(CHECK);
 
@@ -3394,12 +3392,17 @@ void java_lang_Module::set_name(oop module, oop value) {
   module->obj_field_put(_name_offset, value);
 }
 
-ModuleEntry* java_lang_Module::module_entry(oop module) {
+ModuleEntry* java_lang_Module::module_entry_raw(oop module) {
   assert(_module_entry_offset != 0, "Uninitialized module_entry_offset");
   assert(module != NULL, "module can't be null");
   assert(oopDesc::is_oop(module), "module must be oop");
 
   ModuleEntry* module_entry = (ModuleEntry*)module->address_field(_module_entry_offset);
+  return module_entry;
+}
+
+ModuleEntry* java_lang_Module::module_entry(oop module) {
+  ModuleEntry* module_entry = module_entry_raw(module);
   if (module_entry == NULL) {
     // If the inject field containing the ModuleEntry* is null then return the
     // class loader's unnamed module.
@@ -4823,9 +4826,8 @@ bool JavaClasses::is_supported_for_archiving(oop obj) {
   Klass* klass = obj->klass();
 
   if (klass == SystemDictionary::ClassLoader_klass() ||  // ClassLoader::loader_data is malloc'ed.
-      klass == SystemDictionary::Module_klass() ||       // Module::module_entry is malloc'ed
       // The next 3 classes are used to implement java.lang.invoke, and are not used directly in
-      // regular Java code. The implementation of java.lang.invoke uses generated anonymoys classes
+      // regular Java code. The implementation of java.lang.invoke uses generated anonymous classes
       // (e.g., as referenced by ResolvedMethodName::vmholder) that are not yet supported by CDS.
       // So for now we cannot not support these classes for archiving.
       //
diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp
index 537c2523bec..c7916cb4ea3 100644
--- a/src/hotspot/share/classfile/javaClasses.hpp
+++ b/src/hotspot/share/classfile/javaClasses.hpp
@@ -797,6 +797,7 @@ class java_lang_Module {
     static void set_name(oop module, oop value);
 
     static ModuleEntry* module_entry(oop module);
+    static ModuleEntry* module_entry_raw(oop module);
     static void set_module_entry(oop module, ModuleEntry* module_entry);
 
   friend class JavaClasses;
diff --git a/src/hotspot/share/classfile/klassFactory.cpp b/src/hotspot/share/classfile/klassFactory.cpp
index d89018f1e7a..a02d01020b5 100644
--- a/src/hotspot/share/classfile/klassFactory.cpp
+++ b/src/hotspot/share/classfile/klassFactory.cpp
@@ -120,8 +120,7 @@ static ClassFileStream* check_class_file_load_hook(ClassFileStream* stream,
   assert(stream != NULL, "invariant");
 
   if (JvmtiExport::should_post_class_file_load_hook()) {
-    assert(THREAD->is_Java_thread(), "must be a JavaThread");
-    const JavaThread* jt = (JavaThread*)THREAD;
+    const JavaThread* jt = THREAD->as_Java_thread();
 
     Handle class_loader(THREAD, loader_data->class_loader());
 
diff --git a/src/hotspot/share/classfile/moduleEntry.cpp b/src/hotspot/share/classfile/moduleEntry.cpp
index 80d96adb1d7..e1b45955b4f 100644
--- a/src/hotspot/share/classfile/moduleEntry.cpp
+++ b/src/hotspot/share/classfile/moduleEntry.cpp
@@ -29,7 +29,11 @@
 #include "classfile/javaClasses.inline.hpp"
 #include "classfile/moduleEntry.hpp"
 #include "logging/log.hpp"
+#include "memory/archiveBuilder.hpp"
+#include "memory/archiveUtils.hpp"
 #include "memory/filemap.hpp"
+#include "memory/heapShared.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/oopHandle.inline.hpp"
@@ -40,6 +44,8 @@
 #include "utilities/growableArray.hpp"
 #include "utilities/hashtable.inline.hpp"
 #include "utilities/ostream.hpp"
+#include "utilities/quickSort.hpp"
+#include "utilities/resourceHash.hpp"
 
 ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
 
@@ -108,15 +114,15 @@ void ModuleEntry::set_version(Symbol* version) {
 
 // Returns the shared ProtectionDomain
 oop ModuleEntry::shared_protection_domain() {
-  return _pd.resolve();
+  return _shared_pd.resolve();
 }
 
 // Set the shared ProtectionDomain atomically
 void ModuleEntry::set_shared_protection_domain(ClassLoaderData *loader_data,
                                                Handle pd_h) {
   // Create a handle for the shared ProtectionDomain and save it atomically.
-  // init_handle_locked checks if someone beats us setting the _pd cache.
-  loader_data->init_handle_locked(_pd, pd_h);
+  // init_handle_locked checks if someone beats us setting the _shared_pd cache.
+  loader_data->init_handle_locked(_shared_pd, pd_h);
 }
 
 // Returns true if this module can read module m
@@ -362,6 +368,203 @@ ModuleEntryTable::~ModuleEntryTable() {
   assert(new_entry_free_list() == NULL, "entry present on ModuleEntryTable's free list");
 }
 
+#if INCLUDE_CDS_JAVA_HEAP
+typedef ResourceHashtable<
+  const ModuleEntry*,
+  ModuleEntry*,
+  primitive_hash<const ModuleEntry*>,
+  primitive_equals<const ModuleEntry*>,
+  557, // prime number
+  ResourceObj::C_HEAP> ArchivedModuleEntries;
+static ArchivedModuleEntries* _archive_modules_entries = NULL;
+
+ModuleEntry* ModuleEntry::allocate_archived_entry() const {
+  assert(is_named(), "unnamed packages/modules are not archived");
+  ModuleEntry* archived_entry = (ModuleEntry*)MetaspaceShared::read_write_space_alloc(sizeof(ModuleEntry));
+  memcpy((void*)archived_entry, (void*)this, sizeof(ModuleEntry));
+
+  if (_archive_modules_entries == NULL) {
+    _archive_modules_entries = new (ResourceObj::C_HEAP, mtClass)ArchivedModuleEntries();
+  }
+  assert(_archive_modules_entries->get(this) == NULL, "Each ModuleEntry must not be shared across ModuleEntryTables");
+  _archive_modules_entries->put(this, archived_entry);
+
+  return archived_entry;
+}
+
+ModuleEntry* ModuleEntry::get_archived_entry(ModuleEntry* orig_entry) {
+  ModuleEntry** ptr = _archive_modules_entries->get(orig_entry);
+  assert(ptr != NULL && *ptr != NULL, "must have been allocated");
+  return *ptr;
+}
+
+// This function is used to archive ModuleEntry::_reads and PackageEntry::_qualified_exports.
+// GrowableArray cannot be directly archived, as it needs to be expandable at runtime.
+// Write it out as an Array, and convert it back to GrowableArray at runtime.
+Array<ModuleEntry*>* ModuleEntry::write_growable_array(GrowableArray<ModuleEntry*>* array) {
+  Array<ModuleEntry*>* archived_array = NULL;
+  int length = (array == NULL) ? 0 : array->length();
+  if (length > 0) {
+    archived_array = MetaspaceShared::new_ro_array<ModuleEntry*>(length);
+    for (int i = 0; i < length; i++) {
+      ModuleEntry* archived_entry = get_archived_entry(array->at(i));
+      archived_array->at_put(i, archived_entry);
+      ArchivePtrMarker::mark_pointer((address*)archived_array->adr_at(i));
+    }
+  }
+
+  return archived_array;
+}
+
+GrowableArray<ModuleEntry*>* ModuleEntry::restore_growable_array(Array<ModuleEntry*>* archived_array) {
+  GrowableArray<ModuleEntry*>* array = NULL;
+  int length = (archived_array == NULL) ? 0 : archived_array->length();
+  if (length > 0) {
+    array = new (ResourceObj::C_HEAP, mtModule)GrowableArray<ModuleEntry*>(length, mtModule);
+    for (int i = 0; i < length; i++) {
+      ModuleEntry* archived_entry = archived_array->at(i);
+      array->append(archived_entry);
+    }
+  }
+
+  return array;
+}
+
+void ModuleEntry::iterate_symbols(MetaspaceClosure* closure) {
+  closure->push(literal_addr()); // name
+  closure->push(&_version);
+  closure->push(&_location);
+}
+
+void ModuleEntry::init_as_archived_entry() {
+  Array<ModuleEntry*>* archived_reads = write_growable_array(_reads);
+
+  set_next(NULL);
+  set_hash(0x0);        // re-init at runtime
+  _loader_data = NULL;  // re-init at runtime
+  _shared_path_index = FileMapInfo::get_module_shared_path_index(_location);
+  if (literal() != NULL) {
+    set_literal(ArchiveBuilder::get_relocated_symbol(literal()));
+    ArchivePtrMarker::mark_pointer((address*)literal_addr());
+  }
+  _reads = (GrowableArray<ModuleEntry*>*)archived_reads;
+  if (_version != NULL) {
+    _version = ArchiveBuilder::get_relocated_symbol(_version);
+  }
+  if (_location != NULL) {
+    _location = ArchiveBuilder::get_relocated_symbol(_location);
+  }
+
+  ArchivePtrMarker::mark_pointer((address*)&_reads);
+  ArchivePtrMarker::mark_pointer((address*)&_version);
+  ArchivePtrMarker::mark_pointer((address*)&_location);
+}
+
+void ModuleEntry::init_archived_oops() {
+  assert(DumpSharedSpaces, "static dump only");
+  oop module_obj = module();
+  if (module_obj != NULL) {
+    oop m = HeapShared::find_archived_heap_object(module_obj);
+    assert(m != NULL, "sanity");
+    _archived_module_narrow_oop = CompressedOops::encode(m);
+  }
+  assert(shared_protection_domain() == NULL, "never set during -Xshare:dump");
+  // Clear handles and restore at run time. Handles cannot be archived.
+  OopHandle null_handle;
+  _module = null_handle;
+}
+
+void ModuleEntry::load_from_archive(ClassLoaderData* loader_data) {
+  set_loader_data(loader_data);
+  _reads = restore_growable_array((Array<ModuleEntry*>*)_reads);
+  JFR_ONLY(INIT_ID(this);)
+}
+
+void ModuleEntry::restore_archive_oops(ClassLoaderData* loader_data) {
+  Handle module_handle(Thread::current(), HeapShared::materialize_archived_object(_archived_module_narrow_oop));
+  assert(module_handle.not_null(), "huh");
+  set_module(loader_data->add_handle(module_handle));
+
+  // This was cleared to zero during dump time -- we didn't save the value
+  // because it may be affected by archive relocation.
+  java_lang_Module::set_module_entry(module_handle(), this);
+
+  if (loader_data->class_loader() != NULL) {
+    java_lang_Module::set_loader(module_handle(), loader_data->class_loader());
+  }
+}
+
+static int compare_module_by_name(ModuleEntry* a, ModuleEntry* b) {
+  assert(a == b || a->name() != b->name(), "no duplicated names");
+  return a->name()->fast_compare(b->name());
+}
+
+void ModuleEntryTable::iterate_symbols(MetaspaceClosure* closure) {
+  for (int i = 0; i < table_size(); ++i) {
+    for (ModuleEntry* m = bucket(i); m != NULL; m = m->next()) {
+      m->iterate_symbols(closure);
+    }
+  }
+}
+
+Array<ModuleEntry*>* ModuleEntryTable::allocate_archived_entries() {
+  Array<ModuleEntry*>* archived_modules = MetaspaceShared::new_rw_array<ModuleEntry*>(number_of_entries());
+  int n = 0;
+  for (int i = 0; i < table_size(); ++i) {
+    for (ModuleEntry* m = bucket(i); m != NULL; m = m->next()) {
+      archived_modules->at_put(n++, m);
+    }
+  }
+  if (n > 1) {
+    // Always allocate in the same order to produce deterministic archive.
+    QuickSort::sort(archived_modules->data(), n, (_sort_Fn)compare_module_by_name, true);
+  }
+  for (int i = 0; i < n; i++) {
+    archived_modules->at_put(i, archived_modules->at(i)->allocate_archived_entry());
+    ArchivePtrMarker::mark_pointer((address*)archived_modules->adr_at(i));
+  }
+  return archived_modules;
+}
+
+void ModuleEntryTable::init_archived_entries(Array<ModuleEntry*>* archived_modules) {
+  assert(DumpSharedSpaces, "dump time only");
+  for (int i = 0; i < archived_modules->length(); i++) {
+    ModuleEntry* archived_entry = archived_modules->at(i);
+    archived_entry->init_as_archived_entry();
+  }
+}
+
+void ModuleEntryTable::init_archived_oops(Array<ModuleEntry*>* archived_modules) {
+  assert(DumpSharedSpaces, "dump time only");
+  for (int i = 0; i < archived_modules->length(); i++) {
+    ModuleEntry* archived_entry = archived_modules->at(i);
+    archived_entry->init_archived_oops();
+  }
+}
+
+void ModuleEntryTable::load_archived_entries(ClassLoaderData* loader_data,
+                                             Array<ModuleEntry*>* archived_modules) {
+  assert(UseSharedSpaces, "runtime only");
+
+  for (int i = 0; i < archived_modules->length(); i++) {
+    ModuleEntry* archived_entry = archived_modules->at(i);
+    archived_entry->load_from_archive(loader_data);
+
+    unsigned int hash = compute_hash(archived_entry->name());
+    archived_entry->set_hash(hash);
+    add_entry(hash_to_index(hash), archived_entry);
+  }
+}
+
+void ModuleEntryTable::restore_archived_oops(ClassLoaderData* loader_data, Array<ModuleEntry*>* archived_modules) {
+  assert(UseSharedSpaces, "runtime only");
+  for (int i = 0; i < archived_modules->length(); i++) {
+    ModuleEntry* archived_entry = archived_modules->at(i);
+    archived_entry->restore_archive_oops(loader_data);
+  }
+}
+#endif // INCLUDE_CDS_JAVA_HEAP
+
 ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, Handle module_handle,
                                          bool is_open, Symbol* name,
                                          Symbol* version, Symbol* location,
diff --git a/src/hotspot/share/classfile/moduleEntry.hpp b/src/hotspot/share/classfile/moduleEntry.hpp
index 8aa885464c8..ec09fc3eda5 100644
--- a/src/hotspot/share/classfile/moduleEntry.hpp
+++ b/src/hotspot/share/classfile/moduleEntry.hpp
@@ -47,6 +47,8 @@
 #define JAVA_BASE_NAME "java.base"
 #define JAVA_BASE_NAME_LEN 9
 
+template <class T> class Array;
+class MetaspaceClosure;
 class ModuleClosure;
 
 // A ModuleEntry describes a module that has been defined by a call to JVM_DefineModule.
@@ -63,7 +65,7 @@ class ModuleClosure;
 class ModuleEntry : public HashtableEntry<Symbol*, mtModule> {
 private:
   OopHandle _module;                   // java.lang.Module
-  OopHandle _pd;                       // java.security.ProtectionDomain, cached
+  OopHandle _shared_pd;                // java.security.ProtectionDomain, cached
                                        // for shared classes from this module
   ClassLoaderData* _loader_data;
   GrowableArray<ModuleEntry*>* _reads; // list of modules that are readable by this module
@@ -75,13 +77,15 @@ class ModuleEntry : public HashtableEntry<Symbol*, mtModule> {
   bool _must_walk_reads;               // walk module's reads list at GC safepoints to purge out dead modules
   bool _is_open;                       // whether the packages in the module are all unqualifiedly exported
   bool _is_patched;                    // whether the module is patched via --patch-module
+  CDS_JAVA_HEAP_ONLY(narrowOop _archived_module_narrow_oop;)
+
   JFR_ONLY(DEFINE_TRACE_ID_FIELD;)
   enum {MODULE_READS_SIZE = 101};      // Initial size of list of modules that the module can read.
 
 public:
   void init() {
     _module = OopHandle();
-    _pd = OopHandle();
+    _shared_pd = OopHandle();
     _loader_data = NULL;
     _reads = NULL;
     _version = NULL;
@@ -188,6 +192,18 @@ class ModuleEntry : public HashtableEntry<Symbol*, mtModule> {
   CDS_ONLY(int shared_path_index() { return _shared_path_index;})
 
   JFR_ONLY(DEFINE_TRACE_ID_METHODS;)
+
+#if INCLUDE_CDS_JAVA_HEAP
+  void iterate_symbols(MetaspaceClosure* closure);
+  ModuleEntry* allocate_archived_entry() const;
+  void init_as_archived_entry();
+  void init_archived_oops();
+  static ModuleEntry* get_archived_entry(ModuleEntry* orig_entry);
+  static Array<ModuleEntry*>* write_growable_array(GrowableArray<ModuleEntry*>* array);
+  static GrowableArray<ModuleEntry*>* restore_growable_array(Array<ModuleEntry*>* archived_array);
+  void load_from_archive(ClassLoaderData* loader_data);
+  void restore_archive_oops(ClassLoaderData* loader_data);
+#endif
 };
 
 // Iterator interface
@@ -270,6 +286,17 @@ class ModuleEntryTable : public Hashtable<Symbol*, mtModule> {
 
   void print(outputStream* st = tty);
   void verify();
+
+#if INCLUDE_CDS_JAVA_HEAP
+  void iterate_symbols(MetaspaceClosure* closure);
+  Array<ModuleEntry*>* allocate_archived_entries();
+  void init_archived_entries(Array<ModuleEntry*>* archived_modules);
+  void init_archived_oops(Array<ModuleEntry*>* archived_modules);
+  void load_archived_entries(ClassLoaderData* loader_data,
+                             Array<ModuleEntry*>* archived_modules);
+  void restore_archived_oops(ClassLoaderData* loader_data,
+                             Array<ModuleEntry*>* archived_modules);
+#endif
 };
 
 #endif // SHARE_CLASSFILE_MODULEENTRY_HPP
diff --git a/src/hotspot/share/classfile/modules.cpp b/src/hotspot/share/classfile/modules.cpp
index 1b09052e601..b0dd93d0c21 100644
--- a/src/hotspot/share/classfile/modules.cpp
+++ b/src/hotspot/share/classfile/modules.cpp
@@ -27,6 +27,7 @@
 #include "classfile/classFileParser.hpp"
 #include "classfile/classLoader.hpp"
 #include "classfile/classLoaderData.inline.hpp"
+#include "classfile/classLoaderDataShared.hpp"
 #include "classfile/javaAssertions.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/javaClasses.inline.hpp"
@@ -39,7 +40,9 @@
 #include "classfile/vmSymbols.hpp"
 #include "logging/log.hpp"
 #include "logging/logStream.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
+#include "prims/jvmtiExport.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/jniHandles.inline.hpp"
@@ -268,6 +271,7 @@ void throw_dup_pkg_exception(const char* module_name, PackageEntry* package, TRA
 
 void Modules::define_module(jobject module, jboolean is_open, jstring version,
                             jstring location, jobjectArray packages, TRAPS) {
+  check_cds_restrictions(CHECK);
   ResourceMark rm(THREAD);
 
   if (module == NULL) {
@@ -450,6 +454,46 @@ void Modules::define_module(jobject module, jboolean is_open, jstring version,
   }
 }
 
+#if INCLUDE_CDS_JAVA_HEAP
+void Modules::define_archived_modules(jobject platform_loader, jobject system_loader, TRAPS) {
+  assert(UseSharedSpaces && MetaspaceShared::use_full_module_graph(), "must be");
+
+  // We don't want the classes used by the archived full module graph to be redefined by JVMTI.
+  // Luckily, such classes are loaded in the JVMTI "early" phase, and CDS is disabled if a JVMTI
+  // agent wants to redefine classes in this phase.
+  JVMTI_ONLY(assert(JvmtiExport::is_early_phase(), "must be"));
+  assert(!(JvmtiExport::should_post_class_file_load_hook() && JvmtiExport::has_early_class_hook_env()),
+         "CDS should be disabled if early class hooks are enabled");
+
+  Handle java_base_module(THREAD, ClassLoaderDataShared::restore_archived_oops_for_null_class_loader_data());
+  // Patch any previously loaded class's module field with java.base's java.lang.Module.
+  ModuleEntryTable::patch_javabase_entries(java_base_module);
+
+  if (platform_loader == NULL) {
+    THROW_MSG(vmSymbols::java_lang_NullPointerException(), "Null platform loader object");
+  }
+
+  if (system_loader == NULL) {
+    THROW_MSG(vmSymbols::java_lang_NullPointerException(), "Null system loader object");
+  }
+
+  Handle h_platform_loader(THREAD, JNIHandles::resolve_non_null(platform_loader));
+  ClassLoaderData* platform_loader_data = SystemDictionary::register_loader(h_platform_loader);
+  ClassLoaderDataShared::restore_java_platform_loader_from_archive(platform_loader_data);
+
+  Handle h_system_loader(THREAD, JNIHandles::resolve_non_null(system_loader));
+  ClassLoaderData* system_loader_data = SystemDictionary::register_loader(h_system_loader);
+  ClassLoaderDataShared::restore_java_system_loader_from_archive(system_loader_data);
+}
+
+void Modules::check_cds_restrictions(TRAPS) {
+  if (DumpSharedSpaces && Universe::is_module_initialized() && MetaspaceShared::use_full_module_graph()) {
+    THROW_MSG(vmSymbols::java_lang_UnsupportedOperationException(),
+              "During -Xshare:dump, module system cannot be modified after it's initialized");
+  }
+}
+#endif // INCLUDE_CDS_JAVA_HEAP
+
 void Modules::set_bootloader_unnamed_module(jobject module, TRAPS) {
   ResourceMark rm(THREAD);
 
@@ -488,6 +532,7 @@ void Modules::set_bootloader_unnamed_module(jobject module, TRAPS) {
 }
 
 void Modules::add_module_exports(jobject from_module, jstring package_name, jobject to_module, TRAPS) {
+  check_cds_restrictions(CHECK);
 
   if (package_name == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(),
@@ -555,6 +600,7 @@ void Modules::add_module_exports(jobject from_module, jstring package_name, jobj
 
 void Modules::add_module_exports_qualified(jobject from_module, jstring package,
                                            jobject to_module, TRAPS) {
+  check_cds_restrictions(CHECK);
   if (to_module == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(),
               "to_module is null");
@@ -563,6 +609,7 @@ void Modules::add_module_exports_qualified(jobject from_module, jstring package,
 }
 
 void Modules::add_reads_module(jobject from_module, jobject to_module, TRAPS) {
+  check_cds_restrictions(CHECK);
   if (from_module == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(),
               "from_module is null");
@@ -668,6 +715,7 @@ jobject Modules::get_named_module(Handle h_loader, const char* package_name, TRA
 
 // Export package in module to all unnamed modules.
 void Modules::add_module_exports_to_all_unnamed(jobject module, jstring package_name, TRAPS) {
+  check_cds_restrictions(CHECK);
   if (module == NULL) {
     THROW_MSG(vmSymbols::java_lang_NullPointerException(),
               "module is null");
diff --git a/src/hotspot/share/classfile/modules.hpp b/src/hotspot/share/classfile/modules.hpp
index 434a0cfaf23..b76aa8b4aed 100644
--- a/src/hotspot/share/classfile/modules.hpp
+++ b/src/hotspot/share/classfile/modules.hpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -32,6 +32,7 @@ class ModuleEntryTable;
 class Symbol;
 
 class Modules : AllStatic {
+  static void check_cds_restrictions(TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
 
 public:
   // define_module defines a module containing the specified packages. It binds the
@@ -52,6 +53,9 @@ class Modules : AllStatic {
   static void define_module(jobject module, jboolean is_open, jstring version,
                             jstring location, jobjectArray packages, TRAPS);
 
+  static void define_archived_modules(jobject platform_loader, jobject system_loader,
+                                      TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
+
   // Provides the java.lang.Module for the unnamed module defined
   // to the boot loader.
   //
diff --git a/src/hotspot/share/classfile/packageEntry.cpp b/src/hotspot/share/classfile/packageEntry.cpp
index 48475f33183..da83bd519aa 100644
--- a/src/hotspot/share/classfile/packageEntry.cpp
+++ b/src/hotspot/share/classfile/packageEntry.cpp
@@ -26,7 +26,11 @@
 #include "classfile/moduleEntry.hpp"
 #include "classfile/packageEntry.hpp"
 #include "logging/log.hpp"
+#include "memory/archiveBuilder.hpp"
+#include "memory/archiveUtils.hpp"
+#include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
+#include "oops/array.hpp"
 #include "oops/symbol.hpp"
 #include "runtime/java.hpp"
 #include "runtime/handles.inline.hpp"
@@ -34,6 +38,8 @@
 #include "utilities/growableArray.hpp"
 #include "utilities/hashtable.inline.hpp"
 #include "utilities/ostream.hpp"
+#include "utilities/quickSort.hpp"
+#include "utilities/resourceHash.hpp"
 
 // Returns true if this package specifies m as a qualified export, including through an unnamed export
 bool PackageEntry::is_qexported_to(ModuleEntry* m) const {
@@ -189,6 +195,126 @@ PackageEntryTable::~PackageEntryTable() {
   assert(new_entry_free_list() == NULL, "entry present on PackageEntryTable's free list");
 }
 
+#if INCLUDE_CDS_JAVA_HEAP
+typedef ResourceHashtable<
+  const PackageEntry*,
+  PackageEntry*,
+  primitive_hash<const PackageEntry*>,
+  primitive_equals<const PackageEntry*>,
+  557, // prime number
+  ResourceObj::C_HEAP> ArchivedPackageEntries;
+static ArchivedPackageEntries* _archived_packages_entries = NULL;
+
+PackageEntry* PackageEntry::allocate_archived_entry() const {
+  assert(!in_unnamed_module(), "unnamed packages/modules are not archived");
+  PackageEntry* archived_entry = (PackageEntry*)MetaspaceShared::read_write_space_alloc(sizeof(PackageEntry));
+  memcpy((void*)archived_entry, (void*)this, sizeof(PackageEntry));
+
+  if (_archived_packages_entries == NULL) {
+    _archived_packages_entries = new (ResourceObj::C_HEAP, mtClass)ArchivedPackageEntries();
+  }
+  assert(_archived_packages_entries->get(this) == NULL, "Each PackageEntry must not be shared across PackageEntryTables");
+  _archived_packages_entries->put(this, archived_entry);
+
+  return archived_entry;
+}
+
+PackageEntry* PackageEntry::get_archived_entry(PackageEntry* orig_entry) {
+  PackageEntry** ptr = _archived_packages_entries->get(orig_entry);
+  assert(ptr != NULL && *ptr != NULL, "must have been allocated");
+  return *ptr;
+}
+
+void PackageEntry::iterate_symbols(MetaspaceClosure* closure) {
+  closure->push(literal_addr()); // name
+}
+
+void PackageEntry::init_as_archived_entry() {
+  Array<ModuleEntry*>* archived_qualified_exports = ModuleEntry::write_growable_array(_qualified_exports);
+
+  set_next(NULL);
+  set_literal(ArchiveBuilder::get_relocated_symbol(literal()));
+  set_hash(0x0);  // re-init at runtime
+  _module = ModuleEntry::get_archived_entry(_module);
+  _qualified_exports = (GrowableArray<ModuleEntry*>*)archived_qualified_exports;
+  _defined_by_cds_in_class_path = 0;
+
+  ArchivePtrMarker::mark_pointer((address*)literal_addr());
+  ArchivePtrMarker::mark_pointer((address*)&_module);
+  ArchivePtrMarker::mark_pointer((address*)&_qualified_exports);
+}
+
+void PackageEntry::load_from_archive() {
+  _qualified_exports = ModuleEntry::restore_growable_array((Array<ModuleEntry*>*)_qualified_exports);
+  JFR_ONLY(INIT_ID(this);)
+}
+
+static int compare_package_by_name(PackageEntry* a, PackageEntry* b) {
+  assert(a == b || a->name() != b->name(), "no duplicated names");
+  return a->name()->fast_compare(b->name());
+}
+
+void PackageEntryTable::iterate_symbols(MetaspaceClosure* closure) {
+  for (int i = 0; i < table_size(); ++i) {
+    for (PackageEntry* p = bucket(i); p != NULL; p = p->next()) {
+      p->iterate_symbols(closure);
+    }
+  }
+}
+
+Array<PackageEntry*>* PackageEntryTable::allocate_archived_entries() {
+  // First count the packages in named modules
+  int n, i;
+  for (n = 0, i = 0; i < table_size(); ++i) {
+    for (PackageEntry* p = bucket(i); p != NULL; p = p->next()) {
+      if (p->module()->name() != NULL) {
+        n++;
+      }
+    }
+  }
+
+  Array<PackageEntry*>* archived_packages = MetaspaceShared::new_rw_array<PackageEntry*>(n);
+  for (n = 0, i = 0; i < table_size(); ++i) {
+    for (PackageEntry* p = bucket(i); p != NULL; p = p->next()) {
+      if (p->module()->name() != NULL) {
+        // We don't archive unnamed modules, or packages in unnamed modules. They will be
+        // created on-demand at runtime as classes in such packages are loaded.
+        archived_packages->at_put(n++, p);
+      }
+    }
+  }
+  if (n > 1) {
+    QuickSort::sort(archived_packages->data(), n, (_sort_Fn)compare_package_by_name, true);
+  }
+  for (i = 0; i < n; i++) {
+    archived_packages->at_put(i, archived_packages->at(i)->allocate_archived_entry());
+    ArchivePtrMarker::mark_pointer((address*)archived_packages->adr_at(i));
+  }
+  return archived_packages;
+}
+
+void PackageEntryTable::init_archived_entries(Array<PackageEntry*>* archived_packages) {
+  for (int i = 0; i < archived_packages->length(); i++) {
+    PackageEntry* archived_entry = archived_packages->at(i);
+    archived_entry->init_as_archived_entry();
+  }
+}
+
+void PackageEntryTable::load_archived_entries(Array<PackageEntry*>* archived_packages) {
+  assert(UseSharedSpaces, "runtime only");
+
+  for (int i = 0; i < archived_packages->length(); i++) {
+    PackageEntry* archived_entry = archived_packages->at(i);
+    archived_entry->load_from_archive();
+
+    unsigned int hash = compute_hash(archived_entry->name());
+    archived_entry->set_hash(hash);
+    add_entry(hash_to_index(hash), archived_entry);
+  }
+}
+
+#endif // INCLUDE_CDS_JAVA_HEAP
+
 PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, ModuleEntry* module) {
   assert(Module_lock->owned_by_self(), "should have the Module_lock");
   PackageEntry* entry = (PackageEntry*)Hashtable<Symbol*, mtModule>::allocate_new_entry(hash, name);
@@ -274,7 +400,6 @@ void PackageEntryTable::verify_javabase_packages(GrowableArray<Symbol*> *pkg_lis
       }
     }
   }
-
 }
 
 // iteration of qualified exports
diff --git a/src/hotspot/share/classfile/packageEntry.hpp b/src/hotspot/share/classfile/packageEntry.hpp
index ee2bfe86a6f..5bfd565dc3e 100644
--- a/src/hotspot/share/classfile/packageEntry.hpp
+++ b/src/hotspot/share/classfile/packageEntry.hpp
@@ -36,6 +36,8 @@
 #include "jfr/support/jfrTraceIdExtension.hpp"
 #endif
 
+template <class T> class Array;
+class MetaspaceClosure;
 
 // A PackageEntry basically represents a Java package.  It contains:
 //   - Symbol* containing the package's name.
@@ -217,6 +219,14 @@ class PackageEntry : public HashtableEntry<Symbol*, mtModule> {
   void print(outputStream* st = tty);
   void verify();
 
+#if INCLUDE_CDS_JAVA_HEAP
+  void iterate_symbols(MetaspaceClosure* closure);
+  PackageEntry* allocate_archived_entry() const;
+  void init_as_archived_entry();
+  static PackageEntry* get_archived_entry(PackageEntry* orig_entry);
+  void load_from_archive();
+#endif
+
   static int max_index_for_defined_in_class_path() {
     return sizeof(int) * BitsPerByte;
   }
@@ -295,6 +305,13 @@ class PackageEntryTable : public Hashtable<Symbol*, mtModule> {
 
   void print(outputStream* st = tty);
   void verify();
+
+#if INCLUDE_CDS_JAVA_HEAP
+  void iterate_symbols(MetaspaceClosure* closure);
+  Array<PackageEntry*>* allocate_archived_entries();
+  void init_archived_entries(Array<PackageEntry*>* archived_packages);
+  void load_archived_entries(Array<PackageEntry*>* archived_packages);
+#endif
 };
 
 #endif // SHARE_CLASSFILE_PACKAGEENTRY_HPP
diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp
index 8742557ffbe..606a84345ef 100644
--- a/src/hotspot/share/classfile/systemDictionary.cpp
+++ b/src/hotspot/share/classfile/systemDictionary.cpp
@@ -565,7 +565,7 @@ void SystemDictionary::double_lock_wait(Handle lockObject, TRAPS) {
   assert_lock_strong(SystemDictionary_lock);
 
   bool calledholdinglock
-      = ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, lockObject);
+      = ObjectSynchronizer::current_thread_holds_lock(THREAD->as_Java_thread(), lockObject);
   assert(calledholdinglock,"must hold lock for notify");
   assert((lockObject() != _system_loader_lock_obj.resolve() &&
          !is_parallelCapable(lockObject)), "unexpected double_lock_wait");
@@ -898,9 +898,7 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
           }
 
           if (JvmtiExport::should_post_class_load()) {
-            Thread *thread = THREAD;
-            assert(thread->is_Java_thread(), "thread->is_Java_thread()");
-            JvmtiExport::post_class_load((JavaThread *) thread, k);
+            JvmtiExport::post_class_load(THREAD->as_Java_thread(), k);
           }
         }
       }
@@ -1084,8 +1082,7 @@ InstanceKlass* SystemDictionary::parse_stream(Symbol* class_name,
 
     // notify jvmti
     if (JvmtiExport::should_post_class_load()) {
-        assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
-        JvmtiExport::post_class_load((JavaThread *) THREAD, k);
+      JvmtiExport::post_class_load(THREAD->as_Java_thread(), k);
     }
     if (class_load_start_event.should_commit()) {
       post_class_load_event(&class_load_start_event, k, loader_data);
@@ -1583,8 +1580,7 @@ InstanceKlass* SystemDictionary::load_instance_class(Symbol* class_name, Handle
     // Use user specified class loader to load class. Call loadClass operation on class_loader.
     ResourceMark rm(THREAD);
 
-    assert(THREAD->is_Java_thread(), "must be a JavaThread");
-    JavaThread* jt = (JavaThread*) THREAD;
+    JavaThread* jt = THREAD->as_Java_thread();
 
     PerfClassTraceTime vmtimer(ClassLoader::perf_app_classload_time(),
                                ClassLoader::perf_app_classload_selftime(),
@@ -1647,15 +1643,15 @@ void SystemDictionary::define_instance_class(InstanceKlass* k, TRAPS) {
   ClassLoaderData* loader_data = k->class_loader_data();
   Handle class_loader_h(THREAD, loader_data->class_loader());
 
- // for bootstrap and other parallel classloaders don't acquire lock,
- // use placeholder token
- // If a parallelCapable class loader calls define_instance_class instead of
- // find_or_define_instance_class to get here, we have a timing
- // hole with systemDictionary updates and check_constraints
- if (!class_loader_h.is_null() && !is_parallelCapable(class_loader_h)) {
-    assert(ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD,
-         compute_loader_lock_object(class_loader_h, THREAD)),
-         "define called without lock");
+  // for bootstrap and other parallel classloaders don't acquire lock,
+  // use placeholder token
+  // If a parallelCapable class loader calls define_instance_class instead of
+  // find_or_define_instance_class to get here, we have a timing
+  // hole with systemDictionary updates and check_constraints
+  if (!class_loader_h.is_null() && !is_parallelCapable(class_loader_h)) {
+    assert(ObjectSynchronizer::current_thread_holds_lock(THREAD->as_Java_thread(),
+           compute_loader_lock_object(class_loader_h, THREAD)),
+           "define called without lock");
   }
 
   // Check class-loading constraints. Throw exception if violation is detected.
@@ -1705,9 +1701,7 @@ void SystemDictionary::define_instance_class(InstanceKlass* k, TRAPS) {
 
   // notify jvmti
   if (JvmtiExport::should_post_class_load()) {
-      assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
-      JvmtiExport::post_class_load((JavaThread *) THREAD, k);
-
+    JvmtiExport::post_class_load(THREAD->as_Java_thread(), k);
   }
   post_class_define_event(k, loader_data);
 }
@@ -1832,7 +1826,7 @@ void SystemDictionary::check_loader_lock_contention(Handle loader_lock, TRAPS) {
 
   assert(!loader_lock.is_null(), "NULL lock object");
 
-  if (ObjectSynchronizer::query_lock_ownership((JavaThread*)THREAD, loader_lock)
+  if (ObjectSynchronizer::query_lock_ownership(THREAD->as_Java_thread(), loader_lock)
       == ObjectSynchronizer::owner_other) {
     // contention will likely happen, so increment the corresponding
     // contention counter.
diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp
index 743ed212ca9..1b481c10385 100644
--- a/src/hotspot/share/classfile/systemDictionary.hpp
+++ b/src/hotspot/share/classfile/systemDictionary.hpp
@@ -187,10 +187,13 @@ class TableStatistics;
   do_klass(ByteArrayInputStream_klass,                  java_io_ByteArrayInputStream                          ) \
   do_klass(URL_klass,                                   java_net_URL                                          ) \
   do_klass(Jar_Manifest_klass,                          java_util_jar_Manifest                                ) \
+  do_klass(jdk_internal_loader_BuiltinClassLoader_klass,jdk_internal_loader_BuiltinClassLoader                ) \
   do_klass(jdk_internal_loader_ClassLoaders_klass,      jdk_internal_loader_ClassLoaders                      ) \
   do_klass(jdk_internal_loader_ClassLoaders_AppClassLoader_klass,      jdk_internal_loader_ClassLoaders_AppClassLoader) \
   do_klass(jdk_internal_loader_ClassLoaders_PlatformClassLoader_klass, jdk_internal_loader_ClassLoaders_PlatformClassLoader) \
   do_klass(CodeSource_klass,                            java_security_CodeSource                              ) \
+  do_klass(ConcurrentHashMap_klass,                     java_util_concurrent_ConcurrentHashMap                ) \
+  do_klass(ArrayList_klass,                             java_util_ArrayList                                   ) \
                                                                                                                 \
   do_klass(StackTraceElement_klass,                     java_lang_StackTraceElement                           ) \
                                                                                                                 \
diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp
index a55d3112241..304afaba3b3 100644
--- a/src/hotspot/share/classfile/systemDictionaryShared.cpp
+++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp
@@ -655,6 +655,22 @@ static RunTimeSharedDictionary _unregistered_dictionary;
 static RunTimeSharedDictionary _dynamic_builtin_dictionary;
 static RunTimeSharedDictionary _dynamic_unregistered_dictionary;
 
+
+Handle SystemDictionaryShared::create_jar_manifest(const char* manifest_chars, size_t size, TRAPS) {
+  typeArrayOop buf = oopFactory::new_byteArray((int)size, CHECK_NH);
+  typeArrayHandle bufhandle(THREAD, buf);
+  ArrayAccess<>::arraycopy_from_native(reinterpret_cast<const jbyte*>(manifest_chars),
+                                         buf, typeArrayOopDesc::element_offset<jbyte>(0), size);
+  Handle bais = JavaCalls::construct_new_instance(SystemDictionary::ByteArrayInputStream_klass(),
+                      vmSymbols::byte_array_void_signature(),
+                      bufhandle, CHECK_NH);
+  // manifest = new Manifest(ByteArrayInputStream)
+  Handle manifest = JavaCalls::construct_new_instance(SystemDictionary::Jar_Manifest_klass(),
+                      vmSymbols::input_stream_void_signature(),
+                      bais, CHECK_NH);
+  return manifest;
+}
+
 oop SystemDictionaryShared::shared_protection_domain(int index) {
   return ((objArrayOop)_shared_protection_domains.resolve())->obj_at(index);
 }
@@ -671,30 +687,17 @@ Handle SystemDictionaryShared::get_shared_jar_manifest(int shared_path_index, TR
   Handle manifest ;
   if (shared_jar_manifest(shared_path_index) == NULL) {
     SharedClassPathEntry* ent = FileMapInfo::shared_path(shared_path_index);
-    long size = ent->manifest_size();
-    if (size <= 0) {
+    size_t size = (size_t)ent->manifest_size();
+    if (size == 0) {
       return Handle();
     }
 
     // ByteArrayInputStream bais = new ByteArrayInputStream(buf);
     const char* src = ent->manifest();
     assert(src != NULL, "No Manifest data");
-    typeArrayOop buf = oopFactory::new_byteArray(size, CHECK_NH);
-    typeArrayHandle bufhandle(THREAD, buf);
-    ArrayAccess<>::arraycopy_from_native(reinterpret_cast<const jbyte*>(src),
-                                         buf, typeArrayOopDesc::element_offset<jbyte>(0), size);
-
-    Handle bais = JavaCalls::construct_new_instance(SystemDictionary::ByteArrayInputStream_klass(),
-                      vmSymbols::byte_array_void_signature(),
-                      bufhandle, CHECK_NH);
-
-    // manifest = new Manifest(bais)
-    manifest = JavaCalls::construct_new_instance(SystemDictionary::Jar_Manifest_klass(),
-                      vmSymbols::input_stream_void_signature(),
-                      bais, CHECK_NH);
+    manifest = create_jar_manifest(src, size, THREAD);
     atomic_set_shared_jar_manifest(shared_path_index, manifest());
   }
-
   manifest = Handle(THREAD, shared_jar_manifest(shared_path_index));
   assert(manifest.not_null(), "sanity");
   return manifest;
@@ -1616,8 +1619,7 @@ InstanceKlass* SystemDictionaryShared::prepare_shared_lambda_proxy_class(Instanc
   loaded_lambda->link_class(CHECK_NULL);
   // notify jvmti
   if (JvmtiExport::should_post_class_load()) {
-    assert(THREAD->is_Java_thread(), "thread->is_Java_thread()");
-    JvmtiExport::post_class_load((JavaThread *) THREAD, loaded_lambda);
+    JvmtiExport::post_class_load(THREAD->as_Java_thread(), loaded_lambda);
   }
   if (class_load_start_event.should_commit()) {
     SystemDictionary::post_class_load_event(&class_load_start_event, loaded_lambda, ClassLoaderData::class_loader_data(class_loader()));
diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp
index e7b6974a007..fe55b7a5cd7 100644
--- a/src/hotspot/share/classfile/systemDictionaryShared.hpp
+++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp
@@ -320,6 +320,7 @@ class SystemDictionaryShared: public SystemDictionary {
   static void print_table_statistics(outputStream* st) NOT_CDS_RETURN;
   static bool empty_dumptime_table() NOT_CDS_RETURN_(true);
   static void start_dumping() NOT_CDS_RETURN;
+  static Handle create_jar_manifest(const char* man, size_t size, TRAPS) NOT_CDS_RETURN_(Handle());
 
   DEBUG_ONLY(static bool no_class_loading_should_happen() {return _no_class_loading_should_happen;})
 
diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp
index 9edd1daa056..25511485a6c 100644
--- a/src/hotspot/share/classfile/verifier.cpp
+++ b/src/hotspot/share/classfile/verifier.cpp
@@ -173,7 +173,7 @@ bool Verifier::verify(InstanceKlass* klass, bool should_verify_class, TRAPS) {
 
   // Timer includes any side effects of class verification (resolution,
   // etc), but not recursive calls to Verifier::verify().
-  JavaThread* jt = (JavaThread*)THREAD;
+  JavaThread* jt = THREAD->as_Java_thread();
   PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
                            ClassLoader::perf_class_verify_selftime(),
                            ClassLoader::perf_classes_verified(),
@@ -296,7 +296,7 @@ bool Verifier::is_eligible_for_verification(InstanceKlass* klass, bool should_ve
 
 Symbol* Verifier::inference_verify(
     InstanceKlass* klass, char* message, size_t message_len, TRAPS) {
-  JavaThread* thread = (JavaThread*)THREAD;
+  JavaThread* thread = THREAD->as_Java_thread();
 
   verify_byte_codes_fn_t verify_func = verify_byte_codes_fn();
 
diff --git a/src/hotspot/share/classfile/vmIntrinsics.cpp b/src/hotspot/share/classfile/vmIntrinsics.cpp
new file mode 100644
index 00000000000..70932aede66
--- /dev/null
+++ b/src/hotspot/share/classfile/vmIntrinsics.cpp
@@ -0,0 +1,852 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 "classfile/vmIntrinsics.hpp"
+#include "classfile/vmSymbols.hpp"
+#include "compiler/compilerDirectives.hpp"
+#include "utilities/xmlstream.hpp"
+
+// These are flag-matching functions:
+inline bool match_F_R(jshort flags) {
+  const int req = 0;
+  const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
+  return (flags & (req | neg)) == req;
+}
+
+inline bool match_F_Y(jshort flags) {
+  const int req = JVM_ACC_SYNCHRONIZED;
+  const int neg = JVM_ACC_STATIC;
+  return (flags & (req | neg)) == req;
+}
+
+inline bool match_F_RN(jshort flags) {
+  const int req = JVM_ACC_NATIVE;
+  const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
+  return (flags & (req | neg)) == req;
+}
+
+inline bool match_F_S(jshort flags) {
+  const int req = JVM_ACC_STATIC;
+  const int neg = JVM_ACC_SYNCHRONIZED;
+  return (flags & (req | neg)) == req;
+}
+
+inline bool match_F_SN(jshort flags) {
+  const int req = JVM_ACC_STATIC | JVM_ACC_NATIVE;
+  const int neg = JVM_ACC_SYNCHRONIZED;
+  return (flags & (req | neg)) == req;
+}
+
+inline bool match_F_RNY(jshort flags) {
+  const int req = JVM_ACC_NATIVE | JVM_ACC_SYNCHRONIZED;
+  const int neg = JVM_ACC_STATIC;
+  return (flags & (req | neg)) == req;
+}
+
+static vmIntrinsics::ID wrapper_intrinsic(BasicType type, bool unboxing) {
+#define TYPE2(type, unboxing) ((int)(type)*2 + ((unboxing) ? 1 : 0))
+  switch (TYPE2(type, unboxing)) {
+#define BASIC_TYPE_CASE(type, box, unbox) \
+    case TYPE2(type, false):  return vmIntrinsics::box; \
+    case TYPE2(type, true):   return vmIntrinsics::unbox
+    BASIC_TYPE_CASE(T_BOOLEAN, _Boolean_valueOf,   _booleanValue);
+    BASIC_TYPE_CASE(T_BYTE,    _Byte_valueOf,      _byteValue);
+    BASIC_TYPE_CASE(T_CHAR,    _Character_valueOf, _charValue);
+    BASIC_TYPE_CASE(T_SHORT,   _Short_valueOf,     _shortValue);
+    BASIC_TYPE_CASE(T_INT,     _Integer_valueOf,   _intValue);
+    BASIC_TYPE_CASE(T_LONG,    _Long_valueOf,      _longValue);
+    BASIC_TYPE_CASE(T_FLOAT,   _Float_valueOf,     _floatValue);
+    BASIC_TYPE_CASE(T_DOUBLE,  _Double_valueOf,    _doubleValue);
+#undef BASIC_TYPE_CASE
+  }
+#undef TYPE2
+  return vmIntrinsics::_none;
+}
+
+vmIntrinsics::ID vmIntrinsics::for_boxing(BasicType type) {
+  return wrapper_intrinsic(type, false);
+}
+vmIntrinsics::ID vmIntrinsics::for_unboxing(BasicType type) {
+  return wrapper_intrinsic(type, true);
+}
+
+vmIntrinsics::ID vmIntrinsics::for_raw_conversion(BasicType src, BasicType dest) {
+#define SRC_DEST(s,d) (((int)(s) << 4) + (int)(d))
+  switch (SRC_DEST(src, dest)) {
+  case SRC_DEST(T_INT, T_FLOAT):   return vmIntrinsics::_intBitsToFloat;
+  case SRC_DEST(T_FLOAT, T_INT):   return vmIntrinsics::_floatToRawIntBits;
+
+  case SRC_DEST(T_LONG, T_DOUBLE): return vmIntrinsics::_longBitsToDouble;
+  case SRC_DEST(T_DOUBLE, T_LONG): return vmIntrinsics::_doubleToRawLongBits;
+  }
+#undef SRC_DEST
+
+  return vmIntrinsics::_none;
+}
+
+bool vmIntrinsics::preserves_state(vmIntrinsics::ID id) {
+  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
+  switch(id) {
+#ifdef JFR_HAVE_INTRINSICS
+  case vmIntrinsics::_counterTime:
+#endif
+  case vmIntrinsics::_currentTimeMillis:
+  case vmIntrinsics::_nanoTime:
+  case vmIntrinsics::_floatToRawIntBits:
+  case vmIntrinsics::_intBitsToFloat:
+  case vmIntrinsics::_doubleToRawLongBits:
+  case vmIntrinsics::_longBitsToDouble:
+  case vmIntrinsics::_getClass:
+  case vmIntrinsics::_isInstance:
+  case vmIntrinsics::_currentThread:
+  case vmIntrinsics::_dabs:
+  case vmIntrinsics::_fabs:
+  case vmIntrinsics::_iabs:
+  case vmIntrinsics::_labs:
+  case vmIntrinsics::_dsqrt:
+  case vmIntrinsics::_dsin:
+  case vmIntrinsics::_dcos:
+  case vmIntrinsics::_dtan:
+  case vmIntrinsics::_dlog:
+  case vmIntrinsics::_dlog10:
+  case vmIntrinsics::_dexp:
+  case vmIntrinsics::_dpow:
+  case vmIntrinsics::_checkIndex:
+  case vmIntrinsics::_Reference_get:
+  case vmIntrinsics::_updateCRC32:
+  case vmIntrinsics::_updateBytesCRC32:
+  case vmIntrinsics::_updateByteBufferCRC32:
+  case vmIntrinsics::_vectorizedMismatch:
+  case vmIntrinsics::_fmaD:
+  case vmIntrinsics::_fmaF:
+  case vmIntrinsics::_isDigit:
+  case vmIntrinsics::_isLowerCase:
+  case vmIntrinsics::_isUpperCase:
+  case vmIntrinsics::_isWhitespace:
+    return true;
+  default:
+    return false;
+  }
+}
+
+bool vmIntrinsics::can_trap(vmIntrinsics::ID id) {
+  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
+  switch(id) {
+#ifdef JFR_HAVE_INTRINSICS
+  case vmIntrinsics::_counterTime:
+  case vmIntrinsics::_getClassId:
+#endif
+  case vmIntrinsics::_currentTimeMillis:
+  case vmIntrinsics::_nanoTime:
+  case vmIntrinsics::_floatToRawIntBits:
+  case vmIntrinsics::_intBitsToFloat:
+  case vmIntrinsics::_doubleToRawLongBits:
+  case vmIntrinsics::_longBitsToDouble:
+  case vmIntrinsics::_currentThread:
+  case vmIntrinsics::_dabs:
+  case vmIntrinsics::_fabs:
+  case vmIntrinsics::_iabs:
+  case vmIntrinsics::_labs:
+  case vmIntrinsics::_dsqrt:
+  case vmIntrinsics::_dsin:
+  case vmIntrinsics::_dcos:
+  case vmIntrinsics::_dtan:
+  case vmIntrinsics::_dlog:
+  case vmIntrinsics::_dlog10:
+  case vmIntrinsics::_dexp:
+  case vmIntrinsics::_dpow:
+  case vmIntrinsics::_updateCRC32:
+  case vmIntrinsics::_updateBytesCRC32:
+  case vmIntrinsics::_updateByteBufferCRC32:
+  case vmIntrinsics::_vectorizedMismatch:
+  case vmIntrinsics::_fmaD:
+  case vmIntrinsics::_fmaF:
+    return false;
+  default:
+    return true;
+  }
+}
+
+// Some intrinsics produce different results if they are not pinned
+bool vmIntrinsics::should_be_pinned(vmIntrinsics::ID id) {
+  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
+  switch(id) {
+#ifdef JFR_HAVE_INTRINSICS
+  case vmIntrinsics::_counterTime:
+#endif
+  case vmIntrinsics::_currentTimeMillis:
+  case vmIntrinsics::_nanoTime:
+    return true;
+  default:
+    return false;
+  }
+}
+
+bool vmIntrinsics::does_virtual_dispatch(vmIntrinsics::ID id) {
+  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
+  switch(id) {
+  case vmIntrinsics::_hashCode:
+  case vmIntrinsics::_clone:
+    return true;
+    break;
+  default:
+    return false;
+  }
+}
+
+int vmIntrinsics::predicates_needed(vmIntrinsics::ID id) {
+  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
+  switch (id) {
+  case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
+  case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
+  case vmIntrinsics::_electronicCodeBook_encryptAESCrypt:
+  case vmIntrinsics::_electronicCodeBook_decryptAESCrypt:
+  case vmIntrinsics::_counterMode_AESCrypt:
+    return 1;
+  case vmIntrinsics::_digestBase_implCompressMB:
+    return 4;
+  default:
+    return 0;
+  }
+}
+
+bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) {
+  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
+
+  // -XX:-InlineNatives disables nearly all intrinsics except the ones listed in
+  // the following switch statement.
+  if (!InlineNatives) {
+    switch (id) {
+    case vmIntrinsics::_indexOfL:
+    case vmIntrinsics::_indexOfU:
+    case vmIntrinsics::_indexOfUL:
+    case vmIntrinsics::_indexOfIL:
+    case vmIntrinsics::_indexOfIU:
+    case vmIntrinsics::_indexOfIUL:
+    case vmIntrinsics::_indexOfU_char:
+    case vmIntrinsics::_compareToL:
+    case vmIntrinsics::_compareToU:
+    case vmIntrinsics::_compareToLU:
+    case vmIntrinsics::_compareToUL:
+    case vmIntrinsics::_equalsL:
+    case vmIntrinsics::_equalsU:
+    case vmIntrinsics::_equalsC:
+    case vmIntrinsics::_getCharStringU:
+    case vmIntrinsics::_putCharStringU:
+    case vmIntrinsics::_compressStringC:
+    case vmIntrinsics::_compressStringB:
+    case vmIntrinsics::_inflateStringC:
+    case vmIntrinsics::_inflateStringB:
+    case vmIntrinsics::_getAndAddInt:
+    case vmIntrinsics::_getAndAddLong:
+    case vmIntrinsics::_getAndSetInt:
+    case vmIntrinsics::_getAndSetLong:
+    case vmIntrinsics::_getAndSetReference:
+    case vmIntrinsics::_loadFence:
+    case vmIntrinsics::_storeFence:
+    case vmIntrinsics::_fullFence:
+    case vmIntrinsics::_hasNegatives:
+    case vmIntrinsics::_Reference_get:
+      break;
+    default:
+      return true;
+    }
+  }
+
+  switch (id) {
+  case vmIntrinsics::_isInstance:
+  case vmIntrinsics::_isAssignableFrom:
+  case vmIntrinsics::_getModifiers:
+  case vmIntrinsics::_isInterface:
+  case vmIntrinsics::_isArray:
+  case vmIntrinsics::_isPrimitive:
+  case vmIntrinsics::_isHidden:
+  case vmIntrinsics::_getSuperclass:
+  case vmIntrinsics::_Class_cast:
+  case vmIntrinsics::_getLength:
+  case vmIntrinsics::_newArray:
+  case vmIntrinsics::_getClass:
+    if (!InlineClassNatives) return true;
+    break;
+  case vmIntrinsics::_currentThread:
+    if (!InlineThreadNatives) return true;
+    break;
+  case vmIntrinsics::_floatToRawIntBits:
+  case vmIntrinsics::_intBitsToFloat:
+  case vmIntrinsics::_doubleToRawLongBits:
+  case vmIntrinsics::_longBitsToDouble:
+  case vmIntrinsics::_ceil:
+  case vmIntrinsics::_floor:
+  case vmIntrinsics::_rint:
+  case vmIntrinsics::_dabs:
+  case vmIntrinsics::_fabs:
+  case vmIntrinsics::_iabs:
+  case vmIntrinsics::_labs:
+  case vmIntrinsics::_dsqrt:
+  case vmIntrinsics::_dsin:
+  case vmIntrinsics::_dcos:
+  case vmIntrinsics::_dtan:
+  case vmIntrinsics::_dlog:
+  case vmIntrinsics::_dexp:
+  case vmIntrinsics::_dpow:
+  case vmIntrinsics::_dlog10:
+  case vmIntrinsics::_datan2:
+  case vmIntrinsics::_min:
+  case vmIntrinsics::_max:
+  case vmIntrinsics::_floatToIntBits:
+  case vmIntrinsics::_doubleToLongBits:
+  case vmIntrinsics::_maxF:
+  case vmIntrinsics::_minF:
+  case vmIntrinsics::_maxD:
+  case vmIntrinsics::_minD:
+    if (!InlineMathNatives) return true;
+    break;
+  case vmIntrinsics::_fmaD:
+  case vmIntrinsics::_fmaF:
+    if (!InlineMathNatives || !UseFMA) return true;
+    break;
+  case vmIntrinsics::_arraycopy:
+    if (!InlineArrayCopy) return true;
+    break;
+  case vmIntrinsics::_updateCRC32:
+  case vmIntrinsics::_updateBytesCRC32:
+  case vmIntrinsics::_updateByteBufferCRC32:
+    if (!UseCRC32Intrinsics) return true;
+    break;
+  case vmIntrinsics::_getReference:
+  case vmIntrinsics::_getBoolean:
+  case vmIntrinsics::_getByte:
+  case vmIntrinsics::_getShort:
+  case vmIntrinsics::_getChar:
+  case vmIntrinsics::_getInt:
+  case vmIntrinsics::_getLong:
+  case vmIntrinsics::_getFloat:
+  case vmIntrinsics::_getDouble:
+  case vmIntrinsics::_putReference:
+  case vmIntrinsics::_putBoolean:
+  case vmIntrinsics::_putByte:
+  case vmIntrinsics::_putShort:
+  case vmIntrinsics::_putChar:
+  case vmIntrinsics::_putInt:
+  case vmIntrinsics::_putLong:
+  case vmIntrinsics::_putFloat:
+  case vmIntrinsics::_putDouble:
+  case vmIntrinsics::_getReferenceVolatile:
+  case vmIntrinsics::_getBooleanVolatile:
+  case vmIntrinsics::_getByteVolatile:
+  case vmIntrinsics::_getShortVolatile:
+  case vmIntrinsics::_getCharVolatile:
+  case vmIntrinsics::_getIntVolatile:
+  case vmIntrinsics::_getLongVolatile:
+  case vmIntrinsics::_getFloatVolatile:
+  case vmIntrinsics::_getDoubleVolatile:
+  case vmIntrinsics::_putReferenceVolatile:
+  case vmIntrinsics::_putBooleanVolatile:
+  case vmIntrinsics::_putByteVolatile:
+  case vmIntrinsics::_putShortVolatile:
+  case vmIntrinsics::_putCharVolatile:
+  case vmIntrinsics::_putIntVolatile:
+  case vmIntrinsics::_putLongVolatile:
+  case vmIntrinsics::_putFloatVolatile:
+  case vmIntrinsics::_putDoubleVolatile:
+  case vmIntrinsics::_getReferenceAcquire:
+  case vmIntrinsics::_getBooleanAcquire:
+  case vmIntrinsics::_getByteAcquire:
+  case vmIntrinsics::_getShortAcquire:
+  case vmIntrinsics::_getCharAcquire:
+  case vmIntrinsics::_getIntAcquire:
+  case vmIntrinsics::_getLongAcquire:
+  case vmIntrinsics::_getFloatAcquire:
+  case vmIntrinsics::_getDoubleAcquire:
+  case vmIntrinsics::_putReferenceRelease:
+  case vmIntrinsics::_putBooleanRelease:
+  case vmIntrinsics::_putByteRelease:
+  case vmIntrinsics::_putShortRelease:
+  case vmIntrinsics::_putCharRelease:
+  case vmIntrinsics::_putIntRelease:
+  case vmIntrinsics::_putLongRelease:
+  case vmIntrinsics::_putFloatRelease:
+  case vmIntrinsics::_putDoubleRelease:
+  case vmIntrinsics::_getReferenceOpaque:
+  case vmIntrinsics::_getBooleanOpaque:
+  case vmIntrinsics::_getByteOpaque:
+  case vmIntrinsics::_getShortOpaque:
+  case vmIntrinsics::_getCharOpaque:
+  case vmIntrinsics::_getIntOpaque:
+  case vmIntrinsics::_getLongOpaque:
+  case vmIntrinsics::_getFloatOpaque:
+  case vmIntrinsics::_getDoubleOpaque:
+  case vmIntrinsics::_putReferenceOpaque:
+  case vmIntrinsics::_putBooleanOpaque:
+  case vmIntrinsics::_putByteOpaque:
+  case vmIntrinsics::_putShortOpaque:
+  case vmIntrinsics::_putCharOpaque:
+  case vmIntrinsics::_putIntOpaque:
+  case vmIntrinsics::_putLongOpaque:
+  case vmIntrinsics::_putFloatOpaque:
+  case vmIntrinsics::_putDoubleOpaque:
+  case vmIntrinsics::_getAndAddInt:
+  case vmIntrinsics::_getAndAddLong:
+  case vmIntrinsics::_getAndSetInt:
+  case vmIntrinsics::_getAndSetLong:
+  case vmIntrinsics::_getAndSetReference:
+  case vmIntrinsics::_loadFence:
+  case vmIntrinsics::_storeFence:
+  case vmIntrinsics::_fullFence:
+  case vmIntrinsics::_compareAndSetLong:
+  case vmIntrinsics::_weakCompareAndSetLong:
+  case vmIntrinsics::_weakCompareAndSetLongPlain:
+  case vmIntrinsics::_weakCompareAndSetLongAcquire:
+  case vmIntrinsics::_weakCompareAndSetLongRelease:
+  case vmIntrinsics::_compareAndSetInt:
+  case vmIntrinsics::_weakCompareAndSetInt:
+  case vmIntrinsics::_weakCompareAndSetIntPlain:
+  case vmIntrinsics::_weakCompareAndSetIntAcquire:
+  case vmIntrinsics::_weakCompareAndSetIntRelease:
+  case vmIntrinsics::_compareAndSetReference:
+  case vmIntrinsics::_weakCompareAndSetReference:
+  case vmIntrinsics::_weakCompareAndSetReferencePlain:
+  case vmIntrinsics::_weakCompareAndSetReferenceAcquire:
+  case vmIntrinsics::_weakCompareAndSetReferenceRelease:
+  case vmIntrinsics::_compareAndExchangeInt:
+  case vmIntrinsics::_compareAndExchangeIntAcquire:
+  case vmIntrinsics::_compareAndExchangeIntRelease:
+  case vmIntrinsics::_compareAndExchangeLong:
+  case vmIntrinsics::_compareAndExchangeLongAcquire:
+  case vmIntrinsics::_compareAndExchangeLongRelease:
+  case vmIntrinsics::_compareAndExchangeReference:
+  case vmIntrinsics::_compareAndExchangeReferenceAcquire:
+  case vmIntrinsics::_compareAndExchangeReferenceRelease:
+    if (!InlineUnsafeOps) return true;
+    break;
+  case vmIntrinsics::_getShortUnaligned:
+  case vmIntrinsics::_getCharUnaligned:
+  case vmIntrinsics::_getIntUnaligned:
+  case vmIntrinsics::_getLongUnaligned:
+  case vmIntrinsics::_putShortUnaligned:
+  case vmIntrinsics::_putCharUnaligned:
+  case vmIntrinsics::_putIntUnaligned:
+  case vmIntrinsics::_putLongUnaligned:
+  case vmIntrinsics::_allocateInstance:
+    if (!InlineUnsafeOps || !UseUnalignedAccesses) return true;
+    break;
+  case vmIntrinsics::_hashCode:
+    if (!InlineObjectHash) return true;
+    break;
+  case vmIntrinsics::_aescrypt_encryptBlock:
+  case vmIntrinsics::_aescrypt_decryptBlock:
+    if (!UseAESIntrinsics) return true;
+    break;
+  case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
+  case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
+    if (!UseAESIntrinsics) return true;
+    break;
+  case vmIntrinsics::_electronicCodeBook_encryptAESCrypt:
+  case vmIntrinsics::_electronicCodeBook_decryptAESCrypt:
+    if (!UseAESIntrinsics) return true;
+    break;
+  case vmIntrinsics::_counterMode_AESCrypt:
+    if (!UseAESCTRIntrinsics) return true;
+    break;
+  case vmIntrinsics::_md5_implCompress:
+    if (!UseMD5Intrinsics) return true;
+    break;
+  case vmIntrinsics::_sha_implCompress:
+    if (!UseSHA1Intrinsics) return true;
+    break;
+  case vmIntrinsics::_sha2_implCompress:
+    if (!UseSHA256Intrinsics) return true;
+    break;
+  case vmIntrinsics::_sha5_implCompress:
+    if (!UseSHA512Intrinsics) return true;
+    break;
+  case vmIntrinsics::_digestBase_implCompressMB:
+    if (!(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return true;
+    break;
+  case vmIntrinsics::_ghash_processBlocks:
+    if (!UseGHASHIntrinsics) return true;
+    break;
+  case vmIntrinsics::_base64_encodeBlock:
+    if (!UseBASE64Intrinsics) return true;
+    break;
+  case vmIntrinsics::_updateBytesCRC32C:
+  case vmIntrinsics::_updateDirectByteBufferCRC32C:
+    if (!UseCRC32CIntrinsics) return true;
+    break;
+  case vmIntrinsics::_vectorizedMismatch:
+    if (!UseVectorizedMismatchIntrinsic) return true;
+    break;
+  case vmIntrinsics::_updateBytesAdler32:
+  case vmIntrinsics::_updateByteBufferAdler32:
+    if (!UseAdler32Intrinsics) return true;
+    break;
+  case vmIntrinsics::_copyMemory:
+    if (!InlineArrayCopy || !InlineUnsafeOps) return true;
+    break;
+#ifdef COMPILER1
+  case vmIntrinsics::_checkIndex:
+    if (!InlineNIOCheckIndex) return true;
+    break;
+#endif // COMPILER1
+#ifdef COMPILER2
+  case vmIntrinsics::_clone:
+  case vmIntrinsics::_copyOf:
+  case vmIntrinsics::_copyOfRange:
+    // These intrinsics use both the objectcopy and the arraycopy
+    // intrinsic mechanism.
+    if (!InlineObjectCopy || !InlineArrayCopy) return true;
+    break;
+  case vmIntrinsics::_compareToL:
+  case vmIntrinsics::_compareToU:
+  case vmIntrinsics::_compareToLU:
+  case vmIntrinsics::_compareToUL:
+    if (!SpecialStringCompareTo) return true;
+    break;
+  case vmIntrinsics::_indexOfL:
+  case vmIntrinsics::_indexOfU:
+  case vmIntrinsics::_indexOfUL:
+  case vmIntrinsics::_indexOfIL:
+  case vmIntrinsics::_indexOfIU:
+  case vmIntrinsics::_indexOfIUL:
+  case vmIntrinsics::_indexOfU_char:
+    if (!SpecialStringIndexOf) return true;
+    break;
+  case vmIntrinsics::_equalsL:
+  case vmIntrinsics::_equalsU:
+    if (!SpecialStringEquals) return true;
+    break;
+  case vmIntrinsics::_equalsB:
+  case vmIntrinsics::_equalsC:
+    if (!SpecialArraysEquals) return true;
+    break;
+  case vmIntrinsics::_encodeISOArray:
+  case vmIntrinsics::_encodeByteISOArray:
+    if (!SpecialEncodeISOArray) return true;
+    break;
+  case vmIntrinsics::_getCallerClass:
+    if (!InlineReflectionGetCallerClass) return true;
+    break;
+  case vmIntrinsics::_multiplyToLen:
+    if (!UseMultiplyToLenIntrinsic) return true;
+    break;
+  case vmIntrinsics::_squareToLen:
+    if (!UseSquareToLenIntrinsic) return true;
+    break;
+  case vmIntrinsics::_mulAdd:
+    if (!UseMulAddIntrinsic) return true;
+    break;
+  case vmIntrinsics::_montgomeryMultiply:
+    if (!UseMontgomeryMultiplyIntrinsic) return true;
+    break;
+  case vmIntrinsics::_montgomerySquare:
+    if (!UseMontgomerySquareIntrinsic) return true;
+    break;
+  case vmIntrinsics::_bigIntegerRightShiftWorker:
+  case vmIntrinsics::_bigIntegerLeftShiftWorker:
+    break;
+  case vmIntrinsics::_addExactI:
+  case vmIntrinsics::_addExactL:
+  case vmIntrinsics::_decrementExactI:
+  case vmIntrinsics::_decrementExactL:
+  case vmIntrinsics::_incrementExactI:
+  case vmIntrinsics::_incrementExactL:
+  case vmIntrinsics::_multiplyExactI:
+  case vmIntrinsics::_multiplyExactL:
+  case vmIntrinsics::_negateExactI:
+  case vmIntrinsics::_negateExactL:
+  case vmIntrinsics::_subtractExactI:
+  case vmIntrinsics::_subtractExactL:
+    if (!UseMathExactIntrinsics || !InlineMathNatives) return true;
+    break;
+  case vmIntrinsics::_isDigit:
+  case vmIntrinsics::_isLowerCase:
+  case vmIntrinsics::_isUpperCase:
+  case vmIntrinsics::_isWhitespace:
+    if (!UseCharacterCompareIntrinsics) return true;
+    break;
+  case vmIntrinsics::_dcopySign:
+  case vmIntrinsics::_fcopySign:
+    if (!InlineMathNatives || !UseCopySignIntrinsic) return true;
+    break;
+  case vmIntrinsics::_dsignum:
+  case vmIntrinsics::_fsignum:
+    if (!InlineMathNatives || !UseSignumIntrinsic) return true;
+    break;
+#endif // COMPILER2
+  default:
+    return false;
+  }
+
+  return false;
+}
+
+#define VM_INTRINSIC_INITIALIZE(id, klass, name, sig, flags) #id "\0"
+static const char* vm_intrinsic_name_bodies =
+  VM_INTRINSICS_DO(VM_INTRINSIC_INITIALIZE,
+                   VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
+
+static const char* vm_intrinsic_name_table[vmIntrinsics::ID_LIMIT];
+static TriBoolArray<vmIntrinsics::ID_LIMIT, int> vm_intrinsic_control_words;
+
+static void init_vm_intrinsic_name_table() {
+  const char** nt = &vm_intrinsic_name_table[0];
+  char* string = (char*) &vm_intrinsic_name_bodies[0];
+  for (int index = vmIntrinsics::FIRST_ID; index < vmIntrinsics::ID_LIMIT; index++) {
+    nt[index] = string;
+    string += strlen(string); // skip string body
+    string += 1;              // skip trailing null
+  }
+  assert(!strcmp(nt[vmIntrinsics::_hashCode], "_hashCode"), "lined up");
+  nt[vmIntrinsics::_none] = "_none";
+}
+
+const char* vmIntrinsics::name_at(vmIntrinsics::ID id) {
+  const char** nt = &vm_intrinsic_name_table[0];
+  if (nt[_none] == NULL) {
+    init_vm_intrinsic_name_table();
+  }
+
+  if ((uint)id < (uint)ID_LIMIT)
+    return vm_intrinsic_name_table[(uint)id];
+  else
+    return "(unknown intrinsic)";
+}
+
+vmIntrinsics::ID vmIntrinsics::find_id(const char* name) {
+  const char** nt = &vm_intrinsic_name_table[0];
+  if (nt[_none] == NULL) {
+    init_vm_intrinsic_name_table();
+  }
+
+  for (int index = FIRST_ID; index < ID_LIMIT; ++index) {
+    if (0 == strcmp(name, nt[index])) {
+      return ID_from(index);
+    }
+  }
+
+  return _none;
+}
+
+bool vmIntrinsics::is_disabled_by_flags(const methodHandle& method) {
+  vmIntrinsics::ID id = method->intrinsic_id();
+  return is_disabled_by_flags(id);
+}
+
+bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) {
+  assert(id > _none && id < ID_LIMIT, "must be a VM intrinsic");
+
+  // not initialized yet, process Control/DisableIntrinsic
+  if (vm_intrinsic_control_words[_none].is_default()) {
+    for (ControlIntrinsicIter iter(ControlIntrinsic); *iter != NULL; ++iter) {
+      vmIntrinsics::ID id = vmIntrinsics::find_id(*iter);
+
+      if (id != vmIntrinsics::_none) {
+        vm_intrinsic_control_words[id] = iter.is_enabled() && !disabled_by_jvm_flags(id);
+      }
+    }
+
+    // Order matters, DisableIntrinsic can overwrite ControlIntrinsic
+    for (ControlIntrinsicIter iter(DisableIntrinsic, true/*disable_all*/); *iter != NULL; ++iter) {
+      vmIntrinsics::ID id = vmIntrinsics::find_id(*iter);
+
+      if (id != vmIntrinsics::_none) {
+        vm_intrinsic_control_words[id] = false;
+      }
+    }
+
+    vm_intrinsic_control_words[_none] = true;
+  }
+
+  TriBool b = vm_intrinsic_control_words[id];
+  if (b.is_default()) {
+    // unknown yet, query and cache it
+    b = vm_intrinsic_control_words[id] = !disabled_by_jvm_flags(id);
+  }
+
+  return !b;
+}
+
+// These are for forming case labels:
+#define ID3(x, y, z) (( jlong)(z) +                                  \
+                      ((jlong)(y) <<    vmSymbols::log2_SID_LIMIT) + \
+                      ((jlong)(x) << (2*vmSymbols::log2_SID_LIMIT))  )
+#define SID_ENUM(n) vmSymbols::VM_SYMBOL_ENUM_NAME(n)
+
+vmIntrinsics::ID vmIntrinsics::find_id_impl(vmSymbols::SID holder,
+                                            vmSymbols::SID name,
+                                            vmSymbols::SID sig,
+                                            jshort flags) {
+  assert((int)vmSymbols::SID_LIMIT <= (1<<vmSymbols::log2_SID_LIMIT), "must fit");
+
+  // Let the C compiler build the decision tree.
+
+#define VM_INTRINSIC_CASE(id, klass, name, sig, fcode) \
+  case ID3(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig)): \
+    if (!match_##fcode(flags))  break; \
+    return id;
+
+  switch (ID3(holder, name, sig)) {
+    VM_INTRINSICS_DO(VM_INTRINSIC_CASE,
+                     VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
+  }
+  return vmIntrinsics::_none;
+
+#undef VM_INTRINSIC_CASE
+}
+
+
+const char* vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID id, char* buf, int buflen) {
+  const char* str = name_at(id);
+#ifndef PRODUCT
+  const char* kname = vmSymbols::name_for(class_for(id));
+  const char* mname = vmSymbols::name_for(name_for(id));
+  const char* sname = vmSymbols::name_for(signature_for(id));
+  const char* fname = "";
+  switch (flags_for(id)) {
+  case F_Y:  fname = "synchronized ";  break;
+  case F_RN: fname = "native ";        break;
+  case F_SN: fname = "native static "; break;
+  case F_S:  fname = "static ";        break;
+  case F_RNY:fname = "native synchronized "; break;
+  default:   break;
+  }
+  const char* kptr = strrchr(kname, JVM_SIGNATURE_SLASH);
+  if (kptr != NULL)  kname = kptr + 1;
+  int len = jio_snprintf(buf, buflen, "%s: %s%s.%s%s",
+                         str, fname, kname, mname, sname);
+  if (len < buflen)
+    str = buf;
+#endif //PRODUCT
+  return str;
+}
+
+
+// These are to get information about intrinsics.
+
+#define ID4(x, y, z, f) ((ID3(x, y, z) << vmIntrinsics::log2_FLAG_LIMIT) | (jlong) (f))
+
+static const jlong intrinsic_info_array[vmIntrinsics::ID_LIMIT+1] = {
+#define VM_INTRINSIC_INFO(ignore_id, klass, name, sig, fcode) \
+  ID4(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig), vmIntrinsics::fcode),
+
+  0, VM_INTRINSICS_DO(VM_INTRINSIC_INFO,
+                     VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
+    0
+#undef VM_INTRINSIC_INFO
+};
+
+inline jlong intrinsic_info(vmIntrinsics::ID id) {
+  return intrinsic_info_array[vmIntrinsics::ID_from((int)id)];
+}
+
+vmSymbols::SID vmIntrinsics::class_for(vmIntrinsics::ID id) {
+  jlong info = intrinsic_info(id);
+  int shift = 2*vmSymbols::log2_SID_LIMIT + log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
+  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1021, "");
+  return vmSymbols::SID( (info >> shift) & mask );
+}
+
+vmSymbols::SID vmIntrinsics::name_for(vmIntrinsics::ID id) {
+  jlong info = intrinsic_info(id);
+  int shift = vmSymbols::log2_SID_LIMIT + log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
+  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1022, "");
+  return vmSymbols::SID( (info >> shift) & mask );
+}
+
+vmSymbols::SID vmIntrinsics::signature_for(vmIntrinsics::ID id) {
+  jlong info = intrinsic_info(id);
+  int shift = log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
+  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1023, "");
+  return vmSymbols::SID( (info >> shift) & mask );
+}
+
+vmIntrinsics::Flags vmIntrinsics::flags_for(vmIntrinsics::ID id) {
+  jlong info = intrinsic_info(id);
+  int shift = 0, mask = right_n_bits(log2_FLAG_LIMIT);
+  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 15, "");
+  return Flags( (info >> shift) & mask );
+}
+
+
+#ifndef PRODUCT
+// verify_method performs an extra check on a matched intrinsic method
+
+static bool match_method(Method* m, Symbol* n, Symbol* s) {
+  return (m->name() == n &&
+          m->signature() == s);
+}
+
+static vmIntrinsics::ID match_method_with_klass(Method* m, Symbol* mk) {
+#define VM_INTRINSIC_MATCH(id, klassname, namepart, sigpart, flags) \
+  { Symbol* k = vmSymbols::klassname(); \
+    if (mk == k) { \
+      Symbol* n = vmSymbols::namepart(); \
+      Symbol* s = vmSymbols::sigpart(); \
+      if (match_method(m, n, s)) \
+        return vmIntrinsics::id; \
+    } }
+  VM_INTRINSICS_DO(VM_INTRINSIC_MATCH,
+                   VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
+  return vmIntrinsics::_none;
+#undef VM_INTRINSIC_MATCH
+}
+
+void vmIntrinsics::verify_method(ID actual_id, Method* m) {
+  Symbol* mk = m->method_holder()->name();
+  ID declared_id = match_method_with_klass(m, mk);
+
+  if (declared_id == actual_id)  return; // success
+
+  if (declared_id == _none && actual_id != _none && mk == vmSymbols::java_lang_StrictMath()) {
+    // Here are a few special cases in StrictMath not declared in vmSymbols.hpp.
+    switch (actual_id) {
+    case _min:
+    case _max:
+    case _dsqrt:
+      declared_id = match_method_with_klass(m, vmSymbols::java_lang_Math());
+      if (declared_id == actual_id)  return; // acceptable alias
+      break;
+    default:
+        break;
+    }
+  }
+
+  const char* declared_name = name_at(declared_id);
+  const char* actual_name   = name_at(actual_id);
+  m = NULL;
+  ttyLocker ttyl;
+  if (xtty != NULL) {
+    xtty->begin_elem("intrinsic_misdeclared actual='%s' declared='%s'",
+                     actual_name, declared_name);
+    xtty->method(m);
+    xtty->end_elem("%s", "");
+  }
+  if (PrintMiscellaneous && (WizardMode || Verbose)) {
+    tty->print_cr("*** misidentified method; %s(%d) should be %s(%d):",
+                  declared_name, declared_id, actual_name, actual_id);
+    m->print_short_name(tty);
+    tty->cr();
+  }
+}
+#endif //PRODUCT
diff --git a/src/hotspot/share/classfile/vmIntrinsics.hpp b/src/hotspot/share/classfile/vmIntrinsics.hpp
new file mode 100644
index 00000000000..7d4a76b6ee5
--- /dev/null
+++ b/src/hotspot/share/classfile/vmIntrinsics.hpp
@@ -0,0 +1,873 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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_VMINTRINSICS_HPP
+#define SHARE_CLASSFILE_VMINTRINSICS_HPP
+
+// Here are all the intrinsics known to the runtime and the CI.
+// Each intrinsic consists of a public enum name (like _hashCode),
+// followed by a specification of its klass, name, and signature:
+//    template(<id>,  <klass>,  <name>, <sig>, <FCODE>)
+//
+// If you add an intrinsic here, you must also define its name
+// and signature as members of the VM symbols.  The VM symbols for
+// the intrinsic name and signature may be defined above.
+//
+// Because the VM_SYMBOLS_DO macro makes reference to VM_INTRINSICS_DO,
+// you can also define an intrinsic's name and/or signature locally to the
+// intrinsic, if this makes sense.  (It often does make sense.)
+//
+// For example:
+//    do_intrinsic(_foo,  java_lang_Object,  foo_name, foo_signature, F_xx)
+//     do_name(     foo_name, "foo")
+//     do_signature(foo_signature, "()F")
+// klass      = vmSymbols::java_lang_Object()
+// name       = vmSymbols::foo_name()
+// signature  = vmSymbols::foo_signature()
+//
+// The name and/or signature might be a "well known" symbol
+// like "equal" or "()I", in which case there will be no local
+// re-definition of the symbol.
+//
+// The do_class, do_name, and do_signature calls are all used for the
+// same purpose:  Define yet another VM symbol.  They could all be merged
+// into a common 'do_symbol' call, but it seems useful to record our
+// intentions here about kinds of symbols (class vs. name vs. signature).
+//
+// The F_xx is one of the Flags enum; see below.
+//
+// for Emacs: (let ((c-backslash-column 120) (c-backslash-max-column 120)) (c-backslash-region (point) (point-max) nil t))
+//
+//
+// There are two types of intrinsic methods: (1) Library intrinsics and (2) bytecode intrinsics.
+//
+// (1) A library intrinsic method may be replaced with hand-crafted assembly code,
+// with hand-crafted compiler IR, or with a combination of the two. The semantics
+// of the replacement code may differ from the semantics of the replaced code.
+//
+// (2) Bytecode intrinsic methods are not replaced by special code, but they are
+// treated in some other special way by the compiler. For example, the compiler
+// may delay inlining for some String-related intrinsic methods (e.g., some methods
+// defined in the StringBuilder and StringBuffer classes, see
+// Compile::should_delay_string_inlining() for more details).
+//
+// Due to the difference between the semantics of an intrinsic method as defined
+// in the (Java) source code and the semantics of the method as defined
+// by the code in the VM, intrinsic methods must be explicitly marked.
+//
+// Intrinsic methods are marked by the jdk.internal.HotSpotIntrinsicCandidate
+// annotation. If CheckIntrinsics is enabled, the VM performs the following
+// checks when a class C is loaded: (1) all intrinsics defined by the VM for
+// class C are present in the loaded class file and are marked;
+// (2) an intrinsic is defined by the VM for all marked methods of class C;
+// (3) check for orphan methods in class C (i.e., methods for which the VM
+// declares an intrinsic but that are not declared for the loaded class C.
+// Check (3) is available only in debug builds.
+//
+// If a mismatch is detected for a method, the VM behaves differently depending
+// on the type of build. A fastdebug build exits and reports an error on a mismatch.
+// A product build will not replace an unmarked library intrinsic method with
+// hand-crafted code, that is, unmarked library intrinsics are treated as ordinary
+// methods in a product build. The special treatment of a bytecode intrinsic method
+// persists even if the method not marked.
+//
+// When adding an intrinsic for a method, please make sure to appropriately
+// annotate the method in the source code. The list below contains all
+// library intrinsics followed by bytecode intrinsics. Please also make sure to
+// add the declaration of the intrinsic to the approriate section of the list.
+#define VM_INTRINSICS_DO(do_intrinsic, do_class, do_name, do_signature, do_alias)                                       \
+  /* (1) Library intrinsics                                                                        */                   \
+  do_intrinsic(_hashCode,                 java_lang_Object,       hashCode_name, void_int_signature,             F_R)   \
+   do_name(     hashCode_name,                                   "hashCode")                                            \
+  do_intrinsic(_getClass,                 java_lang_Object,       getClass_name, void_class_signature,           F_R)   \
+   do_name(     getClass_name,                                   "getClass")                                            \
+  do_intrinsic(_clone,                    java_lang_Object,       clone_name, void_object_signature,             F_R)   \
+   do_name(     clone_name,                                      "clone")                                               \
+  do_intrinsic(_notify,                   java_lang_Object,       notify_name, void_method_signature,            F_R)   \
+   do_name(     notify_name,                                     "notify")                                              \
+  do_intrinsic(_notifyAll,                java_lang_Object,       notifyAll_name, void_method_signature,         F_R)   \
+   do_name(     notifyAll_name,                                  "notifyAll")                                           \
+                                                                                                                        \
+  /* Math & StrictMath intrinsics are defined in terms of just a few signatures: */                                     \
+  do_class(java_lang_Math,                "java/lang/Math")                                                             \
+  do_class(java_lang_StrictMath,          "java/lang/StrictMath")                                                       \
+  do_signature(double2_double_signature,  "(DD)D")                                                                      \
+  do_signature(double3_double_signature,  "(DDD)D")                                                                     \
+  do_signature(float2_float_signature,    "(FF)F")                                                                      \
+  do_signature(float3_float_signature,    "(FFF)F")                                                                     \
+  do_signature(int2_int_signature,        "(II)I")                                                                      \
+  do_signature(long2_long_signature,      "(JJ)J")                                                                      \
+                                                                                                                        \
+  /* here are the math names, all together: */                                                                          \
+  do_name(abs_name,"abs")       do_name(sin_name,"sin")         do_name(cos_name,"cos")                                 \
+  do_name(tan_name,"tan")       do_name(atan2_name,"atan2")     do_name(sqrt_name,"sqrt")                               \
+  do_name(log_name,"log")       do_name(log10_name,"log10")     do_name(pow_name,"pow")                                 \
+  do_name(exp_name,"exp")       do_name(min_name,"min")         do_name(max_name,"max")                                 \
+  do_name(floor_name, "floor")  do_name(ceil_name, "ceil")      do_name(rint_name, "rint")                              \
+                                                                                                                        \
+  do_name(addExact_name,"addExact")                                                                                     \
+  do_name(decrementExact_name,"decrementExact")                                                                         \
+  do_name(incrementExact_name,"incrementExact")                                                                         \
+  do_name(multiplyExact_name,"multiplyExact")                                                                           \
+  do_name(multiplyHigh_name,"multiplyHigh")                                                                             \
+  do_name(negateExact_name,"negateExact")                                                                               \
+  do_name(subtractExact_name,"subtractExact")                                                                           \
+  do_name(fma_name, "fma")                                                                                              \
+  do_name(copySign_name, "copySign")                                                                                    \
+  do_name(signum_name,"signum")                                                                                         \
+                                                                                                                        \
+  do_intrinsic(_dabs,                     java_lang_Math,         abs_name,   double_double_signature,           F_S)   \
+  do_intrinsic(_fabs,                     java_lang_Math,         abs_name,   float_float_signature,           F_S)   \
+  do_intrinsic(_iabs,                     java_lang_Math,         abs_name,   int_int_signature,           F_S)   \
+  do_intrinsic(_labs,                     java_lang_Math,         abs_name,   long_long_signature,           F_S)   \
+  do_intrinsic(_dsin,                     java_lang_Math,         sin_name,   double_double_signature,           F_S)   \
+  do_intrinsic(_floor,                    java_lang_Math,         floor_name, double_double_signature,           F_S)   \
+  do_intrinsic(_ceil,                     java_lang_Math,         ceil_name,  double_double_signature,           F_S)   \
+  do_intrinsic(_rint,                     java_lang_Math,         rint_name,  double_double_signature,           F_S)   \
+  do_intrinsic(_dcos,                     java_lang_Math,         cos_name,   double_double_signature,           F_S)   \
+  do_intrinsic(_dtan,                     java_lang_Math,         tan_name,   double_double_signature,           F_S)   \
+  do_intrinsic(_datan2,                   java_lang_Math,         atan2_name, double2_double_signature,          F_S)   \
+  do_intrinsic(_dsqrt,                    java_lang_Math,         sqrt_name,  double_double_signature,           F_S)   \
+  do_intrinsic(_dlog,                     java_lang_Math,         log_name,   double_double_signature,           F_S)   \
+  do_intrinsic(_dlog10,                   java_lang_Math,         log10_name, double_double_signature,           F_S)   \
+  do_intrinsic(_dpow,                     java_lang_Math,         pow_name,   double2_double_signature,          F_S)   \
+  do_intrinsic(_dexp,                     java_lang_Math,         exp_name,   double_double_signature,           F_S)   \
+  do_intrinsic(_min,                      java_lang_Math,         min_name,   int2_int_signature,                F_S)   \
+  do_intrinsic(_max,                      java_lang_Math,         max_name,   int2_int_signature,                F_S)   \
+  do_intrinsic(_addExactI,                java_lang_Math,         addExact_name, int2_int_signature,             F_S)   \
+  do_intrinsic(_addExactL,                java_lang_Math,         addExact_name, long2_long_signature,           F_S)   \
+  do_intrinsic(_decrementExactI,          java_lang_Math,         decrementExact_name, int_int_signature,        F_S)   \
+  do_intrinsic(_decrementExactL,          java_lang_Math,         decrementExact_name, long_long_signature,      F_S)   \
+  do_intrinsic(_incrementExactI,          java_lang_Math,         incrementExact_name, int_int_signature,        F_S)   \
+  do_intrinsic(_incrementExactL,          java_lang_Math,         incrementExact_name, long_long_signature,      F_S)   \
+  do_intrinsic(_multiplyExactI,           java_lang_Math,         multiplyExact_name, int2_int_signature,        F_S)   \
+  do_intrinsic(_multiplyExactL,           java_lang_Math,         multiplyExact_name, long2_long_signature,      F_S)   \
+  do_intrinsic(_multiplyHigh,             java_lang_Math,         multiplyHigh_name, long2_long_signature,       F_S)   \
+  do_intrinsic(_negateExactI,             java_lang_Math,         negateExact_name, int_int_signature,           F_S)   \
+  do_intrinsic(_negateExactL,             java_lang_Math,         negateExact_name, long_long_signature,         F_S)   \
+  do_intrinsic(_subtractExactI,           java_lang_Math,         subtractExact_name, int2_int_signature,        F_S)   \
+  do_intrinsic(_subtractExactL,           java_lang_Math,         subtractExact_name, long2_long_signature,      F_S)   \
+  do_intrinsic(_fmaD,                     java_lang_Math,         fma_name,           double3_double_signature,  F_S)   \
+  do_intrinsic(_fmaF,                     java_lang_Math,         fma_name,           float3_float_signature,    F_S)   \
+  do_intrinsic(_maxF,                     java_lang_Math,         max_name,           float2_float_signature,    F_S)   \
+  do_intrinsic(_minF,                     java_lang_Math,         min_name,           float2_float_signature,    F_S)   \
+  do_intrinsic(_maxD,                     java_lang_Math,         max_name,           double2_double_signature,  F_S)   \
+  do_intrinsic(_minD,                     java_lang_Math,         min_name,           double2_double_signature,  F_S)   \
+  do_intrinsic(_dcopySign,                java_lang_Math,         copySign_name,      double2_double_signature,  F_S)   \
+  do_intrinsic(_fcopySign,                java_lang_Math,         copySign_name,      float2_float_signature,    F_S)   \
+  do_intrinsic(_dsignum,                  java_lang_Math,         signum_name,        double_double_signature,   F_S)   \
+  do_intrinsic(_fsignum,                  java_lang_Math,         signum_name,        float_float_signature,     F_S)   \
+                                                                                                                        \
+  do_intrinsic(_floatToRawIntBits,        java_lang_Float,        floatToRawIntBits_name,   float_int_signature, F_S)   \
+   do_name(     floatToRawIntBits_name,                          "floatToRawIntBits")                                   \
+  do_intrinsic(_floatToIntBits,           java_lang_Float,        floatToIntBits_name,      float_int_signature, F_S)   \
+   do_name(     floatToIntBits_name,                             "floatToIntBits")                                      \
+  do_intrinsic(_intBitsToFloat,           java_lang_Float,        intBitsToFloat_name,      int_float_signature, F_S)   \
+   do_name(     intBitsToFloat_name,                             "intBitsToFloat")                                      \
+  do_intrinsic(_doubleToRawLongBits,      java_lang_Double,       doubleToRawLongBits_name, double_long_signature, F_S) \
+   do_name(     doubleToRawLongBits_name,                        "doubleToRawLongBits")                                 \
+  do_intrinsic(_doubleToLongBits,         java_lang_Double,       doubleToLongBits_name,    double_long_signature, F_S) \
+   do_name(     doubleToLongBits_name,                           "doubleToLongBits")                                    \
+  do_intrinsic(_longBitsToDouble,         java_lang_Double,       longBitsToDouble_name,    long_double_signature, F_S) \
+   do_name(     longBitsToDouble_name,                           "longBitsToDouble")                                    \
+                                                                                                                        \
+  do_intrinsic(_numberOfLeadingZeros_i,   java_lang_Integer,      numberOfLeadingZeros_name,int_int_signature,   F_S)   \
+  do_intrinsic(_numberOfLeadingZeros_l,   java_lang_Long,         numberOfLeadingZeros_name,long_int_signature,  F_S)   \
+                                                                                                                        \
+  do_intrinsic(_numberOfTrailingZeros_i,  java_lang_Integer,      numberOfTrailingZeros_name,int_int_signature,  F_S)   \
+  do_intrinsic(_numberOfTrailingZeros_l,  java_lang_Long,         numberOfTrailingZeros_name,long_int_signature, F_S)   \
+                                                                                                                        \
+  do_intrinsic(_bitCount_i,               java_lang_Integer,      bitCount_name,            int_int_signature,   F_S)   \
+  do_intrinsic(_bitCount_l,               java_lang_Long,         bitCount_name,            long_int_signature,  F_S)   \
+                                                                                                                        \
+  do_intrinsic(_reverseBytes_i,           java_lang_Integer,      reverseBytes_name,        int_int_signature,   F_S)   \
+   do_name(     reverseBytes_name,                               "reverseBytes")                                        \
+  do_intrinsic(_reverseBytes_l,           java_lang_Long,         reverseBytes_name,        long_long_signature, F_S)   \
+    /*  (symbol reverseBytes_name defined above) */                                                                     \
+  do_intrinsic(_reverseBytes_c,           java_lang_Character,    reverseBytes_name,        char_char_signature, F_S)   \
+    /*  (symbol reverseBytes_name defined above) */                                                                     \
+  do_intrinsic(_reverseBytes_s,           java_lang_Short,        reverseBytes_name,        short_short_signature, F_S) \
+    /*  (symbol reverseBytes_name defined above) */                                                                     \
+                                                                                                                        \
+  do_intrinsic(_identityHashCode,         java_lang_System,       identityHashCode_name, object_int_signature,   F_S)   \
+   do_name(     identityHashCode_name,                           "identityHashCode")                                    \
+  do_intrinsic(_currentTimeMillis,        java_lang_System,       currentTimeMillis_name, void_long_signature,   F_S)   \
+                                                                                                                        \
+   do_name(     currentTimeMillis_name,                          "currentTimeMillis")                                   \
+  do_intrinsic(_nanoTime,                 java_lang_System,       nanoTime_name,          void_long_signature,   F_S)   \
+   do_name(     nanoTime_name,                                   "nanoTime")                                            \
+                                                                                                                        \
+  JFR_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)                                               \
+                                                                                                                        \
+  do_intrinsic(_arraycopy,                java_lang_System,       arraycopy_name, arraycopy_signature,           F_S)   \
+   do_name(     arraycopy_name,                                  "arraycopy")                                           \
+   do_signature(arraycopy_signature,                             "(Ljava/lang/Object;ILjava/lang/Object;II)V")          \
+  do_intrinsic(_currentThread,            java_lang_Thread,       currentThread_name, currentThread_signature,   F_S)   \
+   do_name(     currentThread_name,                              "currentThread")                                       \
+   do_signature(currentThread_signature,                         "()Ljava/lang/Thread;")                                \
+                                                                                                                        \
+  /* reflective intrinsics, for java/lang/Class, etc. */                                                                \
+  do_intrinsic(_isAssignableFrom,         java_lang_Class,        isAssignableFrom_name, class_boolean_signature, F_RN) \
+   do_name(     isAssignableFrom_name,                           "isAssignableFrom")                                    \
+  do_intrinsic(_isInstance,               java_lang_Class,        isInstance_name, object_boolean_signature,     F_RN)  \
+   do_name(     isInstance_name,                                 "isInstance")                                          \
+  do_intrinsic(_getModifiers,             java_lang_Class,        getModifiers_name, void_int_signature,         F_RN)  \
+   do_name(     getModifiers_name,                               "getModifiers")                                        \
+  do_intrinsic(_isInterface,              java_lang_Class,        isInterface_name, void_boolean_signature,      F_RN)  \
+   do_name(     isInterface_name,                                "isInterface")                                         \
+  do_intrinsic(_isArray,                  java_lang_Class,        isArray_name, void_boolean_signature,          F_RN)  \
+   do_name(     isArray_name,                                    "isArray")                                             \
+  do_intrinsic(_isPrimitive,              java_lang_Class,        isPrimitive_name, void_boolean_signature,      F_RN)  \
+   do_name(     isPrimitive_name,                                "isPrimitive")                                         \
+  do_intrinsic(_isHidden,                 java_lang_Class,        isHidden_name, void_boolean_signature,         F_RN)  \
+   do_name(     isHidden_name,                                   "isHidden")                                            \
+  do_intrinsic(_getSuperclass,            java_lang_Class,        getSuperclass_name, void_class_signature,      F_RN)  \
+   do_name(     getSuperclass_name,                              "getSuperclass")                                       \
+  do_intrinsic(_Class_cast,               java_lang_Class,        Class_cast_name, object_object_signature,      F_R)   \
+   do_name(     Class_cast_name,                                 "cast")                                                \
+                                                                                                                        \
+  do_intrinsic(_getClassAccessFlags,      reflect_Reflection,     getClassAccessFlags_name, class_int_signature, F_SN)  \
+   do_name(     getClassAccessFlags_name,                        "getClassAccessFlags")                                 \
+  do_intrinsic(_getLength,                java_lang_reflect_Array, getLength_name, object_int_signature,         F_SN)  \
+   do_name(     getLength_name,                                   "getLength")                                          \
+                                                                                                                        \
+  do_intrinsic(_getCallerClass,           reflect_Reflection,     getCallerClass_name, void_class_signature,     F_SN)  \
+   do_name(     getCallerClass_name,                             "getCallerClass")                                      \
+                                                                                                                        \
+  do_intrinsic(_newArray,                 java_lang_reflect_Array, newArray_name, newArray_signature,            F_SN)  \
+   do_name(     newArray_name,                                    "newArray")                                           \
+   do_signature(newArray_signature,                               "(Ljava/lang/Class;I)Ljava/lang/Object;")             \
+                                                                                                                        \
+  do_intrinsic(_onSpinWait,               java_lang_Thread,       onSpinWait_name, onSpinWait_signature,         F_S)   \
+   do_name(     onSpinWait_name,                                  "onSpinWait")                                         \
+   do_alias(    onSpinWait_signature,                             void_method_signature)                                \
+                                                                                                                        \
+  do_intrinsic(_copyOf,                   java_util_Arrays,       copyOf_name, copyOf_signature,                 F_S)   \
+   do_name(     copyOf_name,                                     "copyOf")                                              \
+   do_signature(copyOf_signature,             "([Ljava/lang/Object;ILjava/lang/Class;)[Ljava/lang/Object;")             \
+                                                                                                                        \
+  do_intrinsic(_copyOfRange,              java_util_Arrays,       copyOfRange_name, copyOfRange_signature,       F_S)   \
+   do_name(     copyOfRange_name,                                "copyOfRange")                                         \
+   do_signature(copyOfRange_signature,        "([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;")            \
+                                                                                                                        \
+  do_intrinsic(_equalsC,                  java_util_Arrays,       equals_name,    equalsC_signature,             F_S)   \
+   do_signature(equalsC_signature,                               "([C[C)Z")                                             \
+  do_intrinsic(_equalsB,                  java_util_Arrays,       equals_name,    equalsB_signature,             F_S)   \
+   do_signature(equalsB_signature,                               "([B[B)Z")                                             \
+                                                                                                                        \
+  do_intrinsic(_compressStringC,          java_lang_StringUTF16,  compress_name, encodeISOArray_signature,       F_S)   \
+   do_name(     compress_name,                                   "compress")                                            \
+  do_intrinsic(_compressStringB,          java_lang_StringUTF16,  compress_name, indexOfI_signature,             F_S)   \
+  do_intrinsic(_inflateStringC,           java_lang_StringLatin1, inflate_name, inflateC_signature,              F_S)   \
+   do_name(     inflate_name,                                    "inflate")                                             \
+   do_signature(inflateC_signature,                              "([BI[CII)V")                                          \
+  do_intrinsic(_inflateStringB,           java_lang_StringLatin1, inflate_name, inflateB_signature,              F_S)   \
+   do_signature(inflateB_signature,                              "([BI[BII)V")                                          \
+  do_intrinsic(_toBytesStringU,           java_lang_StringUTF16, toBytes_name, toBytesU_signature,               F_S)   \
+   do_name(     toBytes_name,                                    "toBytes")                                             \
+   do_signature(toBytesU_signature,                              "([CII)[B")                                            \
+  do_intrinsic(_getCharsStringU,          java_lang_StringUTF16, getCharsU_name, getCharsU_signature,            F_S)   \
+   do_name(     getCharsU_name,                                  "getChars")                                            \
+   do_signature(getCharsU_signature,                             "([BII[CI)V")                                          \
+  do_intrinsic(_getCharStringU,           java_lang_StringUTF16, getChar_name, getCharStringU_signature,         F_S)   \
+   do_signature(getCharStringU_signature,                        "([BI)C")                                              \
+  do_intrinsic(_putCharStringU,           java_lang_StringUTF16, putChar_name, putCharStringU_signature,         F_S)   \
+   do_signature(putCharStringU_signature,                        "([BII)V")                                             \
+  do_intrinsic(_compareToL,               java_lang_StringLatin1,compareTo_name, compareTo_indexOf_signature,    F_S)   \
+  do_intrinsic(_compareToU,               java_lang_StringUTF16, compareTo_name, compareTo_indexOf_signature,    F_S)   \
+  do_intrinsic(_compareToLU,              java_lang_StringLatin1,compareToLU_name, compareTo_indexOf_signature,  F_S)   \
+  do_intrinsic(_compareToUL,              java_lang_StringUTF16, compareToUL_name, compareTo_indexOf_signature,  F_S)   \
+   do_signature(compareTo_indexOf_signature,                     "([B[B)I")                                             \
+   do_name(     compareTo_name,                                  "compareTo")                                           \
+   do_name(     compareToLU_name,                                "compareToUTF16")                                      \
+   do_name(     compareToUL_name,                                "compareToLatin1")                                     \
+  do_intrinsic(_indexOfL,                 java_lang_StringLatin1,indexOf_name, compareTo_indexOf_signature,      F_S)   \
+  do_intrinsic(_indexOfU,                 java_lang_StringUTF16, indexOf_name, compareTo_indexOf_signature,      F_S)   \
+  do_intrinsic(_indexOfUL,                java_lang_StringUTF16, indexOfUL_name, compareTo_indexOf_signature,    F_S)   \
+  do_intrinsic(_indexOfIL,                java_lang_StringLatin1,indexOf_name, indexOfI_signature,               F_S)   \
+  do_intrinsic(_indexOfIU,                java_lang_StringUTF16, indexOf_name, indexOfI_signature,               F_S)   \
+  do_intrinsic(_indexOfIUL,               java_lang_StringUTF16, indexOfUL_name, indexOfI_signature,             F_S)   \
+  do_intrinsic(_indexOfU_char,            java_lang_StringUTF16, indexOfChar_name, indexOfChar_signature,        F_S)   \
+   do_name(     indexOf_name,                                    "indexOf")                                             \
+   do_name(     indexOfChar_name,                                "indexOfChar")                                         \
+   do_name(     indexOfUL_name,                                  "indexOfLatin1")                                       \
+   do_signature(indexOfI_signature,                              "([BI[BII)I")                                          \
+   do_signature(indexOfChar_signature,                           "([BIII)I")                                            \
+  do_intrinsic(_equalsL,                  java_lang_StringLatin1,equals_name, equalsB_signature,                 F_S)   \
+  do_intrinsic(_equalsU,                  java_lang_StringUTF16, equals_name, equalsB_signature,                 F_S)   \
+                                                                                                                        \
+  do_intrinsic(_isDigit,                  java_lang_CharacterDataLatin1, isDigit_name,      int_bool_signature,  F_R)   \
+   do_name(     isDigit_name,                                           "isDigit")                                      \
+  do_intrinsic(_isLowerCase,              java_lang_CharacterDataLatin1, isLowerCase_name,  int_bool_signature,  F_R)   \
+   do_name(     isLowerCase_name,                                       "isLowerCase")                                  \
+  do_intrinsic(_isUpperCase,              java_lang_CharacterDataLatin1, isUpperCase_name,  int_bool_signature,  F_R)   \
+   do_name(     isUpperCase_name,                                       "isUpperCase")                                  \
+  do_intrinsic(_isWhitespace,             java_lang_CharacterDataLatin1, isWhitespace_name, int_bool_signature,  F_R)   \
+   do_name(     isWhitespace_name,                                      "isWhitespace")                                 \
+                                                                                                                        \
+  do_intrinsic(_Preconditions_checkIndex, jdk_internal_util_Preconditions, checkIndex_name, Preconditions_checkIndex_signature, F_S)   \
+   do_signature(Preconditions_checkIndex_signature,              "(IILjava/util/function/BiFunction;)I")                \
+                                                                                                                        \
+  do_class(java_nio_Buffer,               "java/nio/Buffer")                                                            \
+  do_intrinsic(_checkIndex,               java_nio_Buffer,        checkIndex_name, int_int_signature,            F_R)   \
+   do_name(     checkIndex_name,                                 "checkIndex")                                          \
+                                                                                                                        \
+  do_class(java_lang_StringCoding,        "java/lang/StringCoding")                                                     \
+  do_intrinsic(_hasNegatives,             java_lang_StringCoding, hasNegatives_name, hasNegatives_signature,     F_S)   \
+   do_name(     hasNegatives_name,                               "hasNegatives")                                        \
+   do_signature(hasNegatives_signature,                          "([BII)Z")                                             \
+                                                                                                                        \
+  do_class(sun_nio_cs_iso8859_1_Encoder,  "sun/nio/cs/ISO_8859_1$Encoder")                                              \
+  do_intrinsic(_encodeISOArray,     sun_nio_cs_iso8859_1_Encoder, encodeISOArray_name, encodeISOArray_signature, F_S)   \
+   do_name(     encodeISOArray_name,                             "implEncodeISOArray")                                  \
+   do_signature(encodeISOArray_signature,                        "([CI[BII)I")                                          \
+                                                                                                                        \
+  do_intrinsic(_encodeByteISOArray,     java_lang_StringCoding, encodeISOArray_name, indexOfI_signature,         F_S)   \
+                                                                                                                        \
+  do_class(java_math_BigInteger,                      "java/math/BigInteger")                                           \
+  do_intrinsic(_multiplyToLen,      java_math_BigInteger, multiplyToLen_name, multiplyToLen_signature, F_S)             \
+   do_name(     multiplyToLen_name,                             "implMultiplyToLen")                                    \
+   do_signature(multiplyToLen_signature,                        "([II[II[I)[I")                                         \
+                                                                                                                        \
+  do_intrinsic(_squareToLen, java_math_BigInteger, squareToLen_name, squareToLen_signature, F_S)                        \
+   do_name(     squareToLen_name,                             "implSquareToLen")                                        \
+   do_signature(squareToLen_signature,                        "([II[II)[I")                                             \
+                                                                                                                        \
+  do_intrinsic(_mulAdd, java_math_BigInteger, mulAdd_name, mulAdd_signature, F_S)                                       \
+   do_name(     mulAdd_name,                                  "implMulAdd")                                             \
+   do_signature(mulAdd_signature,                             "([I[IIII)I")                                             \
+                                                                                                                        \
+  do_intrinsic(_montgomeryMultiply,      java_math_BigInteger, montgomeryMultiply_name, montgomeryMultiply_signature, F_S) \
+   do_name(     montgomeryMultiply_name,                             "implMontgomeryMultiply")                          \
+   do_signature(montgomeryMultiply_signature,                        "([I[I[IIJ[I)[I")                                  \
+                                                                                                                        \
+  do_intrinsic(_montgomerySquare,      java_math_BigInteger, montgomerySquare_name, montgomerySquare_signature, F_S)    \
+   do_name(     montgomerySquare_name,                             "implMontgomerySquare")                              \
+   do_signature(montgomerySquare_signature,                        "([I[IIJ[I)[I")                                      \
+                                                                                                                        \
+  do_intrinsic(_bigIntegerRightShiftWorker, java_math_BigInteger, rightShift_name, big_integer_shift_worker_signature, F_S) \
+   do_name(     rightShift_name,                                 "shiftRightImplWorker")                                \
+                                                                                                                        \
+  do_intrinsic(_bigIntegerLeftShiftWorker, java_math_BigInteger, leftShift_name, big_integer_shift_worker_signature, F_S) \
+   do_name(     leftShift_name,                                 "shiftLeftImplWorker")                                  \
+                                                                                                                        \
+  do_class(jdk_internal_util_ArraysSupport, "jdk/internal/util/ArraysSupport")                                                          \
+  do_intrinsic(_vectorizedMismatch, jdk_internal_util_ArraysSupport, vectorizedMismatch_name, vectorizedMismatch_signature, F_S)\
+   do_name(vectorizedMismatch_name, "vectorizedMismatch")                                                               \
+   do_signature(vectorizedMismatch_signature, "(Ljava/lang/Object;JLjava/lang/Object;JII)I")                            \
+                                                                                                                        \
+  /* java/lang/ref/Reference */                                                                                         \
+  do_intrinsic(_Reference_get,            java_lang_ref_Reference, get_name,    void_object_signature, F_R)             \
+                                                                                                                        \
+  /* support for com.sun.crypto.provider.AESCrypt and some of its callers */                                            \
+  do_class(com_sun_crypto_provider_aescrypt,      "com/sun/crypto/provider/AESCrypt")                                   \
+  do_intrinsic(_aescrypt_encryptBlock, com_sun_crypto_provider_aescrypt, encryptBlock_name, byteArray_int_byteArray_int_signature, F_R)   \
+  do_intrinsic(_aescrypt_decryptBlock, com_sun_crypto_provider_aescrypt, decryptBlock_name, byteArray_int_byteArray_int_signature, F_R)   \
+   do_name(     encryptBlock_name,                                 "implEncryptBlock")                                  \
+   do_name(     decryptBlock_name,                                 "implDecryptBlock")                                  \
+   do_signature(byteArray_int_byteArray_int_signature,             "([BI[BI)V")                                         \
+                                                                                                                        \
+  do_class(com_sun_crypto_provider_cipherBlockChaining,            "com/sun/crypto/provider/CipherBlockChaining")       \
+   do_intrinsic(_cipherBlockChaining_encryptAESCrypt, com_sun_crypto_provider_cipherBlockChaining, encrypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
+   do_intrinsic(_cipherBlockChaining_decryptAESCrypt, com_sun_crypto_provider_cipherBlockChaining, decrypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
+   do_name(     encrypt_name,                                      "implEncrypt")                                       \
+   do_name(     decrypt_name,                                      "implDecrypt")                                       \
+   do_signature(byteArray_int_int_byteArray_int_signature,         "([BII[BI)I")                                        \
+                                                                                                                        \
+  do_class(com_sun_crypto_provider_electronicCodeBook, "com/sun/crypto/provider/ElectronicCodeBook")                    \
+   do_intrinsic(_electronicCodeBook_encryptAESCrypt, com_sun_crypto_provider_electronicCodeBook, ecb_encrypt_name, byteArray_int_int_byteArray_int_signature, F_R)  \
+   do_intrinsic(_electronicCodeBook_decryptAESCrypt, com_sun_crypto_provider_electronicCodeBook, ecb_decrypt_name, byteArray_int_int_byteArray_int_signature, F_R)  \
+   do_name(ecb_encrypt_name, "implECBEncrypt")                                                                          \
+   do_name(ecb_decrypt_name, "implECBDecrypt")                                                                          \
+                                                                                                                        \
+  do_class(com_sun_crypto_provider_counterMode,      "com/sun/crypto/provider/CounterMode")                             \
+   do_intrinsic(_counterMode_AESCrypt, com_sun_crypto_provider_counterMode, crypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
+   do_name(     crypt_name,                                 "implCrypt")                                                    \
+                                                                                                                        \
+  /* support for sun.security.provider.MD5 */                                                                           \
+  do_class(sun_security_provider_md5,                              "sun/security/provider/MD5")                         \
+  do_intrinsic(_md5_implCompress, sun_security_provider_md5, implCompress_name, implCompress_signature, F_R)            \
+   do_name(     implCompress_name,                                 "implCompress0")                                     \
+   do_signature(implCompress_signature,                            "([BI)V")                                            \
+                                                                                                                        \
+  /* support for sun.security.provider.SHA */                                                                           \
+  do_class(sun_security_provider_sha,                              "sun/security/provider/SHA")                         \
+  do_intrinsic(_sha_implCompress, sun_security_provider_sha, implCompress_name, implCompress_signature, F_R)            \
+                                                                                                                        \
+  /* support for sun.security.provider.SHA2 */                                                                          \
+  do_class(sun_security_provider_sha2,                             "sun/security/provider/SHA2")                        \
+  do_intrinsic(_sha2_implCompress, sun_security_provider_sha2, implCompress_name, implCompress_signature, F_R)          \
+                                                                                                                        \
+  /* support for sun.security.provider.SHA5 */                                                                          \
+  do_class(sun_security_provider_sha5,                             "sun/security/provider/SHA5")                        \
+  do_intrinsic(_sha5_implCompress, sun_security_provider_sha5, implCompress_name, implCompress_signature, F_R)          \
+                                                                                                                        \
+  /* support for sun.security.provider.DigestBase */                                                                    \
+  do_class(sun_security_provider_digestbase,                       "sun/security/provider/DigestBase")                  \
+  do_intrinsic(_digestBase_implCompressMB, sun_security_provider_digestbase, implCompressMB_name, implCompressMB_signature, F_R)   \
+   do_name(     implCompressMB_name,                               "implCompressMultiBlock0")                           \
+   do_signature(implCompressMB_signature,                          "([BII)I")                                           \
+                                                                                                                        \
+   /* support for java.util.Base64.Encoder*/                                                                            \
+  do_class(java_util_Base64_Encoder, "java/util/Base64$Encoder")                                                        \
+  do_intrinsic(_base64_encodeBlock, java_util_Base64_Encoder, encodeBlock_name, encodeBlock_signature, F_R)             \
+  do_name(encodeBlock_name, "encodeBlock")                                                                              \
+  do_signature(encodeBlock_signature, "([BII[BIZ)V")                                                                    \
+                                                                                                                        \
+  /* support for com.sun.crypto.provider.GHASH */                                                                       \
+  do_class(com_sun_crypto_provider_ghash, "com/sun/crypto/provider/GHASH")                                              \
+  do_intrinsic(_ghash_processBlocks, com_sun_crypto_provider_ghash, processBlocks_name, ghash_processBlocks_signature, F_S) \
+   do_name(processBlocks_name, "processBlocks")                                                                         \
+   do_signature(ghash_processBlocks_signature, "([BII[J[J)V")                                                           \
+                                                                                                                        \
+  /* support for java.util.zip */                                                                                       \
+  do_class(java_util_zip_CRC32,           "java/util/zip/CRC32")                                                        \
+  do_intrinsic(_updateCRC32,               java_util_zip_CRC32,   update_name, int2_int_signature,               F_SN)  \
+   do_name(     update_name,                                      "update")                                             \
+  do_intrinsic(_updateBytesCRC32,          java_util_zip_CRC32,   updateBytes_name, updateBytes_signature,       F_SN)  \
+   do_name(     updateBytes_name,                                "updateBytes0")                                        \
+   do_signature(updateBytes_signature,                           "(I[BII)I")                                            \
+  do_intrinsic(_updateByteBufferCRC32,     java_util_zip_CRC32,   updateByteBuffer_name, updateByteBuffer_signature, F_SN) \
+   do_name(     updateByteBuffer_name,                           "updateByteBuffer0")                                   \
+   do_signature(updateByteBuffer_signature,                      "(IJII)I")                                             \
+                                                                                                                        \
+  /* support for java.util.zip.CRC32C */                                                                                \
+  do_class(java_util_zip_CRC32C,          "java/util/zip/CRC32C")                                                       \
+  do_intrinsic(_updateBytesCRC32C,         java_util_zip_CRC32C,  updateBytes_C_name, updateBytes_signature,       F_S) \
+   do_name(     updateBytes_C_name,                               "updateBytes")                                        \
+  do_intrinsic(_updateDirectByteBufferCRC32C, java_util_zip_CRC32C, updateDirectByteBuffer_C_name, updateByteBuffer_signature, F_S) \
+   do_name(    updateDirectByteBuffer_C_name,                     "updateDirectByteBuffer")                             \
+                                                                                                                        \
+   /* support for java.util.zip.Adler32 */                                                                              \
+  do_class(java_util_zip_Adler32,        "java/util/zip/Adler32")                                                       \
+  do_intrinsic(_updateBytesAdler32,       java_util_zip_Adler32,  updateBytes_C_name,  updateBytes_signature,  F_SN)    \
+  do_intrinsic(_updateByteBufferAdler32,  java_util_zip_Adler32,  updateByteBuffer_A_name,  updateByteBuffer_signature,  F_SN) \
+   do_name(     updateByteBuffer_A_name,                          "updateByteBuffer")                                   \
+                                                                                                                        \
+  /* support for UnsafeConstants */                                                                                     \
+  do_class(jdk_internal_misc_UnsafeConstants,      "jdk/internal/misc/UnsafeConstants")                                 \
+                                                                                                                        \
+  /* support for Unsafe */                                                                                              \
+  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;")                 \
+  do_intrinsic(_allocateUninitializedArray, jdk_internal_misc_Unsafe,   allocateUninitializedArray_name, newArray_signature,  F_R) \
+   do_name(     allocateUninitializedArray_name,                        "allocateUninitializedArray0")                           \
+  do_intrinsic(_copyMemory,               jdk_internal_misc_Unsafe,     copyMemory_name, copyMemory_signature,         F_RN)     \
+   do_name(     copyMemory_name,                                        "copyMemory0")                                           \
+   do_signature(copyMemory_signature,                                   "(Ljava/lang/Object;JLjava/lang/Object;JJ)V")            \
+  do_intrinsic(_loadFence,                jdk_internal_misc_Unsafe,     loadFence_name, loadFence_signature,           F_RN)     \
+   do_name(     loadFence_name,                                         "loadFence")                                             \
+   do_alias(    loadFence_signature,                                    void_method_signature)                                   \
+  do_intrinsic(_storeFence,               jdk_internal_misc_Unsafe,     storeFence_name, storeFence_signature,         F_RN)     \
+   do_name(     storeFence_name,                                        "storeFence")                                            \
+   do_alias(    storeFence_signature,                                   void_method_signature)                                   \
+  do_intrinsic(_fullFence,                jdk_internal_misc_Unsafe,     fullFence_name, fullFence_signature,           F_RN)     \
+   do_name(     fullFence_name,                                         "fullFence")                                             \
+   do_alias(    fullFence_signature,                                    void_method_signature)                                   \
+                                                                                                                        \
+  /* Custom branch frequencies profiling support for JSR292 */                                                          \
+  do_class(java_lang_invoke_MethodHandleImpl,               "java/lang/invoke/MethodHandleImpl")                        \
+  do_intrinsic(_profileBoolean, java_lang_invoke_MethodHandleImpl, profileBoolean_name, profileBoolean_signature, F_S)  \
+   do_name(     profileBoolean_name,                             "profileBoolean")                                      \
+   do_signature(profileBoolean_signature,                        "(Z[I)Z")                                              \
+  do_intrinsic(_isCompileConstant, java_lang_invoke_MethodHandleImpl, isCompileConstant_name, isCompileConstant_signature, F_S) \
+   do_name(     isCompileConstant_name,                          "isCompileConstant")                                   \
+   do_alias(    isCompileConstant_signature,                      object_boolean_signature)                             \
+                                                                                                                        \
+  /* unsafe memory references (there are a lot of them...) */                                                           \
+  do_signature(getReference_signature,    "(Ljava/lang/Object;J)Ljava/lang/Object;")                                    \
+  do_signature(putReference_signature,    "(Ljava/lang/Object;JLjava/lang/Object;)V")                                   \
+  do_signature(getBoolean_signature,      "(Ljava/lang/Object;J)Z")                                                     \
+  do_signature(putBoolean_signature,      "(Ljava/lang/Object;JZ)V")                                                    \
+  do_signature(getByte_signature,         "(Ljava/lang/Object;J)B")                                                     \
+  do_signature(putByte_signature,         "(Ljava/lang/Object;JB)V")                                                    \
+  do_signature(getShort_signature,        "(Ljava/lang/Object;J)S")                                                     \
+  do_signature(putShort_signature,        "(Ljava/lang/Object;JS)V")                                                    \
+  do_signature(getChar_signature,         "(Ljava/lang/Object;J)C")                                                     \
+  do_signature(putChar_signature,         "(Ljava/lang/Object;JC)V")                                                    \
+  do_signature(getInt_signature,          "(Ljava/lang/Object;J)I")                                                     \
+  do_signature(putInt_signature,          "(Ljava/lang/Object;JI)V")                                                    \
+  do_signature(getLong_signature,         "(Ljava/lang/Object;J)J")                                                     \
+  do_signature(putLong_signature,         "(Ljava/lang/Object;JJ)V")                                                    \
+  do_signature(getFloat_signature,        "(Ljava/lang/Object;J)F")                                                     \
+  do_signature(putFloat_signature,        "(Ljava/lang/Object;JF)V")                                                    \
+  do_signature(getDouble_signature,       "(Ljava/lang/Object;J)D")                                                     \
+  do_signature(putDouble_signature,       "(Ljava/lang/Object;JD)V")                                                    \
+                                                                                                                        \
+  do_name(getReference_name,"getReference")     do_name(putReference_name,"putReference")                               \
+  do_name(getBoolean_name,"getBoolean")         do_name(putBoolean_name,"putBoolean")                                   \
+  do_name(getByte_name,"getByte")               do_name(putByte_name,"putByte")                                         \
+  do_name(getShort_name,"getShort")             do_name(putShort_name,"putShort")                                       \
+  do_name(getChar_name,"getChar")               do_name(putChar_name,"putChar")                                         \
+  do_name(getInt_name,"getInt")                 do_name(putInt_name,"putInt")                                           \
+  do_name(getLong_name,"getLong")               do_name(putLong_name,"putLong")                                         \
+  do_name(getFloat_name,"getFloat")             do_name(putFloat_name,"putFloat")                                       \
+  do_name(getDouble_name,"getDouble")           do_name(putDouble_name,"putDouble")                                     \
+                                                                                                                        \
+  do_intrinsic(_getReference,       jdk_internal_misc_Unsafe,     getReference_name, getReference_signature,     F_RN)  \
+  do_intrinsic(_getBoolean,         jdk_internal_misc_Unsafe,     getBoolean_name, getBoolean_signature,         F_RN)  \
+  do_intrinsic(_getByte,            jdk_internal_misc_Unsafe,     getByte_name, getByte_signature,               F_RN)  \
+  do_intrinsic(_getShort,           jdk_internal_misc_Unsafe,     getShort_name, getShort_signature,             F_RN)  \
+  do_intrinsic(_getChar,            jdk_internal_misc_Unsafe,     getChar_name, getChar_signature,               F_RN)  \
+  do_intrinsic(_getInt,             jdk_internal_misc_Unsafe,     getInt_name, getInt_signature,                 F_RN)  \
+  do_intrinsic(_getLong,            jdk_internal_misc_Unsafe,     getLong_name, getLong_signature,               F_RN)  \
+  do_intrinsic(_getFloat,           jdk_internal_misc_Unsafe,     getFloat_name, getFloat_signature,             F_RN)  \
+  do_intrinsic(_getDouble,          jdk_internal_misc_Unsafe,     getDouble_name, getDouble_signature,           F_RN)  \
+  do_intrinsic(_putReference,       jdk_internal_misc_Unsafe,     putReference_name, putReference_signature,     F_RN)  \
+  do_intrinsic(_putBoolean,         jdk_internal_misc_Unsafe,     putBoolean_name, putBoolean_signature,         F_RN)  \
+  do_intrinsic(_putByte,            jdk_internal_misc_Unsafe,     putByte_name, putByte_signature,               F_RN)  \
+  do_intrinsic(_putShort,           jdk_internal_misc_Unsafe,     putShort_name, putShort_signature,             F_RN)  \
+  do_intrinsic(_putChar,            jdk_internal_misc_Unsafe,     putChar_name, putChar_signature,               F_RN)  \
+  do_intrinsic(_putInt,             jdk_internal_misc_Unsafe,     putInt_name, putInt_signature,                 F_RN)  \
+  do_intrinsic(_putLong,            jdk_internal_misc_Unsafe,     putLong_name, putLong_signature,               F_RN)  \
+  do_intrinsic(_putFloat,           jdk_internal_misc_Unsafe,     putFloat_name, putFloat_signature,             F_RN)  \
+  do_intrinsic(_putDouble,          jdk_internal_misc_Unsafe,     putDouble_name, putDouble_signature,           F_RN)  \
+                                                                                                                        \
+  do_name(getReferenceVolatile_name,"getReferenceVolatile")   do_name(putReferenceVolatile_name,"putReferenceVolatile") \
+  do_name(getBooleanVolatile_name,"getBooleanVolatile")       do_name(putBooleanVolatile_name,"putBooleanVolatile")     \
+  do_name(getByteVolatile_name,"getByteVolatile")             do_name(putByteVolatile_name,"putByteVolatile")           \
+  do_name(getShortVolatile_name,"getShortVolatile")           do_name(putShortVolatile_name,"putShortVolatile")         \
+  do_name(getCharVolatile_name,"getCharVolatile")             do_name(putCharVolatile_name,"putCharVolatile")           \
+  do_name(getIntVolatile_name,"getIntVolatile")               do_name(putIntVolatile_name,"putIntVolatile")             \
+  do_name(getLongVolatile_name,"getLongVolatile")             do_name(putLongVolatile_name,"putLongVolatile")           \
+  do_name(getFloatVolatile_name,"getFloatVolatile")           do_name(putFloatVolatile_name,"putFloatVolatile")         \
+  do_name(getDoubleVolatile_name,"getDoubleVolatile")         do_name(putDoubleVolatile_name,"putDoubleVolatile")       \
+                                                                                                                        \
+  do_intrinsic(_getReferenceVolatile,     jdk_internal_misc_Unsafe,     getReferenceVolatile_name, getReference_signature, F_RN)  \
+  do_intrinsic(_getBooleanVolatile,       jdk_internal_misc_Unsafe,     getBooleanVolatile_name, getBoolean_signature,     F_RN)  \
+  do_intrinsic(_getByteVolatile,          jdk_internal_misc_Unsafe,     getByteVolatile_name, getByte_signature,           F_RN)  \
+  do_intrinsic(_getShortVolatile,         jdk_internal_misc_Unsafe,     getShortVolatile_name, getShort_signature,         F_RN)  \
+  do_intrinsic(_getCharVolatile,          jdk_internal_misc_Unsafe,     getCharVolatile_name, getChar_signature,           F_RN)  \
+  do_intrinsic(_getIntVolatile,           jdk_internal_misc_Unsafe,     getIntVolatile_name, getInt_signature,             F_RN)  \
+  do_intrinsic(_getLongVolatile,          jdk_internal_misc_Unsafe,     getLongVolatile_name, getLong_signature,           F_RN)  \
+  do_intrinsic(_getFloatVolatile,         jdk_internal_misc_Unsafe,     getFloatVolatile_name, getFloat_signature,         F_RN)  \
+  do_intrinsic(_getDoubleVolatile,        jdk_internal_misc_Unsafe,     getDoubleVolatile_name, getDouble_signature,       F_RN)  \
+  do_intrinsic(_putReferenceVolatile,     jdk_internal_misc_Unsafe,     putReferenceVolatile_name, putReference_signature, F_RN)  \
+  do_intrinsic(_putBooleanVolatile,       jdk_internal_misc_Unsafe,     putBooleanVolatile_name, putBoolean_signature,     F_RN)  \
+  do_intrinsic(_putByteVolatile,          jdk_internal_misc_Unsafe,     putByteVolatile_name, putByte_signature,           F_RN)  \
+  do_intrinsic(_putShortVolatile,         jdk_internal_misc_Unsafe,     putShortVolatile_name, putShort_signature,         F_RN)  \
+  do_intrinsic(_putCharVolatile,          jdk_internal_misc_Unsafe,     putCharVolatile_name, putChar_signature,           F_RN)  \
+  do_intrinsic(_putIntVolatile,           jdk_internal_misc_Unsafe,     putIntVolatile_name, putInt_signature,             F_RN)  \
+  do_intrinsic(_putLongVolatile,          jdk_internal_misc_Unsafe,     putLongVolatile_name, putLong_signature,           F_RN)  \
+  do_intrinsic(_putFloatVolatile,         jdk_internal_misc_Unsafe,     putFloatVolatile_name, putFloat_signature,         F_RN)  \
+  do_intrinsic(_putDoubleVolatile,        jdk_internal_misc_Unsafe,     putDoubleVolatile_name, putDouble_signature,       F_RN)  \
+                                                                                                                        \
+  do_name(getReferenceOpaque_name,"getReferenceOpaque") do_name(putReferenceOpaque_name,"putReferenceOpaque")           \
+  do_name(getBooleanOpaque_name,"getBooleanOpaque")     do_name(putBooleanOpaque_name,"putBooleanOpaque")               \
+  do_name(getByteOpaque_name,"getByteOpaque")           do_name(putByteOpaque_name,"putByteOpaque")                     \
+  do_name(getShortOpaque_name,"getShortOpaque")         do_name(putShortOpaque_name,"putShortOpaque")                   \
+  do_name(getCharOpaque_name,"getCharOpaque")           do_name(putCharOpaque_name,"putCharOpaque")                     \
+  do_name(getIntOpaque_name,"getIntOpaque")             do_name(putIntOpaque_name,"putIntOpaque")                       \
+  do_name(getLongOpaque_name,"getLongOpaque")           do_name(putLongOpaque_name,"putLongOpaque")                     \
+  do_name(getFloatOpaque_name,"getFloatOpaque")         do_name(putFloatOpaque_name,"putFloatOpaque")                   \
+  do_name(getDoubleOpaque_name,"getDoubleOpaque")       do_name(putDoubleOpaque_name,"putDoubleOpaque")                 \
+                                                                                                                        \
+  do_intrinsic(_getReferenceOpaque,       jdk_internal_misc_Unsafe,        getReferenceOpaque_name, getReference_signature, F_R)  \
+  do_intrinsic(_getBooleanOpaque,         jdk_internal_misc_Unsafe,        getBooleanOpaque_name, getBoolean_signature,     F_R)  \
+  do_intrinsic(_getByteOpaque,            jdk_internal_misc_Unsafe,        getByteOpaque_name, getByte_signature,           F_R)  \
+  do_intrinsic(_getShortOpaque,           jdk_internal_misc_Unsafe,        getShortOpaque_name, getShort_signature,         F_R)  \
+  do_intrinsic(_getCharOpaque,            jdk_internal_misc_Unsafe,        getCharOpaque_name, getChar_signature,           F_R)  \
+  do_intrinsic(_getIntOpaque,             jdk_internal_misc_Unsafe,        getIntOpaque_name, getInt_signature,             F_R)  \
+  do_intrinsic(_getLongOpaque,            jdk_internal_misc_Unsafe,        getLongOpaque_name, getLong_signature,           F_R)  \
+  do_intrinsic(_getFloatOpaque,           jdk_internal_misc_Unsafe,        getFloatOpaque_name, getFloat_signature,         F_R)  \
+  do_intrinsic(_getDoubleOpaque,          jdk_internal_misc_Unsafe,        getDoubleOpaque_name, getDouble_signature,       F_R)  \
+  do_intrinsic(_putReferenceOpaque,       jdk_internal_misc_Unsafe,        putReferenceOpaque_name, putReference_signature, F_R)  \
+  do_intrinsic(_putBooleanOpaque,         jdk_internal_misc_Unsafe,        putBooleanOpaque_name, putBoolean_signature,     F_R)  \
+  do_intrinsic(_putByteOpaque,            jdk_internal_misc_Unsafe,        putByteOpaque_name, putByte_signature,           F_R)  \
+  do_intrinsic(_putShortOpaque,           jdk_internal_misc_Unsafe,        putShortOpaque_name, putShort_signature,         F_R)  \
+  do_intrinsic(_putCharOpaque,            jdk_internal_misc_Unsafe,        putCharOpaque_name, putChar_signature,           F_R)  \
+  do_intrinsic(_putIntOpaque,             jdk_internal_misc_Unsafe,        putIntOpaque_name, putInt_signature,             F_R)  \
+  do_intrinsic(_putLongOpaque,            jdk_internal_misc_Unsafe,        putLongOpaque_name, putLong_signature,           F_R)  \
+  do_intrinsic(_putFloatOpaque,           jdk_internal_misc_Unsafe,        putFloatOpaque_name, putFloat_signature,         F_R)  \
+  do_intrinsic(_putDoubleOpaque,          jdk_internal_misc_Unsafe,        putDoubleOpaque_name, putDouble_signature,       F_R)  \
+                                                                                                                        \
+  do_name(getReferenceAcquire_name,  "getReferenceAcquire") do_name(putReferenceRelease_name,  "putReferenceRelease")   \
+  do_name(getBooleanAcquire_name, "getBooleanAcquire")      do_name(putBooleanRelease_name, "putBooleanRelease")        \
+  do_name(getByteAcquire_name,    "getByteAcquire")         do_name(putByteRelease_name,    "putByteRelease")           \
+  do_name(getShortAcquire_name,   "getShortAcquire")        do_name(putShortRelease_name,   "putShortRelease")          \
+  do_name(getCharAcquire_name,    "getCharAcquire")         do_name(putCharRelease_name,    "putCharRelease")           \
+  do_name(getIntAcquire_name,     "getIntAcquire")          do_name(putIntRelease_name,     "putIntRelease")            \
+  do_name(getLongAcquire_name,    "getLongAcquire")         do_name(putLongRelease_name,    "putLongRelease")           \
+  do_name(getFloatAcquire_name,   "getFloatAcquire")        do_name(putFloatRelease_name,   "putFloatRelease")          \
+  do_name(getDoubleAcquire_name,  "getDoubleAcquire")       do_name(putDoubleRelease_name,  "putDoubleRelease")         \
+                                                                                                                        \
+  do_intrinsic(_getReferenceAcquire,     jdk_internal_misc_Unsafe,        getReferenceAcquire_name, getReference_signature, F_R)  \
+  do_intrinsic(_getBooleanAcquire,       jdk_internal_misc_Unsafe,        getBooleanAcquire_name, getBoolean_signature,     F_R)  \
+  do_intrinsic(_getByteAcquire,          jdk_internal_misc_Unsafe,        getByteAcquire_name, getByte_signature,           F_R)  \
+  do_intrinsic(_getShortAcquire,         jdk_internal_misc_Unsafe,        getShortAcquire_name, getShort_signature,         F_R)  \
+  do_intrinsic(_getCharAcquire,          jdk_internal_misc_Unsafe,        getCharAcquire_name, getChar_signature,           F_R)  \
+  do_intrinsic(_getIntAcquire,           jdk_internal_misc_Unsafe,        getIntAcquire_name, getInt_signature,             F_R)  \
+  do_intrinsic(_getLongAcquire,          jdk_internal_misc_Unsafe,        getLongAcquire_name, getLong_signature,           F_R)  \
+  do_intrinsic(_getFloatAcquire,         jdk_internal_misc_Unsafe,        getFloatAcquire_name, getFloat_signature,         F_R)  \
+  do_intrinsic(_getDoubleAcquire,        jdk_internal_misc_Unsafe,        getDoubleAcquire_name, getDouble_signature,       F_R)  \
+  do_intrinsic(_putReferenceRelease,     jdk_internal_misc_Unsafe,        putReferenceRelease_name, putReference_signature, F_R)  \
+  do_intrinsic(_putBooleanRelease,       jdk_internal_misc_Unsafe,        putBooleanRelease_name, putBoolean_signature,     F_R)  \
+  do_intrinsic(_putByteRelease,          jdk_internal_misc_Unsafe,        putByteRelease_name, putByte_signature,           F_R)  \
+  do_intrinsic(_putShortRelease,         jdk_internal_misc_Unsafe,        putShortRelease_name, putShort_signature,         F_R)  \
+  do_intrinsic(_putCharRelease,          jdk_internal_misc_Unsafe,        putCharRelease_name, putChar_signature,           F_R)  \
+  do_intrinsic(_putIntRelease,           jdk_internal_misc_Unsafe,        putIntRelease_name, putInt_signature,             F_R)  \
+  do_intrinsic(_putLongRelease,          jdk_internal_misc_Unsafe,        putLongRelease_name, putLong_signature,           F_R)  \
+  do_intrinsic(_putFloatRelease,         jdk_internal_misc_Unsafe,        putFloatRelease_name, putFloat_signature,         F_R)  \
+  do_intrinsic(_putDoubleRelease,        jdk_internal_misc_Unsafe,        putDoubleRelease_name, putDouble_signature,       F_R)  \
+                                                                                                                        \
+  do_name(getShortUnaligned_name,"getShortUnaligned")     do_name(putShortUnaligned_name,"putShortUnaligned")           \
+  do_name(getCharUnaligned_name,"getCharUnaligned")       do_name(putCharUnaligned_name,"putCharUnaligned")             \
+  do_name(getIntUnaligned_name,"getIntUnaligned")         do_name(putIntUnaligned_name,"putIntUnaligned")               \
+  do_name(getLongUnaligned_name,"getLongUnaligned")       do_name(putLongUnaligned_name,"putLongUnaligned")             \
+                                                                                                                        \
+  do_intrinsic(_getShortUnaligned,         jdk_internal_misc_Unsafe,    getShortUnaligned_name, getShort_signature,     F_R)  \
+  do_intrinsic(_getCharUnaligned,          jdk_internal_misc_Unsafe,    getCharUnaligned_name, getChar_signature,       F_R)  \
+  do_intrinsic(_getIntUnaligned,           jdk_internal_misc_Unsafe,    getIntUnaligned_name, getInt_signature,         F_R)  \
+  do_intrinsic(_getLongUnaligned,          jdk_internal_misc_Unsafe,    getLongUnaligned_name, getLong_signature,       F_R)  \
+  do_intrinsic(_putShortUnaligned,         jdk_internal_misc_Unsafe,    putShortUnaligned_name, putShort_signature,     F_R)  \
+  do_intrinsic(_putCharUnaligned,          jdk_internal_misc_Unsafe,    putCharUnaligned_name, putChar_signature,       F_R)  \
+  do_intrinsic(_putIntUnaligned,           jdk_internal_misc_Unsafe,    putIntUnaligned_name, putInt_signature,         F_R)  \
+  do_intrinsic(_putLongUnaligned,          jdk_internal_misc_Unsafe,    putLongUnaligned_name, putLong_signature,       F_R)  \
+                                                                                                                        \
+  do_signature(compareAndSetReference_signature,      "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z")        \
+  do_signature(compareAndExchangeReference_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") \
+  do_signature(compareAndSetLong_signature,        "(Ljava/lang/Object;JJJ)Z")                                          \
+  do_signature(compareAndExchangeLong_signature,   "(Ljava/lang/Object;JJJ)J")                                          \
+  do_signature(compareAndSetInt_signature,         "(Ljava/lang/Object;JII)Z")                                          \
+  do_signature(compareAndExchangeInt_signature,    "(Ljava/lang/Object;JII)I")                                          \
+  do_signature(compareAndSetByte_signature,        "(Ljava/lang/Object;JBB)Z")                                          \
+  do_signature(compareAndExchangeByte_signature,   "(Ljava/lang/Object;JBB)B")                                          \
+  do_signature(compareAndSetShort_signature,       "(Ljava/lang/Object;JSS)Z")                                          \
+  do_signature(compareAndExchangeShort_signature,  "(Ljava/lang/Object;JSS)S")                                          \
+                                                                                                                        \
+  do_name(compareAndSetReference_name,              "compareAndSetReference")                                           \
+  do_name(compareAndExchangeReference_name,         "compareAndExchangeReference")                                      \
+  do_name(compareAndExchangeReferenceAcquire_name,  "compareAndExchangeReferenceAcquire")                               \
+  do_name(compareAndExchangeReferenceRelease_name,  "compareAndExchangeReferenceRelease")                               \
+  do_name(compareAndSetLong_name,                   "compareAndSetLong")                                                \
+  do_name(compareAndExchangeLong_name,              "compareAndExchangeLong")                                           \
+  do_name(compareAndExchangeLongAcquire_name,       "compareAndExchangeLongAcquire")                                    \
+  do_name(compareAndExchangeLongRelease_name,       "compareAndExchangeLongRelease")                                    \
+  do_name(compareAndSetInt_name,                    "compareAndSetInt")                                                 \
+  do_name(compareAndExchangeInt_name,               "compareAndExchangeInt")                                            \
+  do_name(compareAndExchangeIntAcquire_name,        "compareAndExchangeIntAcquire")                                     \
+  do_name(compareAndExchangeIntRelease_name,        "compareAndExchangeIntRelease")                                     \
+  do_name(compareAndSetByte_name,                   "compareAndSetByte")                                                \
+  do_name(compareAndExchangeByte_name,              "compareAndExchangeByte")                                           \
+  do_name(compareAndExchangeByteAcquire_name,       "compareAndExchangeByteAcquire")                                    \
+  do_name(compareAndExchangeByteRelease_name,       "compareAndExchangeByteRelease")                                    \
+  do_name(compareAndSetShort_name,                  "compareAndSetShort")                                               \
+  do_name(compareAndExchangeShort_name,             "compareAndExchangeShort")                                          \
+  do_name(compareAndExchangeShortAcquire_name,      "compareAndExchangeShortAcquire")                                   \
+  do_name(compareAndExchangeShortRelease_name,      "compareAndExchangeShortRelease")                                   \
+                                                                                                                        \
+  do_name(weakCompareAndSetReferencePlain_name,     "weakCompareAndSetReferencePlain")                                  \
+  do_name(weakCompareAndSetReferenceAcquire_name,   "weakCompareAndSetReferenceAcquire")                                \
+  do_name(weakCompareAndSetReferenceRelease_name,   "weakCompareAndSetReferenceRelease")                                \
+  do_name(weakCompareAndSetReference_name,          "weakCompareAndSetReference")                                       \
+  do_name(weakCompareAndSetLongPlain_name,          "weakCompareAndSetLongPlain")                                       \
+  do_name(weakCompareAndSetLongAcquire_name,        "weakCompareAndSetLongAcquire")                                     \
+  do_name(weakCompareAndSetLongRelease_name,        "weakCompareAndSetLongRelease")                                     \
+  do_name(weakCompareAndSetLong_name,               "weakCompareAndSetLong")                                            \
+  do_name(weakCompareAndSetIntPlain_name,           "weakCompareAndSetIntPlain")                                        \
+  do_name(weakCompareAndSetIntAcquire_name,         "weakCompareAndSetIntAcquire")                                      \
+  do_name(weakCompareAndSetIntRelease_name,         "weakCompareAndSetIntRelease")                                      \
+  do_name(weakCompareAndSetInt_name,                "weakCompareAndSetInt")                                             \
+  do_name(weakCompareAndSetBytePlain_name,          "weakCompareAndSetBytePlain")                                       \
+  do_name(weakCompareAndSetByteAcquire_name,        "weakCompareAndSetByteAcquire")                                     \
+  do_name(weakCompareAndSetByteRelease_name,        "weakCompareAndSetByteRelease")                                     \
+  do_name(weakCompareAndSetByte_name,               "weakCompareAndSetByte")                                            \
+  do_name(weakCompareAndSetShortPlain_name,         "weakCompareAndSetShortPlain")                                      \
+  do_name(weakCompareAndSetShortAcquire_name,       "weakCompareAndSetShortAcquire")                                    \
+  do_name(weakCompareAndSetShortRelease_name,       "weakCompareAndSetShortRelease")                                    \
+  do_name(weakCompareAndSetShort_name,              "weakCompareAndSetShort")                                           \
+                                                                                                                        \
+  do_intrinsic(_compareAndSetReference,              jdk_internal_misc_Unsafe,  compareAndSetReference_name,              compareAndSetReference_signature,      F_RN) \
+  do_intrinsic(_compareAndExchangeReference,         jdk_internal_misc_Unsafe,  compareAndExchangeReference_name,         compareAndExchangeReference_signature, F_RN) \
+  do_intrinsic(_compareAndExchangeReferenceAcquire,  jdk_internal_misc_Unsafe,  compareAndExchangeReferenceAcquire_name,  compareAndExchangeReference_signature, F_R)  \
+  do_intrinsic(_compareAndExchangeReferenceRelease,  jdk_internal_misc_Unsafe,  compareAndExchangeReferenceRelease_name,  compareAndExchangeReference_signature, F_R)  \
+  do_intrinsic(_compareAndSetLong,                jdk_internal_misc_Unsafe,  compareAndSetLong_name,                compareAndSetLong_signature,        F_RN) \
+  do_intrinsic(_compareAndExchangeLong,           jdk_internal_misc_Unsafe,  compareAndExchangeLong_name,           compareAndExchangeLong_signature,   F_RN) \
+  do_intrinsic(_compareAndExchangeLongAcquire,    jdk_internal_misc_Unsafe,  compareAndExchangeLongAcquire_name,    compareAndExchangeLong_signature,   F_R)  \
+  do_intrinsic(_compareAndExchangeLongRelease,    jdk_internal_misc_Unsafe,  compareAndExchangeLongRelease_name,    compareAndExchangeLong_signature,   F_R)  \
+  do_intrinsic(_compareAndSetInt,                 jdk_internal_misc_Unsafe,  compareAndSetInt_name,                 compareAndSetInt_signature,         F_RN) \
+  do_intrinsic(_compareAndExchangeInt,            jdk_internal_misc_Unsafe,  compareAndExchangeInt_name,            compareAndExchangeInt_signature,    F_RN) \
+  do_intrinsic(_compareAndExchangeIntAcquire,     jdk_internal_misc_Unsafe,  compareAndExchangeIntAcquire_name,     compareAndExchangeInt_signature,    F_R)  \
+  do_intrinsic(_compareAndExchangeIntRelease,     jdk_internal_misc_Unsafe,  compareAndExchangeIntRelease_name,     compareAndExchangeInt_signature,    F_R)  \
+  do_intrinsic(_compareAndSetByte,                jdk_internal_misc_Unsafe,  compareAndSetByte_name,                compareAndSetByte_signature,        F_R)  \
+  do_intrinsic(_compareAndExchangeByte,           jdk_internal_misc_Unsafe,  compareAndExchangeByte_name,           compareAndExchangeByte_signature,   F_R)  \
+  do_intrinsic(_compareAndExchangeByteAcquire,    jdk_internal_misc_Unsafe,  compareAndExchangeByteAcquire_name,    compareAndExchangeByte_signature,   F_R)  \
+  do_intrinsic(_compareAndExchangeByteRelease,    jdk_internal_misc_Unsafe,  compareAndExchangeByteRelease_name,    compareAndExchangeByte_signature,   F_R)  \
+  do_intrinsic(_compareAndSetShort,               jdk_internal_misc_Unsafe,  compareAndSetShort_name,               compareAndSetShort_signature,       F_R)  \
+  do_intrinsic(_compareAndExchangeShort,          jdk_internal_misc_Unsafe,  compareAndExchangeShort_name,          compareAndExchangeShort_signature,  F_R)  \
+  do_intrinsic(_compareAndExchangeShortAcquire,   jdk_internal_misc_Unsafe,  compareAndExchangeShortAcquire_name,   compareAndExchangeShort_signature,  F_R)  \
+  do_intrinsic(_compareAndExchangeShortRelease,   jdk_internal_misc_Unsafe,  compareAndExchangeShortRelease_name,   compareAndExchangeShort_signature,  F_R)  \
+                                                                                                                                                             \
+  do_intrinsic(_weakCompareAndSetReferencePlain,  jdk_internal_misc_Unsafe,  weakCompareAndSetReferencePlain_name,     compareAndSetReference_signature,      F_R) \
+  do_intrinsic(_weakCompareAndSetReferenceAcquire,jdk_internal_misc_Unsafe,  weakCompareAndSetReferenceAcquire_name,   compareAndSetReference_signature,      F_R) \
+  do_intrinsic(_weakCompareAndSetReferenceRelease,jdk_internal_misc_Unsafe,  weakCompareAndSetReferenceRelease_name,   compareAndSetReference_signature,      F_R) \
+  do_intrinsic(_weakCompareAndSetReference,       jdk_internal_misc_Unsafe,  weakCompareAndSetReference_name,          compareAndSetReference_signature,      F_R) \
+  do_intrinsic(_weakCompareAndSetLongPlain,       jdk_internal_misc_Unsafe,  weakCompareAndSetLongPlain_name,       compareAndSetLong_signature,        F_R) \
+  do_intrinsic(_weakCompareAndSetLongAcquire,     jdk_internal_misc_Unsafe,  weakCompareAndSetLongAcquire_name,     compareAndSetLong_signature,        F_R) \
+  do_intrinsic(_weakCompareAndSetLongRelease,     jdk_internal_misc_Unsafe,  weakCompareAndSetLongRelease_name,     compareAndSetLong_signature,        F_R) \
+  do_intrinsic(_weakCompareAndSetLong,            jdk_internal_misc_Unsafe,  weakCompareAndSetLong_name,            compareAndSetLong_signature,        F_R) \
+  do_intrinsic(_weakCompareAndSetIntPlain,        jdk_internal_misc_Unsafe,  weakCompareAndSetIntPlain_name,        compareAndSetInt_signature,         F_R) \
+  do_intrinsic(_weakCompareAndSetIntAcquire,      jdk_internal_misc_Unsafe,  weakCompareAndSetIntAcquire_name,      compareAndSetInt_signature,         F_R) \
+  do_intrinsic(_weakCompareAndSetIntRelease,      jdk_internal_misc_Unsafe,  weakCompareAndSetIntRelease_name,      compareAndSetInt_signature,         F_R) \
+  do_intrinsic(_weakCompareAndSetInt,             jdk_internal_misc_Unsafe,  weakCompareAndSetInt_name,             compareAndSetInt_signature,         F_R) \
+  do_intrinsic(_weakCompareAndSetBytePlain,       jdk_internal_misc_Unsafe,  weakCompareAndSetBytePlain_name,       compareAndSetByte_signature,        F_R) \
+  do_intrinsic(_weakCompareAndSetByteAcquire,     jdk_internal_misc_Unsafe,  weakCompareAndSetByteAcquire_name,     compareAndSetByte_signature,        F_R) \
+  do_intrinsic(_weakCompareAndSetByteRelease,     jdk_internal_misc_Unsafe,  weakCompareAndSetByteRelease_name,     compareAndSetByte_signature,        F_R) \
+  do_intrinsic(_weakCompareAndSetByte,            jdk_internal_misc_Unsafe,  weakCompareAndSetByte_name,            compareAndSetByte_signature,        F_R) \
+  do_intrinsic(_weakCompareAndSetShortPlain,      jdk_internal_misc_Unsafe,  weakCompareAndSetShortPlain_name,      compareAndSetShort_signature,       F_R) \
+  do_intrinsic(_weakCompareAndSetShortAcquire,    jdk_internal_misc_Unsafe,  weakCompareAndSetShortAcquire_name,    compareAndSetShort_signature,       F_R) \
+  do_intrinsic(_weakCompareAndSetShortRelease,    jdk_internal_misc_Unsafe,  weakCompareAndSetShortRelease_name,    compareAndSetShort_signature,       F_R) \
+  do_intrinsic(_weakCompareAndSetShort,           jdk_internal_misc_Unsafe,  weakCompareAndSetShort_name,           compareAndSetShort_signature,       F_R) \
+                           \
+  do_intrinsic(_getAndAddInt,             jdk_internal_misc_Unsafe,     getAndAddInt_name, getAndAddInt_signature, F_R)       \
+   do_name(     getAndAddInt_name,                                      "getAndAddInt")                                       \
+   do_signature(getAndAddInt_signature,                                 "(Ljava/lang/Object;JI)I" )                           \
+  do_intrinsic(_getAndAddLong,            jdk_internal_misc_Unsafe,     getAndAddLong_name, getAndAddLong_signature, F_R)     \
+   do_name(     getAndAddLong_name,                                     "getAndAddLong")                                      \
+   do_signature(getAndAddLong_signature,                                "(Ljava/lang/Object;JJ)J" )                           \
+  do_intrinsic(_getAndAddByte,            jdk_internal_misc_Unsafe,     getAndAddByte_name, getAndAddByte_signature, F_R)     \
+   do_name(     getAndAddByte_name,                                     "getAndAddByte")                                      \
+   do_signature(getAndAddByte_signature,                                "(Ljava/lang/Object;JB)B" )                           \
+  do_intrinsic(_getAndAddShort,           jdk_internal_misc_Unsafe,     getAndAddShort_name, getAndAddShort_signature, F_R)   \
+   do_name(     getAndAddShort_name,                                    "getAndAddShort")                                     \
+   do_signature(getAndAddShort_signature,                               "(Ljava/lang/Object;JS)S" )                           \
+  do_intrinsic(_getAndSetInt,             jdk_internal_misc_Unsafe,     getAndSetInt_name, getAndSetInt_signature, F_R)       \
+   do_name(     getAndSetInt_name,                                      "getAndSetInt")                                       \
+   do_alias(    getAndSetInt_signature,                                 /*"(Ljava/lang/Object;JI)I"*/ getAndAddInt_signature)   \
+  do_intrinsic(_getAndSetLong,            jdk_internal_misc_Unsafe,     getAndSetLong_name, getAndSetLong_signature, F_R)     \
+   do_name(     getAndSetLong_name,                                     "getAndSetLong")                                      \
+   do_alias(    getAndSetLong_signature,                                /*"(Ljava/lang/Object;JJ)J"*/ getAndAddLong_signature)  \
+  do_intrinsic(_getAndSetByte,            jdk_internal_misc_Unsafe,     getAndSetByte_name, getAndSetByte_signature, F_R)     \
+   do_name(     getAndSetByte_name,                                     "getAndSetByte")                                      \
+   do_alias(    getAndSetByte_signature,                                /*"(Ljava/lang/Object;JB)B"*/ getAndAddByte_signature)  \
+  do_intrinsic(_getAndSetShort,           jdk_internal_misc_Unsafe,     getAndSetShort_name, getAndSetShort_signature, F_R)   \
+   do_name(     getAndSetShort_name,                                    "getAndSetShort")                                     \
+   do_alias(    getAndSetShort_signature,                               /*"(Ljava/lang/Object;JS)S"*/ getAndAddShort_signature) \
+  do_intrinsic(_getAndSetReference,       jdk_internal_misc_Unsafe,     getAndSetReference_name, getAndSetReference_signature, F_R) \
+   do_name(     getAndSetReference_name,                                "getAndSetReference")                                  \
+   do_signature(getAndSetReference_signature,                           "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \
+                                                                                                                               \
+   /* (2) Bytecode intrinsics                                                                        */                        \
+                                                                                                                               \
+  do_intrinsic(_park,                     jdk_internal_misc_Unsafe,     park_name, park_signature,                     F_R)    \
+   do_name(     park_name,                                              "park")                                                \
+   do_signature(park_signature,                                         "(ZJ)V")                                               \
+  do_intrinsic(_unpark,                   jdk_internal_misc_Unsafe,     unpark_name, unpark_signature,                 F_R)    \
+   do_name(     unpark_name,                                            "unpark")                                              \
+   do_alias(    unpark_signature,                                       /*(LObject;)V*/ object_void_signature)                 \
+                                                                                                                               \
+  do_intrinsic(_StringBuilder_void,   java_lang_StringBuilder, object_initializer_name, void_method_signature,     F_R)   \
+  do_intrinsic(_StringBuilder_int,    java_lang_StringBuilder, object_initializer_name, int_void_signature,        F_R)   \
+  do_intrinsic(_StringBuilder_String, java_lang_StringBuilder, object_initializer_name, string_void_signature,     F_R)   \
+                                                                                                                          \
+  do_intrinsic(_StringBuilder_append_char,   java_lang_StringBuilder, append_name, char_StringBuilder_signature,   F_R)   \
+  do_intrinsic(_StringBuilder_append_int,    java_lang_StringBuilder, append_name, int_StringBuilder_signature,    F_R)   \
+  do_intrinsic(_StringBuilder_append_String, java_lang_StringBuilder, append_name, String_StringBuilder_signature, F_R)   \
+                                                                                                                          \
+  do_intrinsic(_StringBuilder_toString, java_lang_StringBuilder, toString_name, void_string_signature,             F_R)   \
+                                                                                                                          \
+  do_intrinsic(_StringBuffer_void,   java_lang_StringBuffer, object_initializer_name, void_method_signature,       F_R)   \
+  do_intrinsic(_StringBuffer_int,    java_lang_StringBuffer, object_initializer_name, int_void_signature,          F_R)   \
+  do_intrinsic(_StringBuffer_String, java_lang_StringBuffer, object_initializer_name, string_void_signature,       F_R)   \
+                                                                                                                          \
+  do_intrinsic(_StringBuffer_append_char,   java_lang_StringBuffer, append_name, char_StringBuffer_signature,      F_Y)   \
+  do_intrinsic(_StringBuffer_append_int,    java_lang_StringBuffer, append_name, int_StringBuffer_signature,       F_Y)   \
+  do_intrinsic(_StringBuffer_append_String, java_lang_StringBuffer, append_name, String_StringBuffer_signature,    F_Y)   \
+                                                                                                                          \
+  do_intrinsic(_StringBuffer_toString,  java_lang_StringBuffer, toString_name, void_string_signature,              F_Y)   \
+                                                                                                                          \
+  do_intrinsic(_Integer_toString,      java_lang_Integer, toString_name, int_String_signature,                     F_S)   \
+                                                                                                                          \
+  do_intrinsic(_String_String, java_lang_String, object_initializer_name, string_void_signature,                   F_R)   \
+                                                                                                                          \
+  do_intrinsic(_Object_init,              java_lang_Object, object_initializer_name, void_method_signature,        F_R)   \
+  /*    (symbol object_initializer_name defined above) */                                                                 \
+                                                                                                                          \
+  do_intrinsic(_invoke,                   java_lang_reflect_Method, invoke_name, object_object_array_object_signature, F_R) \
+  /*   (symbols invoke_name and invoke_signature defined above) */                                                      \
+  /* the polymorphic MH intrinsics must be in compact order, with _invokeGeneric first and _linkToInterface last */     \
+  do_intrinsic(_invokeGeneric,            java_lang_invoke_MethodHandle, invoke_name,           star_name, F_RN)        \
+  do_intrinsic(_invokeBasic,              java_lang_invoke_MethodHandle, invokeBasic_name,      star_name, F_RN)        \
+  do_intrinsic(_linkToVirtual,            java_lang_invoke_MethodHandle, linkToVirtual_name,    star_name, F_SN)        \
+  do_intrinsic(_linkToStatic,             java_lang_invoke_MethodHandle, linkToStatic_name,     star_name, F_SN)        \
+  do_intrinsic(_linkToSpecial,            java_lang_invoke_MethodHandle, linkToSpecial_name,    star_name, F_SN)        \
+  do_intrinsic(_linkToInterface,          java_lang_invoke_MethodHandle, linkToInterface_name,  star_name, F_SN)        \
+  /* special marker for bytecode generated for the JVM from a LambdaForm: */                                            \
+  do_intrinsic(_compiledLambdaForm,       java_lang_invoke_MethodHandle, compiledLambdaForm_name, star_name, F_RN)      \
+                                                                                                                        \
+  /* unboxing methods: */                                                                                               \
+  do_intrinsic(_booleanValue,             java_lang_Boolean,      booleanValue_name, void_boolean_signature, F_R)       \
+   do_name(     booleanValue_name,       "booleanValue")                                                                \
+  do_intrinsic(_byteValue,                java_lang_Byte,         byteValue_name, void_byte_signature, F_R)             \
+   do_name(     byteValue_name,          "byteValue")                                                                   \
+  do_intrinsic(_charValue,                java_lang_Character,    charValue_name, void_char_signature, F_R)             \
+   do_name(     charValue_name,          "charValue")                                                                   \
+  do_intrinsic(_shortValue,               java_lang_Short,        shortValue_name, void_short_signature, F_R)           \
+   do_name(     shortValue_name,         "shortValue")                                                                  \
+  do_intrinsic(_intValue,                 java_lang_Integer,      intValue_name, void_int_signature, F_R)               \
+   do_name(     intValue_name,           "intValue")                                                                    \
+  do_intrinsic(_longValue,                java_lang_Long,         longValue_name, void_long_signature, F_R)             \
+   do_name(     longValue_name,          "longValue")                                                                   \
+  do_intrinsic(_floatValue,               java_lang_Float,        floatValue_name, void_float_signature, F_R)           \
+   do_name(     floatValue_name,         "floatValue")                                                                  \
+  do_intrinsic(_doubleValue,              java_lang_Double,       doubleValue_name, void_double_signature, F_R)         \
+   do_name(     doubleValue_name,        "doubleValue")                                                                 \
+                                                                                                                        \
+  /* boxing methods: */                                                                                                 \
+   do_name(    valueOf_name,              "valueOf")                                                                    \
+  do_intrinsic(_Boolean_valueOf,          java_lang_Boolean,      valueOf_name, Boolean_valueOf_signature, F_S)         \
+   do_name(     Boolean_valueOf_signature,                       "(Z)Ljava/lang/Boolean;")                              \
+  do_intrinsic(_Byte_valueOf,             java_lang_Byte,         valueOf_name, Byte_valueOf_signature, F_S)            \
+   do_name(     Byte_valueOf_signature,                          "(B)Ljava/lang/Byte;")                                 \
+  do_intrinsic(_Character_valueOf,        java_lang_Character,    valueOf_name, Character_valueOf_signature, F_S)       \
+   do_name(     Character_valueOf_signature,                     "(C)Ljava/lang/Character;")                            \
+  do_intrinsic(_Short_valueOf,            java_lang_Short,        valueOf_name, Short_valueOf_signature, F_S)           \
+   do_name(     Short_valueOf_signature,                         "(S)Ljava/lang/Short;")                                \
+  do_intrinsic(_Integer_valueOf,          java_lang_Integer,      valueOf_name, Integer_valueOf_signature, F_S)         \
+   do_name(     Integer_valueOf_signature,                       "(I)Ljava/lang/Integer;")                              \
+  do_intrinsic(_Long_valueOf,             java_lang_Long,         valueOf_name, Long_valueOf_signature, F_S)            \
+   do_name(     Long_valueOf_signature,                          "(J)Ljava/lang/Long;")                                 \
+  do_intrinsic(_Float_valueOf,            java_lang_Float,        valueOf_name, Float_valueOf_signature, F_S)           \
+   do_name(     Float_valueOf_signature,                         "(F)Ljava/lang/Float;")                                \
+  do_intrinsic(_Double_valueOf,           java_lang_Double,       valueOf_name, Double_valueOf_signature, F_S)          \
+   do_name(     Double_valueOf_signature,                        "(D)Ljava/lang/Double;")                               \
+                                                                                                                        \
+  /* forEachRemaining */                                                                             \
+  do_intrinsic(_forEachRemaining, java_util_stream_StreamsRangeIntSpliterator, forEachRemaining_name, forEachRemaining_signature, F_R) \
+   do_name(     forEachRemaining_name,    "forEachRemaining")                                                           \
+   do_name(     forEachRemaining_signature,                      "(Ljava/util/function/IntConsumer;)V")                 \
+
+    /*end*/
+
+#endif // SHARE_CLASSFILE_VMINTRINSICS_HPP
diff --git a/src/hotspot/share/classfile/vmSymbols.cpp b/src/hotspot/share/classfile/vmSymbols.cpp
index ef6dbdc781c..cb02bc5be3b 100644
--- a/src/hotspot/share/classfile/vmSymbols.cpp
+++ b/src/hotspot/share/classfile/vmSymbols.cpp
@@ -293,822 +293,3 @@ vmSymbols::SID vmSymbols::find_sid(const char* symbol_name) {
   if (symbol == NULL)  return NO_SID;
   return find_sid(symbol);
 }
-
-static vmIntrinsics::ID wrapper_intrinsic(BasicType type, bool unboxing) {
-#define TYPE2(type, unboxing) ((int)(type)*2 + ((unboxing) ? 1 : 0))
-  switch (TYPE2(type, unboxing)) {
-#define BASIC_TYPE_CASE(type, box, unbox) \
-    case TYPE2(type, false):  return vmIntrinsics::box; \
-    case TYPE2(type, true):   return vmIntrinsics::unbox
-    BASIC_TYPE_CASE(T_BOOLEAN, _Boolean_valueOf,   _booleanValue);
-    BASIC_TYPE_CASE(T_BYTE,    _Byte_valueOf,      _byteValue);
-    BASIC_TYPE_CASE(T_CHAR,    _Character_valueOf, _charValue);
-    BASIC_TYPE_CASE(T_SHORT,   _Short_valueOf,     _shortValue);
-    BASIC_TYPE_CASE(T_INT,     _Integer_valueOf,   _intValue);
-    BASIC_TYPE_CASE(T_LONG,    _Long_valueOf,      _longValue);
-    BASIC_TYPE_CASE(T_FLOAT,   _Float_valueOf,     _floatValue);
-    BASIC_TYPE_CASE(T_DOUBLE,  _Double_valueOf,    _doubleValue);
-#undef BASIC_TYPE_CASE
-  }
-#undef TYPE2
-  return vmIntrinsics::_none;
-}
-
-vmIntrinsics::ID vmIntrinsics::for_boxing(BasicType type) {
-  return wrapper_intrinsic(type, false);
-}
-vmIntrinsics::ID vmIntrinsics::for_unboxing(BasicType type) {
-  return wrapper_intrinsic(type, true);
-}
-
-vmIntrinsics::ID vmIntrinsics::for_raw_conversion(BasicType src, BasicType dest) {
-#define SRC_DEST(s,d) (((int)(s) << 4) + (int)(d))
-  switch (SRC_DEST(src, dest)) {
-  case SRC_DEST(T_INT, T_FLOAT):   return vmIntrinsics::_intBitsToFloat;
-  case SRC_DEST(T_FLOAT, T_INT):   return vmIntrinsics::_floatToRawIntBits;
-
-  case SRC_DEST(T_LONG, T_DOUBLE): return vmIntrinsics::_longBitsToDouble;
-  case SRC_DEST(T_DOUBLE, T_LONG): return vmIntrinsics::_doubleToRawLongBits;
-  }
-#undef SRC_DEST
-
-  return vmIntrinsics::_none;
-}
-
-bool vmIntrinsics::preserves_state(vmIntrinsics::ID id) {
-  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
-  switch(id) {
-#ifdef JFR_HAVE_INTRINSICS
-  case vmIntrinsics::_counterTime:
-#endif
-  case vmIntrinsics::_currentTimeMillis:
-  case vmIntrinsics::_nanoTime:
-  case vmIntrinsics::_floatToRawIntBits:
-  case vmIntrinsics::_intBitsToFloat:
-  case vmIntrinsics::_doubleToRawLongBits:
-  case vmIntrinsics::_longBitsToDouble:
-  case vmIntrinsics::_getClass:
-  case vmIntrinsics::_isInstance:
-  case vmIntrinsics::_currentThread:
-  case vmIntrinsics::_dabs:
-  case vmIntrinsics::_fabs:
-  case vmIntrinsics::_iabs:
-  case vmIntrinsics::_labs:
-  case vmIntrinsics::_dsqrt:
-  case vmIntrinsics::_dsin:
-  case vmIntrinsics::_dcos:
-  case vmIntrinsics::_dtan:
-  case vmIntrinsics::_dlog:
-  case vmIntrinsics::_dlog10:
-  case vmIntrinsics::_dexp:
-  case vmIntrinsics::_dpow:
-  case vmIntrinsics::_checkIndex:
-  case vmIntrinsics::_Reference_get:
-  case vmIntrinsics::_updateCRC32:
-  case vmIntrinsics::_updateBytesCRC32:
-  case vmIntrinsics::_updateByteBufferCRC32:
-  case vmIntrinsics::_vectorizedMismatch:
-  case vmIntrinsics::_fmaD:
-  case vmIntrinsics::_fmaF:
-  case vmIntrinsics::_isDigit:
-  case vmIntrinsics::_isLowerCase:
-  case vmIntrinsics::_isUpperCase:
-  case vmIntrinsics::_isWhitespace:
-    return true;
-  default:
-    return false;
-  }
-}
-
-bool vmIntrinsics::can_trap(vmIntrinsics::ID id) {
-  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
-  switch(id) {
-#ifdef JFR_HAVE_INTRINSICS
-  case vmIntrinsics::_counterTime:
-  case vmIntrinsics::_getClassId:
-#endif
-  case vmIntrinsics::_currentTimeMillis:
-  case vmIntrinsics::_nanoTime:
-  case vmIntrinsics::_floatToRawIntBits:
-  case vmIntrinsics::_intBitsToFloat:
-  case vmIntrinsics::_doubleToRawLongBits:
-  case vmIntrinsics::_longBitsToDouble:
-  case vmIntrinsics::_currentThread:
-  case vmIntrinsics::_dabs:
-  case vmIntrinsics::_fabs:
-  case vmIntrinsics::_iabs:
-  case vmIntrinsics::_labs:
-  case vmIntrinsics::_dsqrt:
-  case vmIntrinsics::_dsin:
-  case vmIntrinsics::_dcos:
-  case vmIntrinsics::_dtan:
-  case vmIntrinsics::_dlog:
-  case vmIntrinsics::_dlog10:
-  case vmIntrinsics::_dexp:
-  case vmIntrinsics::_dpow:
-  case vmIntrinsics::_updateCRC32:
-  case vmIntrinsics::_updateBytesCRC32:
-  case vmIntrinsics::_updateByteBufferCRC32:
-  case vmIntrinsics::_vectorizedMismatch:
-  case vmIntrinsics::_fmaD:
-  case vmIntrinsics::_fmaF:
-    return false;
-  default:
-    return true;
-  }
-}
-
-// Some intrinsics produce different results if they are not pinned
-bool vmIntrinsics::should_be_pinned(vmIntrinsics::ID id) {
-  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
-  switch(id) {
-#ifdef JFR_HAVE_INTRINSICS
-  case vmIntrinsics::_counterTime:
-#endif
-  case vmIntrinsics::_currentTimeMillis:
-  case vmIntrinsics::_nanoTime:
-    return true;
-  default:
-    return false;
-  }
-}
-
-bool vmIntrinsics::does_virtual_dispatch(vmIntrinsics::ID id) {
-  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
-  switch(id) {
-  case vmIntrinsics::_hashCode:
-  case vmIntrinsics::_clone:
-    return true;
-    break;
-  default:
-    return false;
-  }
-}
-
-int vmIntrinsics::predicates_needed(vmIntrinsics::ID id) {
-  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
-  switch (id) {
-  case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
-  case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
-  case vmIntrinsics::_electronicCodeBook_encryptAESCrypt:
-  case vmIntrinsics::_electronicCodeBook_decryptAESCrypt:
-  case vmIntrinsics::_counterMode_AESCrypt:
-    return 1;
-  case vmIntrinsics::_digestBase_implCompressMB:
-    return 4;
-  default:
-    return 0;
-  }
-}
-
-bool vmIntrinsics::disabled_by_jvm_flags(vmIntrinsics::ID id) {
-  assert(id != vmIntrinsics::_none, "must be a VM intrinsic");
-
-  // -XX:-InlineNatives disables nearly all intrinsics except the ones listed in
-  // the following switch statement.
-  if (!InlineNatives) {
-    switch (id) {
-    case vmIntrinsics::_indexOfL:
-    case vmIntrinsics::_indexOfU:
-    case vmIntrinsics::_indexOfUL:
-    case vmIntrinsics::_indexOfIL:
-    case vmIntrinsics::_indexOfIU:
-    case vmIntrinsics::_indexOfIUL:
-    case vmIntrinsics::_indexOfU_char:
-    case vmIntrinsics::_compareToL:
-    case vmIntrinsics::_compareToU:
-    case vmIntrinsics::_compareToLU:
-    case vmIntrinsics::_compareToUL:
-    case vmIntrinsics::_equalsL:
-    case vmIntrinsics::_equalsU:
-    case vmIntrinsics::_equalsC:
-    case vmIntrinsics::_getCharStringU:
-    case vmIntrinsics::_putCharStringU:
-    case vmIntrinsics::_compressStringC:
-    case vmIntrinsics::_compressStringB:
-    case vmIntrinsics::_inflateStringC:
-    case vmIntrinsics::_inflateStringB:
-    case vmIntrinsics::_getAndAddInt:
-    case vmIntrinsics::_getAndAddLong:
-    case vmIntrinsics::_getAndSetInt:
-    case vmIntrinsics::_getAndSetLong:
-    case vmIntrinsics::_getAndSetReference:
-    case vmIntrinsics::_loadFence:
-    case vmIntrinsics::_storeFence:
-    case vmIntrinsics::_fullFence:
-    case vmIntrinsics::_hasNegatives:
-    case vmIntrinsics::_Reference_get:
-      break;
-    default:
-      return true;
-    }
-  }
-
-  switch (id) {
-  case vmIntrinsics::_isInstance:
-  case vmIntrinsics::_isAssignableFrom:
-  case vmIntrinsics::_getModifiers:
-  case vmIntrinsics::_isInterface:
-  case vmIntrinsics::_isArray:
-  case vmIntrinsics::_isPrimitive:
-  case vmIntrinsics::_isHidden:
-  case vmIntrinsics::_getSuperclass:
-  case vmIntrinsics::_Class_cast:
-  case vmIntrinsics::_getLength:
-  case vmIntrinsics::_newArray:
-  case vmIntrinsics::_getClass:
-    if (!InlineClassNatives) return true;
-    break;
-  case vmIntrinsics::_currentThread:
-    if (!InlineThreadNatives) return true;
-    break;
-  case vmIntrinsics::_floatToRawIntBits:
-  case vmIntrinsics::_intBitsToFloat:
-  case vmIntrinsics::_doubleToRawLongBits:
-  case vmIntrinsics::_longBitsToDouble:
-  case vmIntrinsics::_ceil:
-  case vmIntrinsics::_floor:
-  case vmIntrinsics::_rint:
-  case vmIntrinsics::_dabs:
-  case vmIntrinsics::_fabs:
-  case vmIntrinsics::_iabs:
-  case vmIntrinsics::_labs:
-  case vmIntrinsics::_dsqrt:
-  case vmIntrinsics::_dsin:
-  case vmIntrinsics::_dcos:
-  case vmIntrinsics::_dtan:
-  case vmIntrinsics::_dlog:
-  case vmIntrinsics::_dexp:
-  case vmIntrinsics::_dpow:
-  case vmIntrinsics::_dlog10:
-  case vmIntrinsics::_datan2:
-  case vmIntrinsics::_min:
-  case vmIntrinsics::_max:
-  case vmIntrinsics::_floatToIntBits:
-  case vmIntrinsics::_doubleToLongBits:
-  case vmIntrinsics::_maxF:
-  case vmIntrinsics::_minF:
-  case vmIntrinsics::_maxD:
-  case vmIntrinsics::_minD:
-    if (!InlineMathNatives) return true;
-    break;
-  case vmIntrinsics::_fmaD:
-  case vmIntrinsics::_fmaF:
-    if (!InlineMathNatives || !UseFMA) return true;
-    break;
-  case vmIntrinsics::_arraycopy:
-    if (!InlineArrayCopy) return true;
-    break;
-  case vmIntrinsics::_updateCRC32:
-  case vmIntrinsics::_updateBytesCRC32:
-  case vmIntrinsics::_updateByteBufferCRC32:
-    if (!UseCRC32Intrinsics) return true;
-    break;
-  case vmIntrinsics::_getReference:
-  case vmIntrinsics::_getBoolean:
-  case vmIntrinsics::_getByte:
-  case vmIntrinsics::_getShort:
-  case vmIntrinsics::_getChar:
-  case vmIntrinsics::_getInt:
-  case vmIntrinsics::_getLong:
-  case vmIntrinsics::_getFloat:
-  case vmIntrinsics::_getDouble:
-  case vmIntrinsics::_putReference:
-  case vmIntrinsics::_putBoolean:
-  case vmIntrinsics::_putByte:
-  case vmIntrinsics::_putShort:
-  case vmIntrinsics::_putChar:
-  case vmIntrinsics::_putInt:
-  case vmIntrinsics::_putLong:
-  case vmIntrinsics::_putFloat:
-  case vmIntrinsics::_putDouble:
-  case vmIntrinsics::_getReferenceVolatile:
-  case vmIntrinsics::_getBooleanVolatile:
-  case vmIntrinsics::_getByteVolatile:
-  case vmIntrinsics::_getShortVolatile:
-  case vmIntrinsics::_getCharVolatile:
-  case vmIntrinsics::_getIntVolatile:
-  case vmIntrinsics::_getLongVolatile:
-  case vmIntrinsics::_getFloatVolatile:
-  case vmIntrinsics::_getDoubleVolatile:
-  case vmIntrinsics::_putReferenceVolatile:
-  case vmIntrinsics::_putBooleanVolatile:
-  case vmIntrinsics::_putByteVolatile:
-  case vmIntrinsics::_putShortVolatile:
-  case vmIntrinsics::_putCharVolatile:
-  case vmIntrinsics::_putIntVolatile:
-  case vmIntrinsics::_putLongVolatile:
-  case vmIntrinsics::_putFloatVolatile:
-  case vmIntrinsics::_putDoubleVolatile:
-  case vmIntrinsics::_getReferenceAcquire:
-  case vmIntrinsics::_getBooleanAcquire:
-  case vmIntrinsics::_getByteAcquire:
-  case vmIntrinsics::_getShortAcquire:
-  case vmIntrinsics::_getCharAcquire:
-  case vmIntrinsics::_getIntAcquire:
-  case vmIntrinsics::_getLongAcquire:
-  case vmIntrinsics::_getFloatAcquire:
-  case vmIntrinsics::_getDoubleAcquire:
-  case vmIntrinsics::_putReferenceRelease:
-  case vmIntrinsics::_putBooleanRelease:
-  case vmIntrinsics::_putByteRelease:
-  case vmIntrinsics::_putShortRelease:
-  case vmIntrinsics::_putCharRelease:
-  case vmIntrinsics::_putIntRelease:
-  case vmIntrinsics::_putLongRelease:
-  case vmIntrinsics::_putFloatRelease:
-  case vmIntrinsics::_putDoubleRelease:
-  case vmIntrinsics::_getReferenceOpaque:
-  case vmIntrinsics::_getBooleanOpaque:
-  case vmIntrinsics::_getByteOpaque:
-  case vmIntrinsics::_getShortOpaque:
-  case vmIntrinsics::_getCharOpaque:
-  case vmIntrinsics::_getIntOpaque:
-  case vmIntrinsics::_getLongOpaque:
-  case vmIntrinsics::_getFloatOpaque:
-  case vmIntrinsics::_getDoubleOpaque:
-  case vmIntrinsics::_putReferenceOpaque:
-  case vmIntrinsics::_putBooleanOpaque:
-  case vmIntrinsics::_putByteOpaque:
-  case vmIntrinsics::_putShortOpaque:
-  case vmIntrinsics::_putCharOpaque:
-  case vmIntrinsics::_putIntOpaque:
-  case vmIntrinsics::_putLongOpaque:
-  case vmIntrinsics::_putFloatOpaque:
-  case vmIntrinsics::_putDoubleOpaque:
-  case vmIntrinsics::_getAndAddInt:
-  case vmIntrinsics::_getAndAddLong:
-  case vmIntrinsics::_getAndSetInt:
-  case vmIntrinsics::_getAndSetLong:
-  case vmIntrinsics::_getAndSetReference:
-  case vmIntrinsics::_loadFence:
-  case vmIntrinsics::_storeFence:
-  case vmIntrinsics::_fullFence:
-  case vmIntrinsics::_compareAndSetLong:
-  case vmIntrinsics::_weakCompareAndSetLong:
-  case vmIntrinsics::_weakCompareAndSetLongPlain:
-  case vmIntrinsics::_weakCompareAndSetLongAcquire:
-  case vmIntrinsics::_weakCompareAndSetLongRelease:
-  case vmIntrinsics::_compareAndSetInt:
-  case vmIntrinsics::_weakCompareAndSetInt:
-  case vmIntrinsics::_weakCompareAndSetIntPlain:
-  case vmIntrinsics::_weakCompareAndSetIntAcquire:
-  case vmIntrinsics::_weakCompareAndSetIntRelease:
-  case vmIntrinsics::_compareAndSetReference:
-  case vmIntrinsics::_weakCompareAndSetReference:
-  case vmIntrinsics::_weakCompareAndSetReferencePlain:
-  case vmIntrinsics::_weakCompareAndSetReferenceAcquire:
-  case vmIntrinsics::_weakCompareAndSetReferenceRelease:
-  case vmIntrinsics::_compareAndExchangeInt:
-  case vmIntrinsics::_compareAndExchangeIntAcquire:
-  case vmIntrinsics::_compareAndExchangeIntRelease:
-  case vmIntrinsics::_compareAndExchangeLong:
-  case vmIntrinsics::_compareAndExchangeLongAcquire:
-  case vmIntrinsics::_compareAndExchangeLongRelease:
-  case vmIntrinsics::_compareAndExchangeReference:
-  case vmIntrinsics::_compareAndExchangeReferenceAcquire:
-  case vmIntrinsics::_compareAndExchangeReferenceRelease:
-    if (!InlineUnsafeOps) return true;
-    break;
-  case vmIntrinsics::_getShortUnaligned:
-  case vmIntrinsics::_getCharUnaligned:
-  case vmIntrinsics::_getIntUnaligned:
-  case vmIntrinsics::_getLongUnaligned:
-  case vmIntrinsics::_putShortUnaligned:
-  case vmIntrinsics::_putCharUnaligned:
-  case vmIntrinsics::_putIntUnaligned:
-  case vmIntrinsics::_putLongUnaligned:
-  case vmIntrinsics::_allocateInstance:
-    if (!InlineUnsafeOps || !UseUnalignedAccesses) return true;
-    break;
-  case vmIntrinsics::_hashCode:
-    if (!InlineObjectHash) return true;
-    break;
-  case vmIntrinsics::_aescrypt_encryptBlock:
-  case vmIntrinsics::_aescrypt_decryptBlock:
-    if (!UseAESIntrinsics) return true;
-    break;
-  case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
-  case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
-    if (!UseAESIntrinsics) return true;
-    break;
-  case vmIntrinsics::_electronicCodeBook_encryptAESCrypt:
-  case vmIntrinsics::_electronicCodeBook_decryptAESCrypt:
-    if (!UseAESIntrinsics) return true;
-    break;
-  case vmIntrinsics::_counterMode_AESCrypt:
-    if (!UseAESCTRIntrinsics) return true;
-    break;
-  case vmIntrinsics::_md5_implCompress:
-    if (!UseMD5Intrinsics) return true;
-    break;
-  case vmIntrinsics::_sha_implCompress:
-    if (!UseSHA1Intrinsics) return true;
-    break;
-  case vmIntrinsics::_sha2_implCompress:
-    if (!UseSHA256Intrinsics) return true;
-    break;
-  case vmIntrinsics::_sha5_implCompress:
-    if (!UseSHA512Intrinsics) return true;
-    break;
-  case vmIntrinsics::_digestBase_implCompressMB:
-    if (!(UseMD5Intrinsics || UseSHA1Intrinsics || UseSHA256Intrinsics || UseSHA512Intrinsics)) return true;
-    break;
-  case vmIntrinsics::_ghash_processBlocks:
-    if (!UseGHASHIntrinsics) return true;
-    break;
-  case vmIntrinsics::_base64_encodeBlock:
-    if (!UseBASE64Intrinsics) return true;
-    break;
-  case vmIntrinsics::_updateBytesCRC32C:
-  case vmIntrinsics::_updateDirectByteBufferCRC32C:
-    if (!UseCRC32CIntrinsics) return true;
-    break;
-  case vmIntrinsics::_vectorizedMismatch:
-    if (!UseVectorizedMismatchIntrinsic) return true;
-    break;
-  case vmIntrinsics::_updateBytesAdler32:
-  case vmIntrinsics::_updateByteBufferAdler32:
-    if (!UseAdler32Intrinsics) return true;
-    break;
-  case vmIntrinsics::_copyMemory:
-    if (!InlineArrayCopy || !InlineUnsafeOps) return true;
-    break;
-#ifdef COMPILER1
-  case vmIntrinsics::_checkIndex:
-    if (!InlineNIOCheckIndex) return true;
-    break;
-#endif // COMPILER1
-#ifdef COMPILER2
-  case vmIntrinsics::_clone:
-  case vmIntrinsics::_copyOf:
-  case vmIntrinsics::_copyOfRange:
-    // These intrinsics use both the objectcopy and the arraycopy
-    // intrinsic mechanism.
-    if (!InlineObjectCopy || !InlineArrayCopy) return true;
-    break;
-  case vmIntrinsics::_compareToL:
-  case vmIntrinsics::_compareToU:
-  case vmIntrinsics::_compareToLU:
-  case vmIntrinsics::_compareToUL:
-    if (!SpecialStringCompareTo) return true;
-    break;
-  case vmIntrinsics::_indexOfL:
-  case vmIntrinsics::_indexOfU:
-  case vmIntrinsics::_indexOfUL:
-  case vmIntrinsics::_indexOfIL:
-  case vmIntrinsics::_indexOfIU:
-  case vmIntrinsics::_indexOfIUL:
-  case vmIntrinsics::_indexOfU_char:
-    if (!SpecialStringIndexOf) return true;
-    break;
-  case vmIntrinsics::_equalsL:
-  case vmIntrinsics::_equalsU:
-    if (!SpecialStringEquals) return true;
-    break;
-  case vmIntrinsics::_equalsB:
-  case vmIntrinsics::_equalsC:
-    if (!SpecialArraysEquals) return true;
-    break;
-  case vmIntrinsics::_encodeISOArray:
-  case vmIntrinsics::_encodeByteISOArray:
-    if (!SpecialEncodeISOArray) return true;
-    break;
-  case vmIntrinsics::_getCallerClass:
-    if (!InlineReflectionGetCallerClass) return true;
-    break;
-  case vmIntrinsics::_multiplyToLen:
-    if (!UseMultiplyToLenIntrinsic) return true;
-    break;
-  case vmIntrinsics::_squareToLen:
-    if (!UseSquareToLenIntrinsic) return true;
-    break;
-  case vmIntrinsics::_mulAdd:
-    if (!UseMulAddIntrinsic) return true;
-    break;
-  case vmIntrinsics::_montgomeryMultiply:
-    if (!UseMontgomeryMultiplyIntrinsic) return true;
-    break;
-  case vmIntrinsics::_montgomerySquare:
-    if (!UseMontgomerySquareIntrinsic) return true;
-    break;
-  case vmIntrinsics::_bigIntegerRightShiftWorker:
-  case vmIntrinsics::_bigIntegerLeftShiftWorker:
-    break;
-  case vmIntrinsics::_addExactI:
-  case vmIntrinsics::_addExactL:
-  case vmIntrinsics::_decrementExactI:
-  case vmIntrinsics::_decrementExactL:
-  case vmIntrinsics::_incrementExactI:
-  case vmIntrinsics::_incrementExactL:
-  case vmIntrinsics::_multiplyExactI:
-  case vmIntrinsics::_multiplyExactL:
-  case vmIntrinsics::_negateExactI:
-  case vmIntrinsics::_negateExactL:
-  case vmIntrinsics::_subtractExactI:
-  case vmIntrinsics::_subtractExactL:
-    if (!UseMathExactIntrinsics || !InlineMathNatives) return true;
-    break;
-  case vmIntrinsics::_isDigit:
-  case vmIntrinsics::_isLowerCase:
-  case vmIntrinsics::_isUpperCase:
-  case vmIntrinsics::_isWhitespace:
-    if (!UseCharacterCompareIntrinsics) return true;
-    break;
-  case vmIntrinsics::_dcopySign:
-  case vmIntrinsics::_fcopySign:
-    if (!InlineMathNatives || !UseCopySignIntrinsic) return true;
-    break;
-  case vmIntrinsics::_dsignum:
-  case vmIntrinsics::_fsignum:
-    if (!InlineMathNatives || !UseSignumIntrinsic) return true;
-    break;
-#endif // COMPILER2
-  default:
-    return false;
-  }
-
-  return false;
-}
-
-#define VM_INTRINSIC_INITIALIZE(id, klass, name, sig, flags) #id "\0"
-static const char* vm_intrinsic_name_bodies =
-  VM_INTRINSICS_DO(VM_INTRINSIC_INITIALIZE,
-                   VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
-
-static const char* vm_intrinsic_name_table[vmIntrinsics::ID_LIMIT];
-static TriBoolArray<vmIntrinsics::ID_LIMIT, int> vm_intrinsic_control_words;
-
-static void init_vm_intrinsic_name_table() {
-  const char** nt = &vm_intrinsic_name_table[0];
-  char* string = (char*) &vm_intrinsic_name_bodies[0];
-  for (int index = vmIntrinsics::FIRST_ID; index < vmIntrinsics::ID_LIMIT; index++) {
-    nt[index] = string;
-    string += strlen(string); // skip string body
-    string += 1;              // skip trailing null
-  }
-  assert(!strcmp(nt[vmIntrinsics::_hashCode], "_hashCode"), "lined up");
-  nt[vmIntrinsics::_none] = "_none";
-}
-
-const char* vmIntrinsics::name_at(vmIntrinsics::ID id) {
-  const char** nt = &vm_intrinsic_name_table[0];
-  if (nt[_none] == NULL) {
-    init_vm_intrinsic_name_table();
-  }
-
-  if ((uint)id < (uint)ID_LIMIT)
-    return vm_intrinsic_name_table[(uint)id];
-  else
-    return "(unknown intrinsic)";
-}
-
-vmIntrinsics::ID vmIntrinsics::find_id(const char* name) {
-  const char** nt = &vm_intrinsic_name_table[0];
-  if (nt[_none] == NULL) {
-    init_vm_intrinsic_name_table();
-  }
-
-  for (int index = FIRST_ID; index < ID_LIMIT; ++index) {
-    if (0 == strcmp(name, nt[index])) {
-      return ID_from(index);
-    }
-  }
-
-  return _none;
-}
-
-bool vmIntrinsics::is_disabled_by_flags(const methodHandle& method) {
-  vmIntrinsics::ID id = method->intrinsic_id();
-  return is_disabled_by_flags(id);
-}
-
-bool vmIntrinsics::is_disabled_by_flags(vmIntrinsics::ID id) {
-  assert(id > _none && id < ID_LIMIT, "must be a VM intrinsic");
-
-  // not initialized yet, process Control/DisableIntrinsic
-  if (vm_intrinsic_control_words[_none].is_default()) {
-    for (ControlIntrinsicIter iter(ControlIntrinsic); *iter != NULL; ++iter) {
-      vmIntrinsics::ID id = vmIntrinsics::find_id(*iter);
-
-      if (id != vmIntrinsics::_none) {
-        vm_intrinsic_control_words[id] = iter.is_enabled() && !disabled_by_jvm_flags(id);
-      }
-    }
-
-    // Order matters, DisableIntrinsic can overwrite ControlIntrinsic
-    for (ControlIntrinsicIter iter(DisableIntrinsic, true/*disable_all*/); *iter != NULL; ++iter) {
-      vmIntrinsics::ID id = vmIntrinsics::find_id(*iter);
-
-      if (id != vmIntrinsics::_none) {
-        vm_intrinsic_control_words[id] = false;
-      }
-    }
-
-    vm_intrinsic_control_words[_none] = true;
-  }
-
-  TriBool b = vm_intrinsic_control_words[id];
-  if (b.is_default()) {
-    // unknown yet, query and cache it
-    b = vm_intrinsic_control_words[id] = !disabled_by_jvm_flags(id);
-  }
-
-  return !b;
-}
-
-// These are flag-matching functions:
-inline bool match_F_R(jshort flags) {
-  const int req = 0;
-  const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
-  return (flags & (req | neg)) == req;
-}
-inline bool match_F_Y(jshort flags) {
-  const int req = JVM_ACC_SYNCHRONIZED;
-  const int neg = JVM_ACC_STATIC;
-  return (flags & (req | neg)) == req;
-}
-inline bool match_F_RN(jshort flags) {
-  const int req = JVM_ACC_NATIVE;
-  const int neg = JVM_ACC_STATIC | JVM_ACC_SYNCHRONIZED;
-  return (flags & (req | neg)) == req;
-}
-inline bool match_F_S(jshort flags) {
-  const int req = JVM_ACC_STATIC;
-  const int neg = JVM_ACC_SYNCHRONIZED;
-  return (flags & (req | neg)) == req;
-}
-inline bool match_F_SN(jshort flags) {
-  const int req = JVM_ACC_STATIC | JVM_ACC_NATIVE;
-  const int neg = JVM_ACC_SYNCHRONIZED;
-  return (flags & (req | neg)) == req;
-}
-inline bool match_F_RNY(jshort flags) {
-  const int req = JVM_ACC_NATIVE | JVM_ACC_SYNCHRONIZED;
-  const int neg = JVM_ACC_STATIC;
-  return (flags & (req | neg)) == req;
-}
-
-// These are for forming case labels:
-#define ID3(x, y, z) (( jlong)(z) +                                  \
-                      ((jlong)(y) <<    vmSymbols::log2_SID_LIMIT) + \
-                      ((jlong)(x) << (2*vmSymbols::log2_SID_LIMIT))  )
-#define SID_ENUM(n) vmSymbols::VM_SYMBOL_ENUM_NAME(n)
-
-vmIntrinsics::ID vmIntrinsics::find_id_impl(vmSymbols::SID holder,
-                                            vmSymbols::SID name,
-                                            vmSymbols::SID sig,
-                                            jshort flags) {
-  assert((int)vmSymbols::SID_LIMIT <= (1<<vmSymbols::log2_SID_LIMIT), "must fit");
-
-  // Let the C compiler build the decision tree.
-
-#define VM_INTRINSIC_CASE(id, klass, name, sig, fcode) \
-  case ID3(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig)): \
-    if (!match_##fcode(flags))  break; \
-    return id;
-
-  switch (ID3(holder, name, sig)) {
-    VM_INTRINSICS_DO(VM_INTRINSIC_CASE,
-                     VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
-  }
-  return vmIntrinsics::_none;
-
-#undef VM_INTRINSIC_CASE
-}
-
-
-const char* vmIntrinsics::short_name_as_C_string(vmIntrinsics::ID id, char* buf, int buflen) {
-  const char* str = name_at(id);
-#ifndef PRODUCT
-  const char* kname = vmSymbols::name_for(class_for(id));
-  const char* mname = vmSymbols::name_for(name_for(id));
-  const char* sname = vmSymbols::name_for(signature_for(id));
-  const char* fname = "";
-  switch (flags_for(id)) {
-  case F_Y:  fname = "synchronized ";  break;
-  case F_RN: fname = "native ";        break;
-  case F_SN: fname = "native static "; break;
-  case F_S:  fname = "static ";        break;
-  case F_RNY:fname = "native synchronized "; break;
-  default:   break;
-  }
-  const char* kptr = strrchr(kname, JVM_SIGNATURE_SLASH);
-  if (kptr != NULL)  kname = kptr + 1;
-  int len = jio_snprintf(buf, buflen, "%s: %s%s.%s%s",
-                         str, fname, kname, mname, sname);
-  if (len < buflen)
-    str = buf;
-#endif //PRODUCT
-  return str;
-}
-
-
-// These are to get information about intrinsics.
-
-#define ID4(x, y, z, f) ((ID3(x, y, z) << vmIntrinsics::log2_FLAG_LIMIT) | (jlong) (f))
-
-static const jlong intrinsic_info_array[vmIntrinsics::ID_LIMIT+1] = {
-#define VM_INTRINSIC_INFO(ignore_id, klass, name, sig, fcode) \
-  ID4(SID_ENUM(klass), SID_ENUM(name), SID_ENUM(sig), vmIntrinsics::fcode),
-
-  0, VM_INTRINSICS_DO(VM_INTRINSIC_INFO,
-                     VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE)
-    0
-#undef VM_INTRINSIC_INFO
-};
-
-inline jlong intrinsic_info(vmIntrinsics::ID id) {
-  return intrinsic_info_array[vmIntrinsics::ID_from((int)id)];
-}
-
-vmSymbols::SID vmIntrinsics::class_for(vmIntrinsics::ID id) {
-  jlong info = intrinsic_info(id);
-  int shift = 2*vmSymbols::log2_SID_LIMIT + log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
-  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1021, "");
-  return vmSymbols::SID( (info >> shift) & mask );
-}
-
-vmSymbols::SID vmIntrinsics::name_for(vmIntrinsics::ID id) {
-  jlong info = intrinsic_info(id);
-  int shift = vmSymbols::log2_SID_LIMIT + log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
-  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1022, "");
-  return vmSymbols::SID( (info >> shift) & mask );
-}
-
-vmSymbols::SID vmIntrinsics::signature_for(vmIntrinsics::ID id) {
-  jlong info = intrinsic_info(id);
-  int shift = log2_FLAG_LIMIT, mask = right_n_bits(vmSymbols::log2_SID_LIMIT);
-  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 1023, "");
-  return vmSymbols::SID( (info >> shift) & mask );
-}
-
-vmIntrinsics::Flags vmIntrinsics::flags_for(vmIntrinsics::ID id) {
-  jlong info = intrinsic_info(id);
-  int shift = 0, mask = right_n_bits(log2_FLAG_LIMIT);
-  assert(((ID4(1021,1022,1023,15) >> shift) & mask) == 15, "");
-  return Flags( (info >> shift) & mask );
-}
-
-
-#ifndef PRODUCT
-// verify_method performs an extra check on a matched intrinsic method
-
-static bool match_method(Method* m, Symbol* n, Symbol* s) {
-  return (m->name() == n &&
-          m->signature() == s);
-}
-
-static vmIntrinsics::ID match_method_with_klass(Method* m, Symbol* mk) {
-#define VM_INTRINSIC_MATCH(id, klassname, namepart, sigpart, flags) \
-  { Symbol* k = vmSymbols::klassname(); \
-    if (mk == k) { \
-      Symbol* n = vmSymbols::namepart(); \
-      Symbol* s = vmSymbols::sigpart(); \
-      if (match_method(m, n, s)) \
-        return vmIntrinsics::id; \
-    } }
-  VM_INTRINSICS_DO(VM_INTRINSIC_MATCH,
-                   VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_SYMBOL_IGNORE, VM_ALIAS_IGNORE);
-  return vmIntrinsics::_none;
-#undef VM_INTRINSIC_MATCH
-}
-
-void vmIntrinsics::verify_method(ID actual_id, Method* m) {
-  Symbol* mk = m->method_holder()->name();
-  ID declared_id = match_method_with_klass(m, mk);
-
-  if (declared_id == actual_id)  return; // success
-
-  if (declared_id == _none && actual_id != _none && mk == vmSymbols::java_lang_StrictMath()) {
-    // Here are a few special cases in StrictMath not declared in vmSymbols.hpp.
-    switch (actual_id) {
-    case _min:
-    case _max:
-    case _dsqrt:
-      declared_id = match_method_with_klass(m, vmSymbols::java_lang_Math());
-      if (declared_id == actual_id)  return; // acceptable alias
-      break;
-    default:
-        break;
-    }
-  }
-
-  const char* declared_name = name_at(declared_id);
-  const char* actual_name   = name_at(actual_id);
-  m = NULL;
-  ttyLocker ttyl;
-  if (xtty != NULL) {
-    xtty->begin_elem("intrinsic_misdeclared actual='%s' declared='%s'",
-                     actual_name, declared_name);
-    xtty->method(m);
-    xtty->end_elem("%s", "");
-  }
-  if (PrintMiscellaneous && (WizardMode || Verbose)) {
-    tty->print_cr("*** misidentified method; %s(%d) should be %s(%d):",
-                  declared_name, declared_id, actual_name, actual_id);
-    m->print_short_name(tty);
-    tty->cr();
-  }
-}
-#endif //PRODUCT
diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp
index 9b02ce02f99..77b9661c301 100644
--- a/src/hotspot/share/classfile/vmSymbols.hpp
+++ b/src/hotspot/share/classfile/vmSymbols.hpp
@@ -30,6 +30,7 @@
 #include "memory/iterator.hpp"
 #include "oops/symbol.hpp"
 #include "utilities/macros.hpp"
+#include "vmIntrinsics.hpp"
 
 
 // The class vmSymbols is a name space for fast lookup of
@@ -130,6 +131,7 @@
   template(java_lang_Record,                          "java/lang/Record")                         \
                                                                                                   \
   template(jdk_internal_loader_NativeLibraries,       "jdk/internal/loader/NativeLibraries")      \
+  template(jdk_internal_loader_BuiltinClassLoader,    "jdk/internal/loader/BuiltinClassLoader")   \
   template(jdk_internal_loader_ClassLoaders_AppClassLoader,      "jdk/internal/loader/ClassLoaders$AppClassLoader")      \
   template(jdk_internal_loader_ClassLoaders_PlatformClassLoader, "jdk/internal/loader/ClassLoaders$PlatformClassLoader") \
                                                                                                   \
@@ -664,858 +666,14 @@
                                                                                                                   \
   /* cds */                                                                                                       \
   template(jdk_internal_loader_ClassLoaders,       "jdk/internal/loader/ClassLoaders")                            \
+  template(java_util_concurrent_ConcurrentHashMap, "java/util/concurrent/ConcurrentHashMap")                      \
+  template(java_util_ArrayList,                    "java/util/ArrayList")                                         \
   template(toFileURL_name,                         "toFileURL")                                                   \
   template(toFileURL_signature,                    "(Ljava/lang/String;)Ljava/net/URL;")                          \
   template(url_void_signature,                     "(Ljava/net/URL;)V")                                           \
                                                                                                                   \
   /*end*/
 
-// Here are all the intrinsics known to the runtime and the CI.
-// Each intrinsic consists of a public enum name (like _hashCode),
-// followed by a specification of its klass, name, and signature:
-//    template(<id>,  <klass>,  <name>, <sig>, <FCODE>)
-//
-// If you add an intrinsic here, you must also define its name
-// and signature as members of the VM symbols.  The VM symbols for
-// the intrinsic name and signature may be defined above.
-//
-// Because the VM_SYMBOLS_DO macro makes reference to VM_INTRINSICS_DO,
-// you can also define an intrinsic's name and/or signature locally to the
-// intrinsic, if this makes sense.  (It often does make sense.)
-//
-// For example:
-//    do_intrinsic(_foo,  java_lang_Object,  foo_name, foo_signature, F_xx)
-//     do_name(     foo_name, "foo")
-//     do_signature(foo_signature, "()F")
-// klass      = vmSymbols::java_lang_Object()
-// name       = vmSymbols::foo_name()
-// signature  = vmSymbols::foo_signature()
-//
-// The name and/or signature might be a "well known" symbol
-// like "equal" or "()I", in which case there will be no local
-// re-definition of the symbol.
-//
-// The do_class, do_name, and do_signature calls are all used for the
-// same purpose:  Define yet another VM symbol.  They could all be merged
-// into a common 'do_symbol' call, but it seems useful to record our
-// intentions here about kinds of symbols (class vs. name vs. signature).
-//
-// The F_xx is one of the Flags enum; see below.
-//
-// for Emacs: (let ((c-backslash-column 120) (c-backslash-max-column 120)) (c-backslash-region (point) (point-max) nil t))
-//
-//
-// There are two types of intrinsic methods: (1) Library intrinsics and (2) bytecode intrinsics.
-//
-// (1) A library intrinsic method may be replaced with hand-crafted assembly code,
-// with hand-crafted compiler IR, or with a combination of the two. The semantics
-// of the replacement code may differ from the semantics of the replaced code.
-//
-// (2) Bytecode intrinsic methods are not replaced by special code, but they are
-// treated in some other special way by the compiler. For example, the compiler
-// may delay inlining for some String-related intrinsic methods (e.g., some methods
-// defined in the StringBuilder and StringBuffer classes, see
-// Compile::should_delay_string_inlining() for more details).
-//
-// Due to the difference between the semantics of an intrinsic method as defined
-// in the (Java) source code and the semantics of the method as defined
-// by the code in the VM, intrinsic methods must be explicitly marked.
-//
-// Intrinsic methods are marked by the jdk.internal.HotSpotIntrinsicCandidate
-// annotation. If CheckIntrinsics is enabled, the VM performs the following
-// checks when a class C is loaded: (1) all intrinsics defined by the VM for
-// class C are present in the loaded class file and are marked;
-// (2) an intrinsic is defined by the VM for all marked methods of class C;
-// (3) check for orphan methods in class C (i.e., methods for which the VM
-// declares an intrinsic but that are not declared for the loaded class C.
-// Check (3) is available only in debug builds.
-//
-// If a mismatch is detected for a method, the VM behaves differently depending
-// on the type of build. A fastdebug build exits and reports an error on a mismatch.
-// A product build will not replace an unmarked library intrinsic method with
-// hand-crafted code, that is, unmarked library intrinsics are treated as ordinary
-// methods in a product build. The special treatment of a bytecode intrinsic method
-// persists even if the method not marked.
-//
-// When adding an intrinsic for a method, please make sure to appropriately
-// annotate the method in the source code. The list below contains all
-// library intrinsics followed by bytecode intrinsics. Please also make sure to
-// add the declaration of the intrinsic to the approriate section of the list.
-#define VM_INTRINSICS_DO(do_intrinsic, do_class, do_name, do_signature, do_alias)                                       \
-  /* (1) Library intrinsics                                                                        */                   \
-  do_intrinsic(_hashCode,                 java_lang_Object,       hashCode_name, void_int_signature,             F_R)   \
-   do_name(     hashCode_name,                                   "hashCode")                                            \
-  do_intrinsic(_getClass,                 java_lang_Object,       getClass_name, void_class_signature,           F_R)   \
-   do_name(     getClass_name,                                   "getClass")                                            \
-  do_intrinsic(_clone,                    java_lang_Object,       clone_name, void_object_signature,             F_R)   \
-   do_name(     clone_name,                                      "clone")                                               \
-  do_intrinsic(_notify,                   java_lang_Object,       notify_name, void_method_signature,            F_R)   \
-   do_name(     notify_name,                                     "notify")                                              \
-  do_intrinsic(_notifyAll,                java_lang_Object,       notifyAll_name, void_method_signature,         F_R)   \
-   do_name(     notifyAll_name,                                  "notifyAll")                                           \
-                                                                                                                        \
-  /* Math & StrictMath intrinsics are defined in terms of just a few signatures: */                                     \
-  do_class(java_lang_Math,                "java/lang/Math")                                                             \
-  do_class(java_lang_StrictMath,          "java/lang/StrictMath")                                                       \
-  do_signature(double2_double_signature,  "(DD)D")                                                                      \
-  do_signature(double3_double_signature,  "(DDD)D")                                                                     \
-  do_signature(float2_float_signature,    "(FF)F")                                                                      \
-  do_signature(float3_float_signature,    "(FFF)F")                                                                     \
-  do_signature(int2_int_signature,        "(II)I")                                                                      \
-  do_signature(long2_long_signature,      "(JJ)J")                                                                      \
-                                                                                                                        \
-  /* here are the math names, all together: */                                                                          \
-  do_name(abs_name,"abs")       do_name(sin_name,"sin")         do_name(cos_name,"cos")                                 \
-  do_name(tan_name,"tan")       do_name(atan2_name,"atan2")     do_name(sqrt_name,"sqrt")                               \
-  do_name(log_name,"log")       do_name(log10_name,"log10")     do_name(pow_name,"pow")                                 \
-  do_name(exp_name,"exp")       do_name(min_name,"min")         do_name(max_name,"max")                                 \
-  do_name(floor_name, "floor")  do_name(ceil_name, "ceil")      do_name(rint_name, "rint")                              \
-                                                                                                                        \
-  do_name(addExact_name,"addExact")                                                                                     \
-  do_name(decrementExact_name,"decrementExact")                                                                         \
-  do_name(incrementExact_name,"incrementExact")                                                                         \
-  do_name(multiplyExact_name,"multiplyExact")                                                                           \
-  do_name(multiplyHigh_name,"multiplyHigh")                                                                             \
-  do_name(negateExact_name,"negateExact")                                                                               \
-  do_name(subtractExact_name,"subtractExact")                                                                           \
-  do_name(fma_name, "fma")                                                                                              \
-  do_name(copySign_name, "copySign")                                                                                    \
-  do_name(signum_name,"signum")                                                                                         \
-                                                                                                                        \
-  do_intrinsic(_dabs,                     java_lang_Math,         abs_name,   double_double_signature,           F_S)   \
-  do_intrinsic(_fabs,                     java_lang_Math,         abs_name,   float_float_signature,           F_S)   \
-  do_intrinsic(_iabs,                     java_lang_Math,         abs_name,   int_int_signature,           F_S)   \
-  do_intrinsic(_labs,                     java_lang_Math,         abs_name,   long_long_signature,           F_S)   \
-  do_intrinsic(_dsin,                     java_lang_Math,         sin_name,   double_double_signature,           F_S)   \
-  do_intrinsic(_floor,                    java_lang_Math,         floor_name, double_double_signature,           F_S)   \
-  do_intrinsic(_ceil,                     java_lang_Math,         ceil_name,  double_double_signature,           F_S)   \
-  do_intrinsic(_rint,                     java_lang_Math,         rint_name,  double_double_signature,           F_S)   \
-  do_intrinsic(_dcos,                     java_lang_Math,         cos_name,   double_double_signature,           F_S)   \
-  do_intrinsic(_dtan,                     java_lang_Math,         tan_name,   double_double_signature,           F_S)   \
-  do_intrinsic(_datan2,                   java_lang_Math,         atan2_name, double2_double_signature,          F_S)   \
-  do_intrinsic(_dsqrt,                    java_lang_Math,         sqrt_name,  double_double_signature,           F_S)   \
-  do_intrinsic(_dlog,                     java_lang_Math,         log_name,   double_double_signature,           F_S)   \
-  do_intrinsic(_dlog10,                   java_lang_Math,         log10_name, double_double_signature,           F_S)   \
-  do_intrinsic(_dpow,                     java_lang_Math,         pow_name,   double2_double_signature,          F_S)   \
-  do_intrinsic(_dexp,                     java_lang_Math,         exp_name,   double_double_signature,           F_S)   \
-  do_intrinsic(_min,                      java_lang_Math,         min_name,   int2_int_signature,                F_S)   \
-  do_intrinsic(_max,                      java_lang_Math,         max_name,   int2_int_signature,                F_S)   \
-  do_intrinsic(_addExactI,                java_lang_Math,         addExact_name, int2_int_signature,             F_S)   \
-  do_intrinsic(_addExactL,                java_lang_Math,         addExact_name, long2_long_signature,           F_S)   \
-  do_intrinsic(_decrementExactI,          java_lang_Math,         decrementExact_name, int_int_signature,        F_S)   \
-  do_intrinsic(_decrementExactL,          java_lang_Math,         decrementExact_name, long_long_signature,      F_S)   \
-  do_intrinsic(_incrementExactI,          java_lang_Math,         incrementExact_name, int_int_signature,        F_S)   \
-  do_intrinsic(_incrementExactL,          java_lang_Math,         incrementExact_name, long_long_signature,      F_S)   \
-  do_intrinsic(_multiplyExactI,           java_lang_Math,         multiplyExact_name, int2_int_signature,        F_S)   \
-  do_intrinsic(_multiplyExactL,           java_lang_Math,         multiplyExact_name, long2_long_signature,      F_S)   \
-  do_intrinsic(_multiplyHigh,             java_lang_Math,         multiplyHigh_name, long2_long_signature,       F_S)   \
-  do_intrinsic(_negateExactI,             java_lang_Math,         negateExact_name, int_int_signature,           F_S)   \
-  do_intrinsic(_negateExactL,             java_lang_Math,         negateExact_name, long_long_signature,         F_S)   \
-  do_intrinsic(_subtractExactI,           java_lang_Math,         subtractExact_name, int2_int_signature,        F_S)   \
-  do_intrinsic(_subtractExactL,           java_lang_Math,         subtractExact_name, long2_long_signature,      F_S)   \
-  do_intrinsic(_fmaD,                     java_lang_Math,         fma_name,           double3_double_signature,  F_S)   \
-  do_intrinsic(_fmaF,                     java_lang_Math,         fma_name,           float3_float_signature,    F_S)   \
-  do_intrinsic(_maxF,                     java_lang_Math,         max_name,           float2_float_signature,    F_S)   \
-  do_intrinsic(_minF,                     java_lang_Math,         min_name,           float2_float_signature,    F_S)   \
-  do_intrinsic(_maxD,                     java_lang_Math,         max_name,           double2_double_signature,  F_S)   \
-  do_intrinsic(_minD,                     java_lang_Math,         min_name,           double2_double_signature,  F_S)   \
-  do_intrinsic(_dcopySign,                java_lang_Math,         copySign_name,      double2_double_signature,  F_S)   \
-  do_intrinsic(_fcopySign,                java_lang_Math,         copySign_name,      float2_float_signature,    F_S)   \
-  do_intrinsic(_dsignum,                  java_lang_Math,         signum_name,        double_double_signature,   F_S)   \
-  do_intrinsic(_fsignum,                  java_lang_Math,         signum_name,        float_float_signature,     F_S)   \
-                                                                                                                        \
-  do_intrinsic(_floatToRawIntBits,        java_lang_Float,        floatToRawIntBits_name,   float_int_signature, F_S)   \
-   do_name(     floatToRawIntBits_name,                          "floatToRawIntBits")                                   \
-  do_intrinsic(_floatToIntBits,           java_lang_Float,        floatToIntBits_name,      float_int_signature, F_S)   \
-   do_name(     floatToIntBits_name,                             "floatToIntBits")                                      \
-  do_intrinsic(_intBitsToFloat,           java_lang_Float,        intBitsToFloat_name,      int_float_signature, F_S)   \
-   do_name(     intBitsToFloat_name,                             "intBitsToFloat")                                      \
-  do_intrinsic(_doubleToRawLongBits,      java_lang_Double,       doubleToRawLongBits_name, double_long_signature, F_S) \
-   do_name(     doubleToRawLongBits_name,                        "doubleToRawLongBits")                                 \
-  do_intrinsic(_doubleToLongBits,         java_lang_Double,       doubleToLongBits_name,    double_long_signature, F_S) \
-   do_name(     doubleToLongBits_name,                           "doubleToLongBits")                                    \
-  do_intrinsic(_longBitsToDouble,         java_lang_Double,       longBitsToDouble_name,    long_double_signature, F_S) \
-   do_name(     longBitsToDouble_name,                           "longBitsToDouble")                                    \
-                                                                                                                        \
-  do_intrinsic(_numberOfLeadingZeros_i,   java_lang_Integer,      numberOfLeadingZeros_name,int_int_signature,   F_S)   \
-  do_intrinsic(_numberOfLeadingZeros_l,   java_lang_Long,         numberOfLeadingZeros_name,long_int_signature,  F_S)   \
-                                                                                                                        \
-  do_intrinsic(_numberOfTrailingZeros_i,  java_lang_Integer,      numberOfTrailingZeros_name,int_int_signature,  F_S)   \
-  do_intrinsic(_numberOfTrailingZeros_l,  java_lang_Long,         numberOfTrailingZeros_name,long_int_signature, F_S)   \
-                                                                                                                        \
-  do_intrinsic(_bitCount_i,               java_lang_Integer,      bitCount_name,            int_int_signature,   F_S)   \
-  do_intrinsic(_bitCount_l,               java_lang_Long,         bitCount_name,            long_int_signature,  F_S)   \
-                                                                                                                        \
-  do_intrinsic(_reverseBytes_i,           java_lang_Integer,      reverseBytes_name,        int_int_signature,   F_S)   \
-   do_name(     reverseBytes_name,                               "reverseBytes")                                        \
-  do_intrinsic(_reverseBytes_l,           java_lang_Long,         reverseBytes_name,        long_long_signature, F_S)   \
-    /*  (symbol reverseBytes_name defined above) */                                                                     \
-  do_intrinsic(_reverseBytes_c,           java_lang_Character,    reverseBytes_name,        char_char_signature, F_S)   \
-    /*  (symbol reverseBytes_name defined above) */                                                                     \
-  do_intrinsic(_reverseBytes_s,           java_lang_Short,        reverseBytes_name,        short_short_signature, F_S) \
-    /*  (symbol reverseBytes_name defined above) */                                                                     \
-                                                                                                                        \
-  do_intrinsic(_identityHashCode,         java_lang_System,       identityHashCode_name, object_int_signature,   F_S)   \
-   do_name(     identityHashCode_name,                           "identityHashCode")                                    \
-  do_intrinsic(_currentTimeMillis,        java_lang_System,       currentTimeMillis_name, void_long_signature,   F_S)   \
-                                                                                                                        \
-   do_name(     currentTimeMillis_name,                          "currentTimeMillis")                                   \
-  do_intrinsic(_nanoTime,                 java_lang_System,       nanoTime_name,          void_long_signature,   F_S)   \
-   do_name(     nanoTime_name,                                   "nanoTime")                                            \
-                                                                                                                        \
-  JFR_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)                                               \
-                                                                                                                        \
-  do_intrinsic(_arraycopy,                java_lang_System,       arraycopy_name, arraycopy_signature,           F_S)   \
-   do_name(     arraycopy_name,                                  "arraycopy")                                           \
-   do_signature(arraycopy_signature,                             "(Ljava/lang/Object;ILjava/lang/Object;II)V")          \
-  do_intrinsic(_currentThread,            java_lang_Thread,       currentThread_name, currentThread_signature,   F_S)   \
-   do_name(     currentThread_name,                              "currentThread")                                       \
-   do_signature(currentThread_signature,                         "()Ljava/lang/Thread;")                                \
-                                                                                                                        \
-  /* reflective intrinsics, for java/lang/Class, etc. */                                                                \
-  do_intrinsic(_isAssignableFrom,         java_lang_Class,        isAssignableFrom_name, class_boolean_signature, F_RN) \
-   do_name(     isAssignableFrom_name,                           "isAssignableFrom")                                    \
-  do_intrinsic(_isInstance,               java_lang_Class,        isInstance_name, object_boolean_signature,     F_RN)  \
-   do_name(     isInstance_name,                                 "isInstance")                                          \
-  do_intrinsic(_getModifiers,             java_lang_Class,        getModifiers_name, void_int_signature,         F_RN)  \
-   do_name(     getModifiers_name,                               "getModifiers")                                        \
-  do_intrinsic(_isInterface,              java_lang_Class,        isInterface_name, void_boolean_signature,      F_RN)  \
-   do_name(     isInterface_name,                                "isInterface")                                         \
-  do_intrinsic(_isArray,                  java_lang_Class,        isArray_name, void_boolean_signature,          F_RN)  \
-   do_name(     isArray_name,                                    "isArray")                                             \
-  do_intrinsic(_isPrimitive,              java_lang_Class,        isPrimitive_name, void_boolean_signature,      F_RN)  \
-   do_name(     isPrimitive_name,                                "isPrimitive")                                         \
-  do_intrinsic(_isHidden,                 java_lang_Class,        isHidden_name, void_boolean_signature,         F_RN)  \
-   do_name(     isHidden_name,                                   "isHidden")                                            \
-  do_intrinsic(_getSuperclass,            java_lang_Class,        getSuperclass_name, void_class_signature,      F_RN)  \
-   do_name(     getSuperclass_name,                              "getSuperclass")                                       \
-  do_intrinsic(_Class_cast,               java_lang_Class,        Class_cast_name, object_object_signature,      F_R)   \
-   do_name(     Class_cast_name,                                 "cast")                                                \
-                                                                                                                        \
-  do_intrinsic(_getClassAccessFlags,      reflect_Reflection,     getClassAccessFlags_name, class_int_signature, F_SN)  \
-   do_name(     getClassAccessFlags_name,                        "getClassAccessFlags")                                 \
-  do_intrinsic(_getLength,                java_lang_reflect_Array, getLength_name, object_int_signature,         F_SN)  \
-   do_name(     getLength_name,                                   "getLength")                                          \
-                                                                                                                        \
-  do_intrinsic(_getCallerClass,           reflect_Reflection,     getCallerClass_name, void_class_signature,     F_SN)  \
-   do_name(     getCallerClass_name,                             "getCallerClass")                                      \
-                                                                                                                        \
-  do_intrinsic(_newArray,                 java_lang_reflect_Array, newArray_name, newArray_signature,            F_SN)  \
-   do_name(     newArray_name,                                    "newArray")                                           \
-   do_signature(newArray_signature,                               "(Ljava/lang/Class;I)Ljava/lang/Object;")             \
-                                                                                                                        \
-  do_intrinsic(_onSpinWait,               java_lang_Thread,       onSpinWait_name, onSpinWait_signature,         F_S)   \
-   do_name(     onSpinWait_name,                                  "onSpinWait")                                         \
-   do_alias(    onSpinWait_signature,                             void_method_signature)                                \
-                                                                                                                        \
-  do_intrinsic(_copyOf,                   java_util_Arrays,       copyOf_name, copyOf_signature,                 F_S)   \
-   do_name(     copyOf_name,                                     "copyOf")                                              \
-   do_signature(copyOf_signature,             "([Ljava/lang/Object;ILjava/lang/Class;)[Ljava/lang/Object;")             \
-                                                                                                                        \
-  do_intrinsic(_copyOfRange,              java_util_Arrays,       copyOfRange_name, copyOfRange_signature,       F_S)   \
-   do_name(     copyOfRange_name,                                "copyOfRange")                                         \
-   do_signature(copyOfRange_signature,        "([Ljava/lang/Object;IILjava/lang/Class;)[Ljava/lang/Object;")            \
-                                                                                                                        \
-  do_intrinsic(_equalsC,                  java_util_Arrays,       equals_name,    equalsC_signature,             F_S)   \
-   do_signature(equalsC_signature,                               "([C[C)Z")                                             \
-  do_intrinsic(_equalsB,                  java_util_Arrays,       equals_name,    equalsB_signature,             F_S)   \
-   do_signature(equalsB_signature,                               "([B[B)Z")                                             \
-                                                                                                                        \
-  do_intrinsic(_compressStringC,          java_lang_StringUTF16,  compress_name, encodeISOArray_signature,       F_S)   \
-   do_name(     compress_name,                                   "compress")                                            \
-  do_intrinsic(_compressStringB,          java_lang_StringUTF16,  compress_name, indexOfI_signature,             F_S)   \
-  do_intrinsic(_inflateStringC,           java_lang_StringLatin1, inflate_name, inflateC_signature,              F_S)   \
-   do_name(     inflate_name,                                    "inflate")                                             \
-   do_signature(inflateC_signature,                              "([BI[CII)V")                                          \
-  do_intrinsic(_inflateStringB,           java_lang_StringLatin1, inflate_name, inflateB_signature,              F_S)   \
-   do_signature(inflateB_signature,                              "([BI[BII)V")                                          \
-  do_intrinsic(_toBytesStringU,           java_lang_StringUTF16, toBytes_name, toBytesU_signature,               F_S)   \
-   do_name(     toBytes_name,                                    "toBytes")                                             \
-   do_signature(toBytesU_signature,                              "([CII)[B")                                            \
-  do_intrinsic(_getCharsStringU,          java_lang_StringUTF16, getCharsU_name, getCharsU_signature,            F_S)   \
-   do_name(     getCharsU_name,                                  "getChars")                                            \
-   do_signature(getCharsU_signature,                             "([BII[CI)V")                                          \
-  do_intrinsic(_getCharStringU,           java_lang_StringUTF16, getChar_name, getCharStringU_signature,         F_S)   \
-   do_signature(getCharStringU_signature,                        "([BI)C")                                              \
-  do_intrinsic(_putCharStringU,           java_lang_StringUTF16, putChar_name, putCharStringU_signature,         F_S)   \
-   do_signature(putCharStringU_signature,                        "([BII)V")                                             \
-  do_intrinsic(_compareToL,               java_lang_StringLatin1,compareTo_name, compareTo_indexOf_signature,    F_S)   \
-  do_intrinsic(_compareToU,               java_lang_StringUTF16, compareTo_name, compareTo_indexOf_signature,    F_S)   \
-  do_intrinsic(_compareToLU,              java_lang_StringLatin1,compareToLU_name, compareTo_indexOf_signature,  F_S)   \
-  do_intrinsic(_compareToUL,              java_lang_StringUTF16, compareToUL_name, compareTo_indexOf_signature,  F_S)   \
-   do_signature(compareTo_indexOf_signature,                     "([B[B)I")                                             \
-   do_name(     compareTo_name,                                  "compareTo")                                           \
-   do_name(     compareToLU_name,                                "compareToUTF16")                                      \
-   do_name(     compareToUL_name,                                "compareToLatin1")                                     \
-  do_intrinsic(_indexOfL,                 java_lang_StringLatin1,indexOf_name, compareTo_indexOf_signature,      F_S)   \
-  do_intrinsic(_indexOfU,                 java_lang_StringUTF16, indexOf_name, compareTo_indexOf_signature,      F_S)   \
-  do_intrinsic(_indexOfUL,                java_lang_StringUTF16, indexOfUL_name, compareTo_indexOf_signature,    F_S)   \
-  do_intrinsic(_indexOfIL,                java_lang_StringLatin1,indexOf_name, indexOfI_signature,               F_S)   \
-  do_intrinsic(_indexOfIU,                java_lang_StringUTF16, indexOf_name, indexOfI_signature,               F_S)   \
-  do_intrinsic(_indexOfIUL,               java_lang_StringUTF16, indexOfUL_name, indexOfI_signature,             F_S)   \
-  do_intrinsic(_indexOfU_char,            java_lang_StringUTF16, indexOfChar_name, indexOfChar_signature,        F_S)   \
-   do_name(     indexOf_name,                                    "indexOf")                                             \
-   do_name(     indexOfChar_name,                                "indexOfChar")                                         \
-   do_name(     indexOfUL_name,                                  "indexOfLatin1")                                       \
-   do_signature(indexOfI_signature,                              "([BI[BII)I")                                          \
-   do_signature(indexOfChar_signature,                           "([BIII)I")                                            \
-  do_intrinsic(_equalsL,                  java_lang_StringLatin1,equals_name, equalsB_signature,                 F_S)   \
-  do_intrinsic(_equalsU,                  java_lang_StringUTF16, equals_name, equalsB_signature,                 F_S)   \
-                                                                                                                        \
-  do_intrinsic(_isDigit,                  java_lang_CharacterDataLatin1, isDigit_name,      int_bool_signature,  F_R)   \
-   do_name(     isDigit_name,                                           "isDigit")                                      \
-  do_intrinsic(_isLowerCase,              java_lang_CharacterDataLatin1, isLowerCase_name,  int_bool_signature,  F_R)   \
-   do_name(     isLowerCase_name,                                       "isLowerCase")                                  \
-  do_intrinsic(_isUpperCase,              java_lang_CharacterDataLatin1, isUpperCase_name,  int_bool_signature,  F_R)   \
-   do_name(     isUpperCase_name,                                       "isUpperCase")                                  \
-  do_intrinsic(_isWhitespace,             java_lang_CharacterDataLatin1, isWhitespace_name, int_bool_signature,  F_R)   \
-   do_name(     isWhitespace_name,                                      "isWhitespace")                                 \
-                                                                                                                        \
-  do_intrinsic(_Preconditions_checkIndex, jdk_internal_util_Preconditions, checkIndex_name, Preconditions_checkIndex_signature, F_S)   \
-   do_signature(Preconditions_checkIndex_signature,              "(IILjava/util/function/BiFunction;)I")                \
-                                                                                                                        \
-  do_class(java_nio_Buffer,               "java/nio/Buffer")                                                            \
-  do_intrinsic(_checkIndex,               java_nio_Buffer,        checkIndex_name, int_int_signature,            F_R)   \
-   do_name(     checkIndex_name,                                 "checkIndex")                                          \
-                                                                                                                        \
-  do_class(java_lang_StringCoding,        "java/lang/StringCoding")                                                     \
-  do_intrinsic(_hasNegatives,             java_lang_StringCoding, hasNegatives_name, hasNegatives_signature,     F_S)   \
-   do_name(     hasNegatives_name,                               "hasNegatives")                                        \
-   do_signature(hasNegatives_signature,                          "([BII)Z")                                             \
-                                                                                                                        \
-  do_class(sun_nio_cs_iso8859_1_Encoder,  "sun/nio/cs/ISO_8859_1$Encoder")                                              \
-  do_intrinsic(_encodeISOArray,     sun_nio_cs_iso8859_1_Encoder, encodeISOArray_name, encodeISOArray_signature, F_S)   \
-   do_name(     encodeISOArray_name,                             "implEncodeISOArray")                                  \
-   do_signature(encodeISOArray_signature,                        "([CI[BII)I")                                          \
-                                                                                                                        \
-  do_intrinsic(_encodeByteISOArray,     java_lang_StringCoding, encodeISOArray_name, indexOfI_signature,         F_S)   \
-                                                                                                                        \
-  do_class(java_math_BigInteger,                      "java/math/BigInteger")                                           \
-  do_intrinsic(_multiplyToLen,      java_math_BigInteger, multiplyToLen_name, multiplyToLen_signature, F_S)             \
-   do_name(     multiplyToLen_name,                             "implMultiplyToLen")                                    \
-   do_signature(multiplyToLen_signature,                        "([II[II[I)[I")                                         \
-                                                                                                                        \
-  do_intrinsic(_squareToLen, java_math_BigInteger, squareToLen_name, squareToLen_signature, F_S)                        \
-   do_name(     squareToLen_name,                             "implSquareToLen")                                        \
-   do_signature(squareToLen_signature,                        "([II[II)[I")                                             \
-                                                                                                                        \
-  do_intrinsic(_mulAdd, java_math_BigInteger, mulAdd_name, mulAdd_signature, F_S)                                       \
-   do_name(     mulAdd_name,                                  "implMulAdd")                                             \
-   do_signature(mulAdd_signature,                             "([I[IIII)I")                                             \
-                                                                                                                        \
-  do_intrinsic(_montgomeryMultiply,      java_math_BigInteger, montgomeryMultiply_name, montgomeryMultiply_signature, F_S) \
-   do_name(     montgomeryMultiply_name,                             "implMontgomeryMultiply")                          \
-   do_signature(montgomeryMultiply_signature,                        "([I[I[IIJ[I)[I")                                  \
-                                                                                                                        \
-  do_intrinsic(_montgomerySquare,      java_math_BigInteger, montgomerySquare_name, montgomerySquare_signature, F_S)    \
-   do_name(     montgomerySquare_name,                             "implMontgomerySquare")                              \
-   do_signature(montgomerySquare_signature,                        "([I[IIJ[I)[I")                                      \
-                                                                                                                        \
-  do_intrinsic(_bigIntegerRightShiftWorker, java_math_BigInteger, rightShift_name, big_integer_shift_worker_signature, F_S) \
-   do_name(     rightShift_name,                                 "shiftRightImplWorker")                                \
-                                                                                                                        \
-  do_intrinsic(_bigIntegerLeftShiftWorker, java_math_BigInteger, leftShift_name, big_integer_shift_worker_signature, F_S) \
-   do_name(     leftShift_name,                                 "shiftLeftImplWorker")                                  \
-                                                                                                                        \
-  do_class(jdk_internal_util_ArraysSupport, "jdk/internal/util/ArraysSupport")                                                          \
-  do_intrinsic(_vectorizedMismatch, jdk_internal_util_ArraysSupport, vectorizedMismatch_name, vectorizedMismatch_signature, F_S)\
-   do_name(vectorizedMismatch_name, "vectorizedMismatch")                                                               \
-   do_signature(vectorizedMismatch_signature, "(Ljava/lang/Object;JLjava/lang/Object;JII)I")                            \
-                                                                                                                        \
-  /* java/lang/ref/Reference */                                                                                         \
-  do_intrinsic(_Reference_get,            java_lang_ref_Reference, get_name,    void_object_signature, F_R)             \
-                                                                                                                        \
-  /* support for com.sun.crypto.provider.AESCrypt and some of its callers */                                            \
-  do_class(com_sun_crypto_provider_aescrypt,      "com/sun/crypto/provider/AESCrypt")                                   \
-  do_intrinsic(_aescrypt_encryptBlock, com_sun_crypto_provider_aescrypt, encryptBlock_name, byteArray_int_byteArray_int_signature, F_R)   \
-  do_intrinsic(_aescrypt_decryptBlock, com_sun_crypto_provider_aescrypt, decryptBlock_name, byteArray_int_byteArray_int_signature, F_R)   \
-   do_name(     encryptBlock_name,                                 "implEncryptBlock")                                  \
-   do_name(     decryptBlock_name,                                 "implDecryptBlock")                                  \
-   do_signature(byteArray_int_byteArray_int_signature,             "([BI[BI)V")                                         \
-                                                                                                                        \
-  do_class(com_sun_crypto_provider_cipherBlockChaining,            "com/sun/crypto/provider/CipherBlockChaining")       \
-   do_intrinsic(_cipherBlockChaining_encryptAESCrypt, com_sun_crypto_provider_cipherBlockChaining, encrypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
-   do_intrinsic(_cipherBlockChaining_decryptAESCrypt, com_sun_crypto_provider_cipherBlockChaining, decrypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
-   do_name(     encrypt_name,                                      "implEncrypt")                                       \
-   do_name(     decrypt_name,                                      "implDecrypt")                                       \
-   do_signature(byteArray_int_int_byteArray_int_signature,         "([BII[BI)I")                                        \
-                                                                                                                        \
-  do_class(com_sun_crypto_provider_electronicCodeBook, "com/sun/crypto/provider/ElectronicCodeBook")                    \
-   do_intrinsic(_electronicCodeBook_encryptAESCrypt, com_sun_crypto_provider_electronicCodeBook, ecb_encrypt_name, byteArray_int_int_byteArray_int_signature, F_R)  \
-   do_intrinsic(_electronicCodeBook_decryptAESCrypt, com_sun_crypto_provider_electronicCodeBook, ecb_decrypt_name, byteArray_int_int_byteArray_int_signature, F_R)  \
-   do_name(ecb_encrypt_name, "implECBEncrypt")                                                                          \
-   do_name(ecb_decrypt_name, "implECBDecrypt")                                                                          \
-                                                                                                                        \
-  do_class(com_sun_crypto_provider_counterMode,      "com/sun/crypto/provider/CounterMode")                             \
-   do_intrinsic(_counterMode_AESCrypt, com_sun_crypto_provider_counterMode, crypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
-   do_name(     crypt_name,                                 "implCrypt")                                                    \
-                                                                                                                        \
-  /* support for sun.security.provider.MD5 */                                                                           \
-  do_class(sun_security_provider_md5,                              "sun/security/provider/MD5")                         \
-  do_intrinsic(_md5_implCompress, sun_security_provider_md5, implCompress_name, implCompress_signature, F_R)            \
-   do_name(     implCompress_name,                                 "implCompress0")                                     \
-   do_signature(implCompress_signature,                            "([BI)V")                                            \
-                                                                                                                        \
-  /* support for sun.security.provider.SHA */                                                                           \
-  do_class(sun_security_provider_sha,                              "sun/security/provider/SHA")                         \
-  do_intrinsic(_sha_implCompress, sun_security_provider_sha, implCompress_name, implCompress_signature, F_R)            \
-                                                                                                                        \
-  /* support for sun.security.provider.SHA2 */                                                                          \
-  do_class(sun_security_provider_sha2,                             "sun/security/provider/SHA2")                        \
-  do_intrinsic(_sha2_implCompress, sun_security_provider_sha2, implCompress_name, implCompress_signature, F_R)          \
-                                                                                                                        \
-  /* support for sun.security.provider.SHA5 */                                                                          \
-  do_class(sun_security_provider_sha5,                             "sun/security/provider/SHA5")                        \
-  do_intrinsic(_sha5_implCompress, sun_security_provider_sha5, implCompress_name, implCompress_signature, F_R)          \
-                                                                                                                        \
-  /* support for sun.security.provider.DigestBase */                                                                    \
-  do_class(sun_security_provider_digestbase,                       "sun/security/provider/DigestBase")                  \
-  do_intrinsic(_digestBase_implCompressMB, sun_security_provider_digestbase, implCompressMB_name, implCompressMB_signature, F_R)   \
-   do_name(     implCompressMB_name,                               "implCompressMultiBlock0")                           \
-   do_signature(implCompressMB_signature,                          "([BII)I")                                           \
-                                                                                                                        \
-   /* support for java.util.Base64.Encoder*/                                                                            \
-  do_class(java_util_Base64_Encoder, "java/util/Base64$Encoder")                                                        \
-  do_intrinsic(_base64_encodeBlock, java_util_Base64_Encoder, encodeBlock_name, encodeBlock_signature, F_R)             \
-  do_name(encodeBlock_name, "encodeBlock")                                                                              \
-  do_signature(encodeBlock_signature, "([BII[BIZ)V")                                                                    \
-                                                                                                                        \
-  /* support for com.sun.crypto.provider.GHASH */                                                                       \
-  do_class(com_sun_crypto_provider_ghash, "com/sun/crypto/provider/GHASH")                                              \
-  do_intrinsic(_ghash_processBlocks, com_sun_crypto_provider_ghash, processBlocks_name, ghash_processBlocks_signature, F_S) \
-   do_name(processBlocks_name, "processBlocks")                                                                         \
-   do_signature(ghash_processBlocks_signature, "([BII[J[J)V")                                                           \
-                                                                                                                        \
-  /* support for java.util.zip */                                                                                       \
-  do_class(java_util_zip_CRC32,           "java/util/zip/CRC32")                                                        \
-  do_intrinsic(_updateCRC32,               java_util_zip_CRC32,   update_name, int2_int_signature,               F_SN)  \
-   do_name(     update_name,                                      "update")                                             \
-  do_intrinsic(_updateBytesCRC32,          java_util_zip_CRC32,   updateBytes_name, updateBytes_signature,       F_SN)  \
-   do_name(     updateBytes_name,                                "updateBytes0")                                        \
-   do_signature(updateBytes_signature,                           "(I[BII)I")                                            \
-  do_intrinsic(_updateByteBufferCRC32,     java_util_zip_CRC32,   updateByteBuffer_name, updateByteBuffer_signature, F_SN) \
-   do_name(     updateByteBuffer_name,                           "updateByteBuffer0")                                   \
-   do_signature(updateByteBuffer_signature,                      "(IJII)I")                                             \
-                                                                                                                        \
-  /* support for java.util.zip.CRC32C */                                                                                \
-  do_class(java_util_zip_CRC32C,          "java/util/zip/CRC32C")                                                       \
-  do_intrinsic(_updateBytesCRC32C,         java_util_zip_CRC32C,  updateBytes_C_name, updateBytes_signature,       F_S) \
-   do_name(     updateBytes_C_name,                               "updateBytes")                                        \
-  do_intrinsic(_updateDirectByteBufferCRC32C, java_util_zip_CRC32C, updateDirectByteBuffer_C_name, updateByteBuffer_signature, F_S) \
-   do_name(    updateDirectByteBuffer_C_name,                     "updateDirectByteBuffer")                             \
-                                                                                                                        \
-   /* support for java.util.zip.Adler32 */                                                                              \
-  do_class(java_util_zip_Adler32,        "java/util/zip/Adler32")                                                       \
-  do_intrinsic(_updateBytesAdler32,       java_util_zip_Adler32,  updateBytes_C_name,  updateBytes_signature,  F_SN)    \
-  do_intrinsic(_updateByteBufferAdler32,  java_util_zip_Adler32,  updateByteBuffer_A_name,  updateByteBuffer_signature,  F_SN) \
-   do_name(     updateByteBuffer_A_name,                          "updateByteBuffer")                                   \
-                                                                                                                        \
-  /* support for UnsafeConstants */                                                                                     \
-  do_class(jdk_internal_misc_UnsafeConstants,      "jdk/internal/misc/UnsafeConstants")                                 \
-                                                                                                                        \
-  /* support for Unsafe */                                                                                              \
-  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;")                 \
-  do_intrinsic(_allocateUninitializedArray, jdk_internal_misc_Unsafe,   allocateUninitializedArray_name, newArray_signature,  F_R) \
-   do_name(     allocateUninitializedArray_name,                        "allocateUninitializedArray0")                           \
-  do_intrinsic(_copyMemory,               jdk_internal_misc_Unsafe,     copyMemory_name, copyMemory_signature,         F_RN)     \
-   do_name(     copyMemory_name,                                        "copyMemory0")                                           \
-   do_signature(copyMemory_signature,                                   "(Ljava/lang/Object;JLjava/lang/Object;JJ)V")            \
-  do_intrinsic(_loadFence,                jdk_internal_misc_Unsafe,     loadFence_name, loadFence_signature,           F_RN)     \
-   do_name(     loadFence_name,                                         "loadFence")                                             \
-   do_alias(    loadFence_signature,                                    void_method_signature)                                   \
-  do_intrinsic(_storeFence,               jdk_internal_misc_Unsafe,     storeFence_name, storeFence_signature,         F_RN)     \
-   do_name(     storeFence_name,                                        "storeFence")                                            \
-   do_alias(    storeFence_signature,                                   void_method_signature)                                   \
-  do_intrinsic(_fullFence,                jdk_internal_misc_Unsafe,     fullFence_name, fullFence_signature,           F_RN)     \
-   do_name(     fullFence_name,                                         "fullFence")                                             \
-   do_alias(    fullFence_signature,                                    void_method_signature)                                   \
-                                                                                                                        \
-  /* Custom branch frequencies profiling support for JSR292 */                                                          \
-  do_class(java_lang_invoke_MethodHandleImpl,               "java/lang/invoke/MethodHandleImpl")                        \
-  do_intrinsic(_profileBoolean, java_lang_invoke_MethodHandleImpl, profileBoolean_name, profileBoolean_signature, F_S)  \
-   do_name(     profileBoolean_name,                             "profileBoolean")                                      \
-   do_signature(profileBoolean_signature,                        "(Z[I)Z")                                              \
-  do_intrinsic(_isCompileConstant, java_lang_invoke_MethodHandleImpl, isCompileConstant_name, isCompileConstant_signature, F_S) \
-   do_name(     isCompileConstant_name,                          "isCompileConstant")                                   \
-   do_alias(    isCompileConstant_signature,                      object_boolean_signature)                             \
-                                                                                                                        \
-  /* unsafe memory references (there are a lot of them...) */                                                           \
-  do_signature(getReference_signature,    "(Ljava/lang/Object;J)Ljava/lang/Object;")                                    \
-  do_signature(putReference_signature,    "(Ljava/lang/Object;JLjava/lang/Object;)V")                                   \
-  do_signature(getBoolean_signature,      "(Ljava/lang/Object;J)Z")                                                     \
-  do_signature(putBoolean_signature,      "(Ljava/lang/Object;JZ)V")                                                    \
-  do_signature(getByte_signature,         "(Ljava/lang/Object;J)B")                                                     \
-  do_signature(putByte_signature,         "(Ljava/lang/Object;JB)V")                                                    \
-  do_signature(getShort_signature,        "(Ljava/lang/Object;J)S")                                                     \
-  do_signature(putShort_signature,        "(Ljava/lang/Object;JS)V")                                                    \
-  do_signature(getChar_signature,         "(Ljava/lang/Object;J)C")                                                     \
-  do_signature(putChar_signature,         "(Ljava/lang/Object;JC)V")                                                    \
-  do_signature(getInt_signature,          "(Ljava/lang/Object;J)I")                                                     \
-  do_signature(putInt_signature,          "(Ljava/lang/Object;JI)V")                                                    \
-  do_signature(getLong_signature,         "(Ljava/lang/Object;J)J")                                                     \
-  do_signature(putLong_signature,         "(Ljava/lang/Object;JJ)V")                                                    \
-  do_signature(getFloat_signature,        "(Ljava/lang/Object;J)F")                                                     \
-  do_signature(putFloat_signature,        "(Ljava/lang/Object;JF)V")                                                    \
-  do_signature(getDouble_signature,       "(Ljava/lang/Object;J)D")                                                     \
-  do_signature(putDouble_signature,       "(Ljava/lang/Object;JD)V")                                                    \
-                                                                                                                        \
-  do_name(getReference_name,"getReference")     do_name(putReference_name,"putReference")                               \
-  do_name(getBoolean_name,"getBoolean")         do_name(putBoolean_name,"putBoolean")                                   \
-  do_name(getByte_name,"getByte")               do_name(putByte_name,"putByte")                                         \
-  do_name(getShort_name,"getShort")             do_name(putShort_name,"putShort")                                       \
-  do_name(getChar_name,"getChar")               do_name(putChar_name,"putChar")                                         \
-  do_name(getInt_name,"getInt")                 do_name(putInt_name,"putInt")                                           \
-  do_name(getLong_name,"getLong")               do_name(putLong_name,"putLong")                                         \
-  do_name(getFloat_name,"getFloat")             do_name(putFloat_name,"putFloat")                                       \
-  do_name(getDouble_name,"getDouble")           do_name(putDouble_name,"putDouble")                                     \
-                                                                                                                        \
-  do_intrinsic(_getReference,       jdk_internal_misc_Unsafe,     getReference_name, getReference_signature,     F_RN)  \
-  do_intrinsic(_getBoolean,         jdk_internal_misc_Unsafe,     getBoolean_name, getBoolean_signature,         F_RN)  \
-  do_intrinsic(_getByte,            jdk_internal_misc_Unsafe,     getByte_name, getByte_signature,               F_RN)  \
-  do_intrinsic(_getShort,           jdk_internal_misc_Unsafe,     getShort_name, getShort_signature,             F_RN)  \
-  do_intrinsic(_getChar,            jdk_internal_misc_Unsafe,     getChar_name, getChar_signature,               F_RN)  \
-  do_intrinsic(_getInt,             jdk_internal_misc_Unsafe,     getInt_name, getInt_signature,                 F_RN)  \
-  do_intrinsic(_getLong,            jdk_internal_misc_Unsafe,     getLong_name, getLong_signature,               F_RN)  \
-  do_intrinsic(_getFloat,           jdk_internal_misc_Unsafe,     getFloat_name, getFloat_signature,             F_RN)  \
-  do_intrinsic(_getDouble,          jdk_internal_misc_Unsafe,     getDouble_name, getDouble_signature,           F_RN)  \
-  do_intrinsic(_putReference,       jdk_internal_misc_Unsafe,     putReference_name, putReference_signature,     F_RN)  \
-  do_intrinsic(_putBoolean,         jdk_internal_misc_Unsafe,     putBoolean_name, putBoolean_signature,         F_RN)  \
-  do_intrinsic(_putByte,            jdk_internal_misc_Unsafe,     putByte_name, putByte_signature,               F_RN)  \
-  do_intrinsic(_putShort,           jdk_internal_misc_Unsafe,     putShort_name, putShort_signature,             F_RN)  \
-  do_intrinsic(_putChar,            jdk_internal_misc_Unsafe,     putChar_name, putChar_signature,               F_RN)  \
-  do_intrinsic(_putInt,             jdk_internal_misc_Unsafe,     putInt_name, putInt_signature,                 F_RN)  \
-  do_intrinsic(_putLong,            jdk_internal_misc_Unsafe,     putLong_name, putLong_signature,               F_RN)  \
-  do_intrinsic(_putFloat,           jdk_internal_misc_Unsafe,     putFloat_name, putFloat_signature,             F_RN)  \
-  do_intrinsic(_putDouble,          jdk_internal_misc_Unsafe,     putDouble_name, putDouble_signature,           F_RN)  \
-                                                                                                                        \
-  do_name(getReferenceVolatile_name,"getReferenceVolatile")   do_name(putReferenceVolatile_name,"putReferenceVolatile") \
-  do_name(getBooleanVolatile_name,"getBooleanVolatile")       do_name(putBooleanVolatile_name,"putBooleanVolatile")     \
-  do_name(getByteVolatile_name,"getByteVolatile")             do_name(putByteVolatile_name,"putByteVolatile")           \
-  do_name(getShortVolatile_name,"getShortVolatile")           do_name(putShortVolatile_name,"putShortVolatile")         \
-  do_name(getCharVolatile_name,"getCharVolatile")             do_name(putCharVolatile_name,"putCharVolatile")           \
-  do_name(getIntVolatile_name,"getIntVolatile")               do_name(putIntVolatile_name,"putIntVolatile")             \
-  do_name(getLongVolatile_name,"getLongVolatile")             do_name(putLongVolatile_name,"putLongVolatile")           \
-  do_name(getFloatVolatile_name,"getFloatVolatile")           do_name(putFloatVolatile_name,"putFloatVolatile")         \
-  do_name(getDoubleVolatile_name,"getDoubleVolatile")         do_name(putDoubleVolatile_name,"putDoubleVolatile")       \
-                                                                                                                        \
-  do_intrinsic(_getReferenceVolatile,     jdk_internal_misc_Unsafe,     getReferenceVolatile_name, getReference_signature, F_RN)  \
-  do_intrinsic(_getBooleanVolatile,       jdk_internal_misc_Unsafe,     getBooleanVolatile_name, getBoolean_signature,     F_RN)  \
-  do_intrinsic(_getByteVolatile,          jdk_internal_misc_Unsafe,     getByteVolatile_name, getByte_signature,           F_RN)  \
-  do_intrinsic(_getShortVolatile,         jdk_internal_misc_Unsafe,     getShortVolatile_name, getShort_signature,         F_RN)  \
-  do_intrinsic(_getCharVolatile,          jdk_internal_misc_Unsafe,     getCharVolatile_name, getChar_signature,           F_RN)  \
-  do_intrinsic(_getIntVolatile,           jdk_internal_misc_Unsafe,     getIntVolatile_name, getInt_signature,             F_RN)  \
-  do_intrinsic(_getLongVolatile,          jdk_internal_misc_Unsafe,     getLongVolatile_name, getLong_signature,           F_RN)  \
-  do_intrinsic(_getFloatVolatile,         jdk_internal_misc_Unsafe,     getFloatVolatile_name, getFloat_signature,         F_RN)  \
-  do_intrinsic(_getDoubleVolatile,        jdk_internal_misc_Unsafe,     getDoubleVolatile_name, getDouble_signature,       F_RN)  \
-  do_intrinsic(_putReferenceVolatile,     jdk_internal_misc_Unsafe,     putReferenceVolatile_name, putReference_signature, F_RN)  \
-  do_intrinsic(_putBooleanVolatile,       jdk_internal_misc_Unsafe,     putBooleanVolatile_name, putBoolean_signature,     F_RN)  \
-  do_intrinsic(_putByteVolatile,          jdk_internal_misc_Unsafe,     putByteVolatile_name, putByte_signature,           F_RN)  \
-  do_intrinsic(_putShortVolatile,         jdk_internal_misc_Unsafe,     putShortVolatile_name, putShort_signature,         F_RN)  \
-  do_intrinsic(_putCharVolatile,          jdk_internal_misc_Unsafe,     putCharVolatile_name, putChar_signature,           F_RN)  \
-  do_intrinsic(_putIntVolatile,           jdk_internal_misc_Unsafe,     putIntVolatile_name, putInt_signature,             F_RN)  \
-  do_intrinsic(_putLongVolatile,          jdk_internal_misc_Unsafe,     putLongVolatile_name, putLong_signature,           F_RN)  \
-  do_intrinsic(_putFloatVolatile,         jdk_internal_misc_Unsafe,     putFloatVolatile_name, putFloat_signature,         F_RN)  \
-  do_intrinsic(_putDoubleVolatile,        jdk_internal_misc_Unsafe,     putDoubleVolatile_name, putDouble_signature,       F_RN)  \
-                                                                                                                        \
-  do_name(getReferenceOpaque_name,"getReferenceOpaque") do_name(putReferenceOpaque_name,"putReferenceOpaque")           \
-  do_name(getBooleanOpaque_name,"getBooleanOpaque")     do_name(putBooleanOpaque_name,"putBooleanOpaque")               \
-  do_name(getByteOpaque_name,"getByteOpaque")           do_name(putByteOpaque_name,"putByteOpaque")                     \
-  do_name(getShortOpaque_name,"getShortOpaque")         do_name(putShortOpaque_name,"putShortOpaque")                   \
-  do_name(getCharOpaque_name,"getCharOpaque")           do_name(putCharOpaque_name,"putCharOpaque")                     \
-  do_name(getIntOpaque_name,"getIntOpaque")             do_name(putIntOpaque_name,"putIntOpaque")                       \
-  do_name(getLongOpaque_name,"getLongOpaque")           do_name(putLongOpaque_name,"putLongOpaque")                     \
-  do_name(getFloatOpaque_name,"getFloatOpaque")         do_name(putFloatOpaque_name,"putFloatOpaque")                   \
-  do_name(getDoubleOpaque_name,"getDoubleOpaque")       do_name(putDoubleOpaque_name,"putDoubleOpaque")                 \
-                                                                                                                        \
-  do_intrinsic(_getReferenceOpaque,       jdk_internal_misc_Unsafe,        getReferenceOpaque_name, getReference_signature, F_R)  \
-  do_intrinsic(_getBooleanOpaque,         jdk_internal_misc_Unsafe,        getBooleanOpaque_name, getBoolean_signature,     F_R)  \
-  do_intrinsic(_getByteOpaque,            jdk_internal_misc_Unsafe,        getByteOpaque_name, getByte_signature,           F_R)  \
-  do_intrinsic(_getShortOpaque,           jdk_internal_misc_Unsafe,        getShortOpaque_name, getShort_signature,         F_R)  \
-  do_intrinsic(_getCharOpaque,            jdk_internal_misc_Unsafe,        getCharOpaque_name, getChar_signature,           F_R)  \
-  do_intrinsic(_getIntOpaque,             jdk_internal_misc_Unsafe,        getIntOpaque_name, getInt_signature,             F_R)  \
-  do_intrinsic(_getLongOpaque,            jdk_internal_misc_Unsafe,        getLongOpaque_name, getLong_signature,           F_R)  \
-  do_intrinsic(_getFloatOpaque,           jdk_internal_misc_Unsafe,        getFloatOpaque_name, getFloat_signature,         F_R)  \
-  do_intrinsic(_getDoubleOpaque,          jdk_internal_misc_Unsafe,        getDoubleOpaque_name, getDouble_signature,       F_R)  \
-  do_intrinsic(_putReferenceOpaque,       jdk_internal_misc_Unsafe,        putReferenceOpaque_name, putReference_signature, F_R)  \
-  do_intrinsic(_putBooleanOpaque,         jdk_internal_misc_Unsafe,        putBooleanOpaque_name, putBoolean_signature,     F_R)  \
-  do_intrinsic(_putByteOpaque,            jdk_internal_misc_Unsafe,        putByteOpaque_name, putByte_signature,           F_R)  \
-  do_intrinsic(_putShortOpaque,           jdk_internal_misc_Unsafe,        putShortOpaque_name, putShort_signature,         F_R)  \
-  do_intrinsic(_putCharOpaque,            jdk_internal_misc_Unsafe,        putCharOpaque_name, putChar_signature,           F_R)  \
-  do_intrinsic(_putIntOpaque,             jdk_internal_misc_Unsafe,        putIntOpaque_name, putInt_signature,             F_R)  \
-  do_intrinsic(_putLongOpaque,            jdk_internal_misc_Unsafe,        putLongOpaque_name, putLong_signature,           F_R)  \
-  do_intrinsic(_putFloatOpaque,           jdk_internal_misc_Unsafe,        putFloatOpaque_name, putFloat_signature,         F_R)  \
-  do_intrinsic(_putDoubleOpaque,          jdk_internal_misc_Unsafe,        putDoubleOpaque_name, putDouble_signature,       F_R)  \
-                                                                                                                        \
-  do_name(getReferenceAcquire_name,  "getReferenceAcquire") do_name(putReferenceRelease_name,  "putReferenceRelease")   \
-  do_name(getBooleanAcquire_name, "getBooleanAcquire")      do_name(putBooleanRelease_name, "putBooleanRelease")        \
-  do_name(getByteAcquire_name,    "getByteAcquire")         do_name(putByteRelease_name,    "putByteRelease")           \
-  do_name(getShortAcquire_name,   "getShortAcquire")        do_name(putShortRelease_name,   "putShortRelease")          \
-  do_name(getCharAcquire_name,    "getCharAcquire")         do_name(putCharRelease_name,    "putCharRelease")           \
-  do_name(getIntAcquire_name,     "getIntAcquire")          do_name(putIntRelease_name,     "putIntRelease")            \
-  do_name(getLongAcquire_name,    "getLongAcquire")         do_name(putLongRelease_name,    "putLongRelease")           \
-  do_name(getFloatAcquire_name,   "getFloatAcquire")        do_name(putFloatRelease_name,   "putFloatRelease")          \
-  do_name(getDoubleAcquire_name,  "getDoubleAcquire")       do_name(putDoubleRelease_name,  "putDoubleRelease")         \
-                                                                                                                        \
-  do_intrinsic(_getReferenceAcquire,     jdk_internal_misc_Unsafe,        getReferenceAcquire_name, getReference_signature, F_R)  \
-  do_intrinsic(_getBooleanAcquire,       jdk_internal_misc_Unsafe,        getBooleanAcquire_name, getBoolean_signature,     F_R)  \
-  do_intrinsic(_getByteAcquire,          jdk_internal_misc_Unsafe,        getByteAcquire_name, getByte_signature,           F_R)  \
-  do_intrinsic(_getShortAcquire,         jdk_internal_misc_Unsafe,        getShortAcquire_name, getShort_signature,         F_R)  \
-  do_intrinsic(_getCharAcquire,          jdk_internal_misc_Unsafe,        getCharAcquire_name, getChar_signature,           F_R)  \
-  do_intrinsic(_getIntAcquire,           jdk_internal_misc_Unsafe,        getIntAcquire_name, getInt_signature,             F_R)  \
-  do_intrinsic(_getLongAcquire,          jdk_internal_misc_Unsafe,        getLongAcquire_name, getLong_signature,           F_R)  \
-  do_intrinsic(_getFloatAcquire,         jdk_internal_misc_Unsafe,        getFloatAcquire_name, getFloat_signature,         F_R)  \
-  do_intrinsic(_getDoubleAcquire,        jdk_internal_misc_Unsafe,        getDoubleAcquire_name, getDouble_signature,       F_R)  \
-  do_intrinsic(_putReferenceRelease,     jdk_internal_misc_Unsafe,        putReferenceRelease_name, putReference_signature, F_R)  \
-  do_intrinsic(_putBooleanRelease,       jdk_internal_misc_Unsafe,        putBooleanRelease_name, putBoolean_signature,     F_R)  \
-  do_intrinsic(_putByteRelease,          jdk_internal_misc_Unsafe,        putByteRelease_name, putByte_signature,           F_R)  \
-  do_intrinsic(_putShortRelease,         jdk_internal_misc_Unsafe,        putShortRelease_name, putShort_signature,         F_R)  \
-  do_intrinsic(_putCharRelease,          jdk_internal_misc_Unsafe,        putCharRelease_name, putChar_signature,           F_R)  \
-  do_intrinsic(_putIntRelease,           jdk_internal_misc_Unsafe,        putIntRelease_name, putInt_signature,             F_R)  \
-  do_intrinsic(_putLongRelease,          jdk_internal_misc_Unsafe,        putLongRelease_name, putLong_signature,           F_R)  \
-  do_intrinsic(_putFloatRelease,         jdk_internal_misc_Unsafe,        putFloatRelease_name, putFloat_signature,         F_R)  \
-  do_intrinsic(_putDoubleRelease,        jdk_internal_misc_Unsafe,        putDoubleRelease_name, putDouble_signature,       F_R)  \
-                                                                                                                        \
-  do_name(getShortUnaligned_name,"getShortUnaligned")     do_name(putShortUnaligned_name,"putShortUnaligned")           \
-  do_name(getCharUnaligned_name,"getCharUnaligned")       do_name(putCharUnaligned_name,"putCharUnaligned")             \
-  do_name(getIntUnaligned_name,"getIntUnaligned")         do_name(putIntUnaligned_name,"putIntUnaligned")               \
-  do_name(getLongUnaligned_name,"getLongUnaligned")       do_name(putLongUnaligned_name,"putLongUnaligned")             \
-                                                                                                                        \
-  do_intrinsic(_getShortUnaligned,         jdk_internal_misc_Unsafe,    getShortUnaligned_name, getShort_signature,     F_R)  \
-  do_intrinsic(_getCharUnaligned,          jdk_internal_misc_Unsafe,    getCharUnaligned_name, getChar_signature,       F_R)  \
-  do_intrinsic(_getIntUnaligned,           jdk_internal_misc_Unsafe,    getIntUnaligned_name, getInt_signature,         F_R)  \
-  do_intrinsic(_getLongUnaligned,          jdk_internal_misc_Unsafe,    getLongUnaligned_name, getLong_signature,       F_R)  \
-  do_intrinsic(_putShortUnaligned,         jdk_internal_misc_Unsafe,    putShortUnaligned_name, putShort_signature,     F_R)  \
-  do_intrinsic(_putCharUnaligned,          jdk_internal_misc_Unsafe,    putCharUnaligned_name, putChar_signature,       F_R)  \
-  do_intrinsic(_putIntUnaligned,           jdk_internal_misc_Unsafe,    putIntUnaligned_name, putInt_signature,         F_R)  \
-  do_intrinsic(_putLongUnaligned,          jdk_internal_misc_Unsafe,    putLongUnaligned_name, putLong_signature,       F_R)  \
-                                                                                                                        \
-  do_signature(compareAndSetReference_signature,      "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z")        \
-  do_signature(compareAndExchangeReference_signature, "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;") \
-  do_signature(compareAndSetLong_signature,        "(Ljava/lang/Object;JJJ)Z")                                          \
-  do_signature(compareAndExchangeLong_signature,   "(Ljava/lang/Object;JJJ)J")                                          \
-  do_signature(compareAndSetInt_signature,         "(Ljava/lang/Object;JII)Z")                                          \
-  do_signature(compareAndExchangeInt_signature,    "(Ljava/lang/Object;JII)I")                                          \
-  do_signature(compareAndSetByte_signature,        "(Ljava/lang/Object;JBB)Z")                                          \
-  do_signature(compareAndExchangeByte_signature,   "(Ljava/lang/Object;JBB)B")                                          \
-  do_signature(compareAndSetShort_signature,       "(Ljava/lang/Object;JSS)Z")                                          \
-  do_signature(compareAndExchangeShort_signature,  "(Ljava/lang/Object;JSS)S")                                          \
-                                                                                                                        \
-  do_name(compareAndSetReference_name,              "compareAndSetReference")                                           \
-  do_name(compareAndExchangeReference_name,         "compareAndExchangeReference")                                      \
-  do_name(compareAndExchangeReferenceAcquire_name,  "compareAndExchangeReferenceAcquire")                               \
-  do_name(compareAndExchangeReferenceRelease_name,  "compareAndExchangeReferenceRelease")                               \
-  do_name(compareAndSetLong_name,                   "compareAndSetLong")                                                \
-  do_name(compareAndExchangeLong_name,              "compareAndExchangeLong")                                           \
-  do_name(compareAndExchangeLongAcquire_name,       "compareAndExchangeLongAcquire")                                    \
-  do_name(compareAndExchangeLongRelease_name,       "compareAndExchangeLongRelease")                                    \
-  do_name(compareAndSetInt_name,                    "compareAndSetInt")                                                 \
-  do_name(compareAndExchangeInt_name,               "compareAndExchangeInt")                                            \
-  do_name(compareAndExchangeIntAcquire_name,        "compareAndExchangeIntAcquire")                                     \
-  do_name(compareAndExchangeIntRelease_name,        "compareAndExchangeIntRelease")                                     \
-  do_name(compareAndSetByte_name,                   "compareAndSetByte")                                                \
-  do_name(compareAndExchangeByte_name,              "compareAndExchangeByte")                                           \
-  do_name(compareAndExchangeByteAcquire_name,       "compareAndExchangeByteAcquire")                                    \
-  do_name(compareAndExchangeByteRelease_name,       "compareAndExchangeByteRelease")                                    \
-  do_name(compareAndSetShort_name,                  "compareAndSetShort")                                               \
-  do_name(compareAndExchangeShort_name,             "compareAndExchangeShort")                                          \
-  do_name(compareAndExchangeShortAcquire_name,      "compareAndExchangeShortAcquire")                                   \
-  do_name(compareAndExchangeShortRelease_name,      "compareAndExchangeShortRelease")                                   \
-                                                                                                                        \
-  do_name(weakCompareAndSetReferencePlain_name,     "weakCompareAndSetReferencePlain")                                  \
-  do_name(weakCompareAndSetReferenceAcquire_name,   "weakCompareAndSetReferenceAcquire")                                \
-  do_name(weakCompareAndSetReferenceRelease_name,   "weakCompareAndSetReferenceRelease")                                \
-  do_name(weakCompareAndSetReference_name,          "weakCompareAndSetReference")                                       \
-  do_name(weakCompareAndSetLongPlain_name,          "weakCompareAndSetLongPlain")                                       \
-  do_name(weakCompareAndSetLongAcquire_name,        "weakCompareAndSetLongAcquire")                                     \
-  do_name(weakCompareAndSetLongRelease_name,        "weakCompareAndSetLongRelease")                                     \
-  do_name(weakCompareAndSetLong_name,               "weakCompareAndSetLong")                                            \
-  do_name(weakCompareAndSetIntPlain_name,           "weakCompareAndSetIntPlain")                                        \
-  do_name(weakCompareAndSetIntAcquire_name,         "weakCompareAndSetIntAcquire")                                      \
-  do_name(weakCompareAndSetIntRelease_name,         "weakCompareAndSetIntRelease")                                      \
-  do_name(weakCompareAndSetInt_name,                "weakCompareAndSetInt")                                             \
-  do_name(weakCompareAndSetBytePlain_name,          "weakCompareAndSetBytePlain")                                       \
-  do_name(weakCompareAndSetByteAcquire_name,        "weakCompareAndSetByteAcquire")                                     \
-  do_name(weakCompareAndSetByteRelease_name,        "weakCompareAndSetByteRelease")                                     \
-  do_name(weakCompareAndSetByte_name,               "weakCompareAndSetByte")                                            \
-  do_name(weakCompareAndSetShortPlain_name,         "weakCompareAndSetShortPlain")                                      \
-  do_name(weakCompareAndSetShortAcquire_name,       "weakCompareAndSetShortAcquire")                                    \
-  do_name(weakCompareAndSetShortRelease_name,       "weakCompareAndSetShortRelease")                                    \
-  do_name(weakCompareAndSetShort_name,              "weakCompareAndSetShort")                                           \
-                                                                                                                        \
-  do_intrinsic(_compareAndSetReference,              jdk_internal_misc_Unsafe,  compareAndSetReference_name,              compareAndSetReference_signature,      F_RN) \
-  do_intrinsic(_compareAndExchangeReference,         jdk_internal_misc_Unsafe,  compareAndExchangeReference_name,         compareAndExchangeReference_signature, F_RN) \
-  do_intrinsic(_compareAndExchangeReferenceAcquire,  jdk_internal_misc_Unsafe,  compareAndExchangeReferenceAcquire_name,  compareAndExchangeReference_signature, F_R)  \
-  do_intrinsic(_compareAndExchangeReferenceRelease,  jdk_internal_misc_Unsafe,  compareAndExchangeReferenceRelease_name,  compareAndExchangeReference_signature, F_R)  \
-  do_intrinsic(_compareAndSetLong,                jdk_internal_misc_Unsafe,  compareAndSetLong_name,                compareAndSetLong_signature,        F_RN) \
-  do_intrinsic(_compareAndExchangeLong,           jdk_internal_misc_Unsafe,  compareAndExchangeLong_name,           compareAndExchangeLong_signature,   F_RN) \
-  do_intrinsic(_compareAndExchangeLongAcquire,    jdk_internal_misc_Unsafe,  compareAndExchangeLongAcquire_name,    compareAndExchangeLong_signature,   F_R)  \
-  do_intrinsic(_compareAndExchangeLongRelease,    jdk_internal_misc_Unsafe,  compareAndExchangeLongRelease_name,    compareAndExchangeLong_signature,   F_R)  \
-  do_intrinsic(_compareAndSetInt,                 jdk_internal_misc_Unsafe,  compareAndSetInt_name,                 compareAndSetInt_signature,         F_RN) \
-  do_intrinsic(_compareAndExchangeInt,            jdk_internal_misc_Unsafe,  compareAndExchangeInt_name,            compareAndExchangeInt_signature,    F_RN) \
-  do_intrinsic(_compareAndExchangeIntAcquire,     jdk_internal_misc_Unsafe,  compareAndExchangeIntAcquire_name,     compareAndExchangeInt_signature,    F_R)  \
-  do_intrinsic(_compareAndExchangeIntRelease,     jdk_internal_misc_Unsafe,  compareAndExchangeIntRelease_name,     compareAndExchangeInt_signature,    F_R)  \
-  do_intrinsic(_compareAndSetByte,                jdk_internal_misc_Unsafe,  compareAndSetByte_name,                compareAndSetByte_signature,        F_R)  \
-  do_intrinsic(_compareAndExchangeByte,           jdk_internal_misc_Unsafe,  compareAndExchangeByte_name,           compareAndExchangeByte_signature,   F_R)  \
-  do_intrinsic(_compareAndExchangeByteAcquire,    jdk_internal_misc_Unsafe,  compareAndExchangeByteAcquire_name,    compareAndExchangeByte_signature,   F_R)  \
-  do_intrinsic(_compareAndExchangeByteRelease,    jdk_internal_misc_Unsafe,  compareAndExchangeByteRelease_name,    compareAndExchangeByte_signature,   F_R)  \
-  do_intrinsic(_compareAndSetShort,               jdk_internal_misc_Unsafe,  compareAndSetShort_name,               compareAndSetShort_signature,       F_R)  \
-  do_intrinsic(_compareAndExchangeShort,          jdk_internal_misc_Unsafe,  compareAndExchangeShort_name,          compareAndExchangeShort_signature,  F_R)  \
-  do_intrinsic(_compareAndExchangeShortAcquire,   jdk_internal_misc_Unsafe,  compareAndExchangeShortAcquire_name,   compareAndExchangeShort_signature,  F_R)  \
-  do_intrinsic(_compareAndExchangeShortRelease,   jdk_internal_misc_Unsafe,  compareAndExchangeShortRelease_name,   compareAndExchangeShort_signature,  F_R)  \
-                                                                                                                                                             \
-  do_intrinsic(_weakCompareAndSetReferencePlain,  jdk_internal_misc_Unsafe,  weakCompareAndSetReferencePlain_name,     compareAndSetReference_signature,      F_R) \
-  do_intrinsic(_weakCompareAndSetReferenceAcquire,jdk_internal_misc_Unsafe,  weakCompareAndSetReferenceAcquire_name,   compareAndSetReference_signature,      F_R) \
-  do_intrinsic(_weakCompareAndSetReferenceRelease,jdk_internal_misc_Unsafe,  weakCompareAndSetReferenceRelease_name,   compareAndSetReference_signature,      F_R) \
-  do_intrinsic(_weakCompareAndSetReference,       jdk_internal_misc_Unsafe,  weakCompareAndSetReference_name,          compareAndSetReference_signature,      F_R) \
-  do_intrinsic(_weakCompareAndSetLongPlain,       jdk_internal_misc_Unsafe,  weakCompareAndSetLongPlain_name,       compareAndSetLong_signature,        F_R) \
-  do_intrinsic(_weakCompareAndSetLongAcquire,     jdk_internal_misc_Unsafe,  weakCompareAndSetLongAcquire_name,     compareAndSetLong_signature,        F_R) \
-  do_intrinsic(_weakCompareAndSetLongRelease,     jdk_internal_misc_Unsafe,  weakCompareAndSetLongRelease_name,     compareAndSetLong_signature,        F_R) \
-  do_intrinsic(_weakCompareAndSetLong,            jdk_internal_misc_Unsafe,  weakCompareAndSetLong_name,            compareAndSetLong_signature,        F_R) \
-  do_intrinsic(_weakCompareAndSetIntPlain,        jdk_internal_misc_Unsafe,  weakCompareAndSetIntPlain_name,        compareAndSetInt_signature,         F_R) \
-  do_intrinsic(_weakCompareAndSetIntAcquire,      jdk_internal_misc_Unsafe,  weakCompareAndSetIntAcquire_name,      compareAndSetInt_signature,         F_R) \
-  do_intrinsic(_weakCompareAndSetIntRelease,      jdk_internal_misc_Unsafe,  weakCompareAndSetIntRelease_name,      compareAndSetInt_signature,         F_R) \
-  do_intrinsic(_weakCompareAndSetInt,             jdk_internal_misc_Unsafe,  weakCompareAndSetInt_name,             compareAndSetInt_signature,         F_R) \
-  do_intrinsic(_weakCompareAndSetBytePlain,       jdk_internal_misc_Unsafe,  weakCompareAndSetBytePlain_name,       compareAndSetByte_signature,        F_R) \
-  do_intrinsic(_weakCompareAndSetByteAcquire,     jdk_internal_misc_Unsafe,  weakCompareAndSetByteAcquire_name,     compareAndSetByte_signature,        F_R) \
-  do_intrinsic(_weakCompareAndSetByteRelease,     jdk_internal_misc_Unsafe,  weakCompareAndSetByteRelease_name,     compareAndSetByte_signature,        F_R) \
-  do_intrinsic(_weakCompareAndSetByte,            jdk_internal_misc_Unsafe,  weakCompareAndSetByte_name,            compareAndSetByte_signature,        F_R) \
-  do_intrinsic(_weakCompareAndSetShortPlain,      jdk_internal_misc_Unsafe,  weakCompareAndSetShortPlain_name,      compareAndSetShort_signature,       F_R) \
-  do_intrinsic(_weakCompareAndSetShortAcquire,    jdk_internal_misc_Unsafe,  weakCompareAndSetShortAcquire_name,    compareAndSetShort_signature,       F_R) \
-  do_intrinsic(_weakCompareAndSetShortRelease,    jdk_internal_misc_Unsafe,  weakCompareAndSetShortRelease_name,    compareAndSetShort_signature,       F_R) \
-  do_intrinsic(_weakCompareAndSetShort,           jdk_internal_misc_Unsafe,  weakCompareAndSetShort_name,           compareAndSetShort_signature,       F_R) \
-                           \
-  do_intrinsic(_getAndAddInt,             jdk_internal_misc_Unsafe,     getAndAddInt_name, getAndAddInt_signature, F_R)       \
-   do_name(     getAndAddInt_name,                                      "getAndAddInt")                                       \
-   do_signature(getAndAddInt_signature,                                 "(Ljava/lang/Object;JI)I" )                           \
-  do_intrinsic(_getAndAddLong,            jdk_internal_misc_Unsafe,     getAndAddLong_name, getAndAddLong_signature, F_R)     \
-   do_name(     getAndAddLong_name,                                     "getAndAddLong")                                      \
-   do_signature(getAndAddLong_signature,                                "(Ljava/lang/Object;JJ)J" )                           \
-  do_intrinsic(_getAndAddByte,            jdk_internal_misc_Unsafe,     getAndAddByte_name, getAndAddByte_signature, F_R)     \
-   do_name(     getAndAddByte_name,                                     "getAndAddByte")                                      \
-   do_signature(getAndAddByte_signature,                                "(Ljava/lang/Object;JB)B" )                           \
-  do_intrinsic(_getAndAddShort,           jdk_internal_misc_Unsafe,     getAndAddShort_name, getAndAddShort_signature, F_R)   \
-   do_name(     getAndAddShort_name,                                    "getAndAddShort")                                     \
-   do_signature(getAndAddShort_signature,                               "(Ljava/lang/Object;JS)S" )                           \
-  do_intrinsic(_getAndSetInt,             jdk_internal_misc_Unsafe,     getAndSetInt_name, getAndSetInt_signature, F_R)       \
-   do_name(     getAndSetInt_name,                                      "getAndSetInt")                                       \
-   do_alias(    getAndSetInt_signature,                                 /*"(Ljava/lang/Object;JI)I"*/ getAndAddInt_signature)   \
-  do_intrinsic(_getAndSetLong,            jdk_internal_misc_Unsafe,     getAndSetLong_name, getAndSetLong_signature, F_R)     \
-   do_name(     getAndSetLong_name,                                     "getAndSetLong")                                      \
-   do_alias(    getAndSetLong_signature,                                /*"(Ljava/lang/Object;JJ)J"*/ getAndAddLong_signature)  \
-  do_intrinsic(_getAndSetByte,            jdk_internal_misc_Unsafe,     getAndSetByte_name, getAndSetByte_signature, F_R)     \
-   do_name(     getAndSetByte_name,                                     "getAndSetByte")                                      \
-   do_alias(    getAndSetByte_signature,                                /*"(Ljava/lang/Object;JB)B"*/ getAndAddByte_signature)  \
-  do_intrinsic(_getAndSetShort,           jdk_internal_misc_Unsafe,     getAndSetShort_name, getAndSetShort_signature, F_R)   \
-   do_name(     getAndSetShort_name,                                    "getAndSetShort")                                     \
-   do_alias(    getAndSetShort_signature,                               /*"(Ljava/lang/Object;JS)S"*/ getAndAddShort_signature) \
-  do_intrinsic(_getAndSetReference,       jdk_internal_misc_Unsafe,     getAndSetReference_name, getAndSetReference_signature, F_R) \
-   do_name(     getAndSetReference_name,                                "getAndSetReference")                                  \
-   do_signature(getAndSetReference_signature,                           "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \
-                                                                                                                               \
-   /* (2) Bytecode intrinsics                                                                        */                        \
-                                                                                                                               \
-  do_intrinsic(_park,                     jdk_internal_misc_Unsafe,     park_name, park_signature,                     F_R)    \
-   do_name(     park_name,                                              "park")                                                \
-   do_signature(park_signature,                                         "(ZJ)V")                                               \
-  do_intrinsic(_unpark,                   jdk_internal_misc_Unsafe,     unpark_name, unpark_signature,                 F_R)    \
-   do_name(     unpark_name,                                            "unpark")                                              \
-   do_alias(    unpark_signature,                                       /*(LObject;)V*/ object_void_signature)                 \
-                                                                                                                               \
-  do_intrinsic(_StringBuilder_void,   java_lang_StringBuilder, object_initializer_name, void_method_signature,     F_R)   \
-  do_intrinsic(_StringBuilder_int,    java_lang_StringBuilder, object_initializer_name, int_void_signature,        F_R)   \
-  do_intrinsic(_StringBuilder_String, java_lang_StringBuilder, object_initializer_name, string_void_signature,     F_R)   \
-                                                                                                                          \
-  do_intrinsic(_StringBuilder_append_char,   java_lang_StringBuilder, append_name, char_StringBuilder_signature,   F_R)   \
-  do_intrinsic(_StringBuilder_append_int,    java_lang_StringBuilder, append_name, int_StringBuilder_signature,    F_R)   \
-  do_intrinsic(_StringBuilder_append_String, java_lang_StringBuilder, append_name, String_StringBuilder_signature, F_R)   \
-                                                                                                                          \
-  do_intrinsic(_StringBuilder_toString, java_lang_StringBuilder, toString_name, void_string_signature,             F_R)   \
-                                                                                                                          \
-  do_intrinsic(_StringBuffer_void,   java_lang_StringBuffer, object_initializer_name, void_method_signature,       F_R)   \
-  do_intrinsic(_StringBuffer_int,    java_lang_StringBuffer, object_initializer_name, int_void_signature,          F_R)   \
-  do_intrinsic(_StringBuffer_String, java_lang_StringBuffer, object_initializer_name, string_void_signature,       F_R)   \
-                                                                                                                          \
-  do_intrinsic(_StringBuffer_append_char,   java_lang_StringBuffer, append_name, char_StringBuffer_signature,      F_Y)   \
-  do_intrinsic(_StringBuffer_append_int,    java_lang_StringBuffer, append_name, int_StringBuffer_signature,       F_Y)   \
-  do_intrinsic(_StringBuffer_append_String, java_lang_StringBuffer, append_name, String_StringBuffer_signature,    F_Y)   \
-                                                                                                                          \
-  do_intrinsic(_StringBuffer_toString,  java_lang_StringBuffer, toString_name, void_string_signature,              F_Y)   \
-                                                                                                                          \
-  do_intrinsic(_Integer_toString,      java_lang_Integer, toString_name, int_String_signature,                     F_S)   \
-                                                                                                                          \
-  do_intrinsic(_String_String, java_lang_String, object_initializer_name, string_void_signature,                   F_R)   \
-                                                                                                                          \
-  do_intrinsic(_Object_init,              java_lang_Object, object_initializer_name, void_method_signature,        F_R)   \
-  /*    (symbol object_initializer_name defined above) */                                                                 \
-                                                                                                                          \
-  do_intrinsic(_invoke,                   java_lang_reflect_Method, invoke_name, object_object_array_object_signature, F_R) \
-  /*   (symbols invoke_name and invoke_signature defined above) */                                                      \
-  /* the polymorphic MH intrinsics must be in compact order, with _invokeGeneric first and _linkToInterface last */     \
-  do_intrinsic(_invokeGeneric,            java_lang_invoke_MethodHandle, invoke_name,           star_name, F_RN)        \
-  do_intrinsic(_invokeBasic,              java_lang_invoke_MethodHandle, invokeBasic_name,      star_name, F_RN)        \
-  do_intrinsic(_linkToVirtual,            java_lang_invoke_MethodHandle, linkToVirtual_name,    star_name, F_SN)        \
-  do_intrinsic(_linkToStatic,             java_lang_invoke_MethodHandle, linkToStatic_name,     star_name, F_SN)        \
-  do_intrinsic(_linkToSpecial,            java_lang_invoke_MethodHandle, linkToSpecial_name,    star_name, F_SN)        \
-  do_intrinsic(_linkToInterface,          java_lang_invoke_MethodHandle, linkToInterface_name,  star_name, F_SN)        \
-  /* special marker for bytecode generated for the JVM from a LambdaForm: */                                            \
-  do_intrinsic(_compiledLambdaForm,       java_lang_invoke_MethodHandle, compiledLambdaForm_name, star_name, F_RN)      \
-                                                                                                                        \
-  /* unboxing methods: */                                                                                               \
-  do_intrinsic(_booleanValue,             java_lang_Boolean,      booleanValue_name, void_boolean_signature, F_R)       \
-   do_name(     booleanValue_name,       "booleanValue")                                                                \
-  do_intrinsic(_byteValue,                java_lang_Byte,         byteValue_name, void_byte_signature, F_R)             \
-   do_name(     byteValue_name,          "byteValue")                                                                   \
-  do_intrinsic(_charValue,                java_lang_Character,    charValue_name, void_char_signature, F_R)             \
-   do_name(     charValue_name,          "charValue")                                                                   \
-  do_intrinsic(_shortValue,               java_lang_Short,        shortValue_name, void_short_signature, F_R)           \
-   do_name(     shortValue_name,         "shortValue")                                                                  \
-  do_intrinsic(_intValue,                 java_lang_Integer,      intValue_name, void_int_signature, F_R)               \
-   do_name(     intValue_name,           "intValue")                                                                    \
-  do_intrinsic(_longValue,                java_lang_Long,         longValue_name, void_long_signature, F_R)             \
-   do_name(     longValue_name,          "longValue")                                                                   \
-  do_intrinsic(_floatValue,               java_lang_Float,        floatValue_name, void_float_signature, F_R)           \
-   do_name(     floatValue_name,         "floatValue")                                                                  \
-  do_intrinsic(_doubleValue,              java_lang_Double,       doubleValue_name, void_double_signature, F_R)         \
-   do_name(     doubleValue_name,        "doubleValue")                                                                 \
-                                                                                                                        \
-  /* boxing methods: */                                                                                                 \
-   do_name(    valueOf_name,              "valueOf")                                                                    \
-  do_intrinsic(_Boolean_valueOf,          java_lang_Boolean,      valueOf_name, Boolean_valueOf_signature, F_S)         \
-   do_name(     Boolean_valueOf_signature,                       "(Z)Ljava/lang/Boolean;")                              \
-  do_intrinsic(_Byte_valueOf,             java_lang_Byte,         valueOf_name, Byte_valueOf_signature, F_S)            \
-   do_name(     Byte_valueOf_signature,                          "(B)Ljava/lang/Byte;")                                 \
-  do_intrinsic(_Character_valueOf,        java_lang_Character,    valueOf_name, Character_valueOf_signature, F_S)       \
-   do_name(     Character_valueOf_signature,                     "(C)Ljava/lang/Character;")                            \
-  do_intrinsic(_Short_valueOf,            java_lang_Short,        valueOf_name, Short_valueOf_signature, F_S)           \
-   do_name(     Short_valueOf_signature,                         "(S)Ljava/lang/Short;")                                \
-  do_intrinsic(_Integer_valueOf,          java_lang_Integer,      valueOf_name, Integer_valueOf_signature, F_S)         \
-   do_name(     Integer_valueOf_signature,                       "(I)Ljava/lang/Integer;")                              \
-  do_intrinsic(_Long_valueOf,             java_lang_Long,         valueOf_name, Long_valueOf_signature, F_S)            \
-   do_name(     Long_valueOf_signature,                          "(J)Ljava/lang/Long;")                                 \
-  do_intrinsic(_Float_valueOf,            java_lang_Float,        valueOf_name, Float_valueOf_signature, F_S)           \
-   do_name(     Float_valueOf_signature,                         "(F)Ljava/lang/Float;")                                \
-  do_intrinsic(_Double_valueOf,           java_lang_Double,       valueOf_name, Double_valueOf_signature, F_S)          \
-   do_name(     Double_valueOf_signature,                        "(D)Ljava/lang/Double;")                               \
-                                                                                                                        \
-  /* forEachRemaining */                                                                             \
-  do_intrinsic(_forEachRemaining, java_util_stream_StreamsRangeIntSpliterator, forEachRemaining_name, forEachRemaining_signature, F_R) \
-   do_name(     forEachRemaining_name,    "forEachRemaining")                                                           \
-   do_name(     forEachRemaining_signature,                      "(Ljava/util/function/IntConsumer;)V")                 \
-
-    /*end*/
-
-
 
 
 // Class vmSymbols
diff --git a/src/hotspot/share/code/codeCache.cpp b/src/hotspot/share/code/codeCache.cpp
index b9a63dbd97f..3b589844232 100644
--- a/src/hotspot/share/code/codeCache.cpp
+++ b/src/hotspot/share/code/codeCache.cpp
@@ -49,6 +49,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/deoptimization.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/icache.hpp"
 #include "runtime/java.hpp"
diff --git a/src/hotspot/share/code/debugInfoRec.cpp b/src/hotspot/share/code/debugInfoRec.cpp
index a6f2dbbb971..b19b9defc4d 100644
--- a/src/hotspot/share/code/debugInfoRec.cpp
+++ b/src/hotspot/share/code/debugInfoRec.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 #include "code/debugInfoRec.hpp"
 #include "code/scopeDesc.hpp"
 #include "prims/jvmtiExport.hpp"
+#include "runtime/globals_extension.hpp"
 
 // Private definition.
 // There is one DIR_Chunk for each scope and values array.
diff --git a/src/hotspot/share/code/dependencies.cpp b/src/hotspot/share/code/dependencies.cpp
index ff1956d5c5d..cbf591eb638 100644
--- a/src/hotspot/share/code/dependencies.cpp
+++ b/src/hotspot/share/code/dependencies.cpp
@@ -41,16 +41,18 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/thread.inline.hpp"
+#include "runtime/vmThread.hpp"
 #include "utilities/copy.hpp"
 
 
 #ifdef ASSERT
 static bool must_be_in_vm() {
   Thread* thread = Thread::current();
-  if (thread->is_Java_thread())
-    return ((JavaThread*)thread)->thread_state() == _thread_in_vm;
-  else
-    return true;  //something like this: thread->is_VM_thread();
+  if (thread->is_Java_thread()) {
+    return thread->as_Java_thread()->thread_state() == _thread_in_vm;
+  } else {
+    return true;  // Could be VMThread or GC thread
+  }
 }
 #endif //ASSERT
 
diff --git a/src/hotspot/share/compiler/compilationPolicy.cpp b/src/hotspot/share/compiler/compilationPolicy.cpp
index b5ce247f917..14c0024cfcf 100644
--- a/src/hotspot/share/compiler/compilationPolicy.cpp
+++ b/src/hotspot/share/compiler/compilationPolicy.cpp
@@ -36,6 +36,7 @@
 #include "oops/oop.inline.hpp"
 #include "prims/nativeLookup.hpp"
 #include "runtime/frame.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "runtime/thread.hpp"
diff --git a/src/hotspot/share/compiler/compileBroker.cpp b/src/hotspot/share/compiler/compileBroker.cpp
index 50521eb1129..9beb34192f9 100644
--- a/src/hotspot/share/compiler/compileBroker.cpp
+++ b/src/hotspot/share/compiler/compileBroker.cpp
@@ -50,6 +50,7 @@
 #include "prims/whitebox.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
@@ -249,11 +250,6 @@ bool compileBroker_init() {
 CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) {
   CompilerThread* thread = CompilerThread::current();
   thread->set_task(task);
-#if INCLUDE_JVMCI
-  if (task->is_blocking() && CompileBroker::compiler(task->comp_level())->is_jvmci()) {
-    task->set_jvmci_compiler_thread(thread);
-  }
-#endif
   CompileLog*     log  = thread->log();
   if (log != NULL && !task->is_unloaded())  task->log_task_start(log);
 }
@@ -277,7 +273,7 @@ CompileTaskWrapper::~CompileTaskWrapper() {
           // The waiting thread timed out and thus did not free the task.
           free_task = true;
         }
-        task->set_jvmci_compiler_thread(NULL);
+        task->set_blocking_jvmci_compile_state(NULL);
       }
 #endif
       if (!free_task) {
@@ -606,19 +602,16 @@ void register_jfr_phasetype_serializer(CompilerType compiler_type) {
   ResourceMark rm;
   static bool first_registration = true;
   if (compiler_type == compiler_jvmci) {
-    // register serializer, phases will be added later lazily.
-    GrowableArray<const char*>* jvmci_phase_names = new GrowableArray<const char*>(1);
-    jvmci_phase_names->append("NOT_A_PHASE_NAME");
-    CompilerEvent::PhaseEvent::register_phases(jvmci_phase_names);
+    CompilerEvent::PhaseEvent::get_phase_id("NOT_A_PHASE_NAME", false, false, false);
     first_registration = false;
 #ifdef COMPILER2
   } else if (compiler_type == compiler_c2) {
     assert(first_registration, "invariant"); // c2 must be registered first.
     GrowableArray<const char*>* c2_phase_names = new GrowableArray<const char*>(PHASE_NUM_TYPES);
     for (int i = 0; i < PHASE_NUM_TYPES; i++) {
-      c2_phase_names->append(CompilerPhaseTypeHelper::to_string((CompilerPhaseType)i));
+      const char* phase_name = CompilerPhaseTypeHelper::to_string((CompilerPhaseType) i);
+      CompilerEvent::PhaseEvent::get_phase_id(phase_name, false, false, false);
     }
-    CompilerEvent::PhaseEvent::register_phases(c2_phase_names);
     first_registration = false;
 #endif // COMPILER2
   }
@@ -1183,7 +1176,7 @@ void CompileBroker::compile_method_base(const methodHandle& method,
 
       if (!UseJVMCINativeLibrary) {
         // Don't allow blocking compiles if inside a class initializer or while performing class loading
-        vframeStream vfst((JavaThread*) thread);
+        vframeStream vfst(thread->as_Java_thread());
         for (; !vfst.at_end(); vfst.next()) {
           if (vfst.method()->is_static_initializer() ||
               (vfst.method()->method_holder()->is_subclass_of(SystemDictionary::ClassLoader_klass()) &&
@@ -1604,22 +1597,27 @@ bool CompileBroker::wait_for_jvmci_completion(JVMCICompiler* jvmci, CompileTask*
   assert(UseJVMCICompiler, "sanity");
   MonitorLocker ml(thread, task->lock());
   int progress_wait_attempts = 0;
-  int methods_compiled = jvmci->methods_compiled();
+  jint thread_jvmci_compilation_ticks = 0;
+  jint global_jvmci_compilation_ticks = jvmci->global_compilation_ticks();
   while (!task->is_complete() && !is_compilation_disabled_forever() &&
          ml.wait(JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE)) {
-    CompilerThread* jvmci_compiler_thread = task->jvmci_compiler_thread();
+    JVMCICompileState* jvmci_compile_state = task->blocking_jvmci_compile_state();
 
     bool progress;
-    if (jvmci_compiler_thread != NULL) {
-      // If the JVMCI compiler thread is not blocked or suspended, we deem it to be making progress.
-      progress = jvmci_compiler_thread->thread_state() != _thread_blocked &&
-        !jvmci_compiler_thread->is_external_suspend();
+    if (jvmci_compile_state != NULL) {
+      jint ticks = jvmci_compile_state->compilation_ticks();
+      progress = (ticks - thread_jvmci_compilation_ticks) != 0;
+      JVMCI_event_1("waiting on compilation %d [ticks=%d]", task->compile_id(), ticks);
+      thread_jvmci_compilation_ticks = ticks;
     } else {
       // Still waiting on JVMCI compiler queue. This thread may be holding a lock
-      // that all JVMCI compiler threads are blocked on. We use the counter for
-      // successful JVMCI compilations to determine whether JVMCI compilation
+      // that all JVMCI compiler threads are blocked on. We use the global JVMCI
+      // compilation ticks to determine whether JVMCI compilation
       // is still making progress through the JVMCI compiler queue.
-      progress = jvmci->methods_compiled() != methods_compiled;
+      jint ticks = jvmci->global_compilation_ticks();
+      progress = (ticks - global_jvmci_compilation_ticks) != 0;
+      JVMCI_event_1("waiting on compilation %d to be queued [ticks=%d]", task->compile_id(), ticks);
+      global_jvmci_compilation_ticks = ticks;
     }
 
     if (!progress) {
@@ -1627,13 +1625,11 @@ bool CompileBroker::wait_for_jvmci_completion(JVMCICompiler* jvmci, CompileTask*
         if (PrintCompilation) {
           task->print(tty, "wait for blocking compilation timed out");
         }
+        JVMCI_event_1("waiting on compilation %d timed out", task->compile_id());
         break;
       }
     } else {
       progress_wait_attempts = 0;
-      if (jvmci_compiler_thread == NULL) {
-        methods_compiled = jvmci->methods_compiled();
-      }
     }
   }
   task->clear_waiter();
@@ -2152,7 +2148,7 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
 
     TraceTime t1("compilation", &time);
     EventCompilation event;
-    JVMCICompileState compile_state(task);
+    JVMCICompileState compile_state(task, jvmci);
     JVMCIRuntime *runtime = NULL;
 
     if (JVMCI::in_shutdown()) {
diff --git a/src/hotspot/share/compiler/compileTask.cpp b/src/hotspot/share/compiler/compileTask.cpp
index 26155b19f13..e4147062fb7 100644
--- a/src/hotspot/share/compiler/compileTask.cpp
+++ b/src/hotspot/share/compiler/compileTask.cpp
@@ -100,7 +100,7 @@ void CompileTask::initialize(int compile_id,
   _osr_bci = osr_bci;
   _is_blocking = is_blocking;
   JVMCI_ONLY(_has_waiter = CompileBroker::compiler(comp_level)->is_jvmci();)
-  JVMCI_ONLY(_jvmci_compiler_thread = NULL;)
+  JVMCI_ONLY(_blocking_jvmci_compile_state = NULL;)
   _comp_level = comp_level;
   _num_inlined_bytecodes = 0;
 
diff --git a/src/hotspot/share/compiler/compileTask.hpp b/src/hotspot/share/compiler/compileTask.hpp
index fd8c4603329..03beb350b1b 100644
--- a/src/hotspot/share/compiler/compileTask.hpp
+++ b/src/hotspot/share/compiler/compileTask.hpp
@@ -31,6 +31,8 @@
 #include "memory/allocation.hpp"
 #include "utilities/xmlstream.hpp"
 
+JVMCI_ONLY(class JVMCICompileState;)
+
 // CompileTask
 //
 // An entry in the compile queue.  It represents a pending or current
@@ -81,8 +83,8 @@ class CompileTask : public CHeapObj<mtCompiler> {
   bool         _is_blocking;
 #if INCLUDE_JVMCI
   bool         _has_waiter;
-  // Compiler thread for a blocking JVMCI compilation
-  CompilerThread* _jvmci_compiler_thread;
+  // Compilation state for a blocking JVMCI compilation
+  JVMCICompileState* _blocking_jvmci_compile_state;
 #endif
   int          _comp_level;
   int          _num_inlined_bytecodes;
@@ -144,11 +146,9 @@ class CompileTask : public CHeapObj<mtCompiler> {
 
   bool         has_waiter() const                { return _has_waiter; }
   void         clear_waiter()                    { _has_waiter = false; }
-  CompilerThread* jvmci_compiler_thread() const  { return _jvmci_compiler_thread; }
-  void         set_jvmci_compiler_thread(CompilerThread* t) {
-    assert(is_blocking(), "must be");
-    assert((t == NULL) != (_jvmci_compiler_thread == NULL), "must be");
-    _jvmci_compiler_thread = t;
+  JVMCICompileState* blocking_jvmci_compile_state() const { return _blocking_jvmci_compile_state; }
+  void         set_blocking_jvmci_compile_state(JVMCICompileState* state) {
+    _blocking_jvmci_compile_state = state;
   }
 #endif
 
diff --git a/src/hotspot/share/compiler/compilerEvent.cpp b/src/hotspot/share/compiler/compilerEvent.cpp
index 5aca2de2856..f89db6ce389 100644
--- a/src/hotspot/share/compiler/compilerEvent.cpp
+++ b/src/hotspot/share/compiler/compilerEvent.cpp
@@ -34,67 +34,84 @@
 class PhaseTypeGuard : public StackObj {
  private:
   static Semaphore _mutex_semaphore;
+  bool _enabled;
  public:
-  PhaseTypeGuard() {
-    _mutex_semaphore.wait();
+  PhaseTypeGuard(bool enabled=true) {
+    if (enabled) {
+      _mutex_semaphore.wait();
+      _enabled = true;
+    } else {
+      _enabled = false;
+    }
   }
   ~PhaseTypeGuard() {
-    _mutex_semaphore.signal();
+    if (_enabled) {
+      _mutex_semaphore.signal();
+    }
   }
 };
 
 Semaphore PhaseTypeGuard::_mutex_semaphore(1);
 
-static void write_phases(JfrCheckpointWriter& writer, u4 base_idx, GrowableArray<const char*>* phases) {
-  assert(phases != NULL, "invariant");
-  assert(phases->is_nonempty(), "invariant");
-  const u4 nof_entries = phases->length();
-  writer.write_count(nof_entries);
-  for (u4 i = 0; i < nof_entries; i++) {
-    writer.write_key(base_idx + i);
-    writer.write(phases->at(i));
-  }
-}
-
+// Table for mapping compiler phases names to int identifiers.
 static GrowableArray<const char*>* phase_names = NULL;
 
 class CompilerPhaseTypeConstant : public JfrSerializer {
  public:
   void serialize(JfrCheckpointWriter& writer) {
     PhaseTypeGuard guard;
-    write_phases(writer, 0, phase_names);
+    assert(phase_names != NULL, "invariant");
+    assert(phase_names->is_nonempty(), "invariant");
+    const u4 nof_entries = phase_names->length();
+    writer.write_count(nof_entries);
+    for (u4 i = 0; i < nof_entries; i++) {
+      writer.write_key(i);
+      writer.write(phase_names->at(i));
+    }
   }
 };
 
-// This function provides support for adding dynamic entries to JFR type CompilerPhaseType.
-// The mapping for CompilerPhaseType is maintained as growable array phase_names.
-// The serializer CompilerPhaseTypeConstant must be registered with JFR at vm init.
-// Registration of new phase names creates mapping, serialize it for current chunk and registers its serializer with JFR if it is not already done.
-int CompilerEvent::PhaseEvent::register_phases(GrowableArray<const char*>* new_phases) {
-  int idx = -1;
-  if (new_phases == NULL || new_phases->is_empty()) {
-    return idx;
+static int lookup_phase(const char* phase_name) {
+  for (int i = 0; i < phase_names->length(); i++) {
+    const char* name = phase_names->at(i);
+    if (strcmp(name, phase_name) == 0) {
+      return i;
+    }
   }
+  return -1;
+}
+
+int CompilerEvent::PhaseEvent::get_phase_id(const char* phase_name, bool may_exist, bool use_strdup, bool sync) {
+  int index;
   bool register_jfr_serializer = false;
   {
-    PhaseTypeGuard guard;
+    PhaseTypeGuard guard(sync);
     if (phase_names == NULL) {
-      phase_names = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<const char*>(100, mtCompiler);
+      phase_names = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<const char*>(100, mtCompiler);
       register_jfr_serializer = true;
+    } else if (may_exist) {
+      index = lookup_phase(phase_name);
+      if (index != -1) {
+        return index;
+      }
+    } else {
+      assert((index = lookup_phase(phase_name)) == -1, "phase name \"%s\" already registered: %d", phase_name, index);
     }
-    idx = phase_names->length();
-    phase_names->appendAll(new_phases);
-    guarantee(phase_names->length() < 256, "exceeds maximum supported phases");
+
+    index = phase_names->length();
+    phase_names->append(use_strdup ? strdup(phase_name) : phase_name);
   }
   if (register_jfr_serializer) {
     JfrSerializer::register_serializer(TYPE_COMPILERPHASETYPE, false, new CompilerPhaseTypeConstant());
   } else if (Jfr::is_recording()) {
-    // serialize new_phases.
+    // serialize new phase.
     JfrCheckpointWriter writer;
     writer.write_type(TYPE_COMPILERPHASETYPE);
-    write_phases(writer, idx, new_phases);
+    writer.write_count(1);
+    writer.write_key(index);
+    writer.write(phase_name);
   }
-  return idx;
+  return index;
 }
 
 void CompilerEvent::CompilationEvent::post(EventCompilation& event, int compile_id, CompilerType compiler_type, Method* method, int compile_level, bool success, bool is_osr, int code_size, int inlined_bytecodes) {
diff --git a/src/hotspot/share/compiler/compilerEvent.hpp b/src/hotspot/share/compiler/compilerEvent.hpp
index ae94d4cf185..65fc296b66b 100644
--- a/src/hotspot/share/compiler/compilerEvent.hpp
+++ b/src/hotspot/share/compiler/compilerEvent.hpp
@@ -64,15 +64,13 @@ class CompilerEvent : AllStatic {
   class PhaseEvent : AllStatic {
     friend class CompilerPhaseTypeConstant;
    public:
-    /**
-     * Register compiler phases for JFR type CompilerPhaseType serialization purposes.
-     * This method is called during compiler creation or during compilation.
-     * Registration will serialize the passed in phase constants, supporting bulk and/or incremental registrations.
-     * This method returns start index of new list that just got appended to phase_names.
-     * Param new_phases may contain duplicates.
-     * Return value could be used for mapping purpose at caller site, or caller can assume explicit order of registration.
-     */
-    static int register_phases(GrowableArray<const char*>* new_phases) NOT_JFR_RETURN_(-1);
+
+    // Gets a unique identifier for `phase_name`, computing and registering it first if necessary.
+    // If `may_exist` is true, then current registrations are searched first. If false, then
+    // there must not be an existing registration for `phase_name`.
+    // If `use_strdup` is true, then `phase_name` is strdup'ed before registration.
+    // If `sync` is true, then access to the registration table is synchronized.
+    static int get_phase_id(const char* phase_name, bool may_exist, bool use_strdup, bool sync) NOT_JFR_RETURN_(-1);
 
     static void post(EventCompilerPhase& event, const Ticks& start_time, int phase, int compile_id, int level) NOT_JFR_RETURN();
     static void post(EventCompilerPhase& event, jlong start_time, int phase, int compile_id, int level) {
diff --git a/src/hotspot/share/compiler/compilerOracle.cpp b/src/hotspot/share/compiler/compilerOracle.cpp
index fe4c93d450c..26328783964 100644
--- a/src/hotspot/share/compiler/compilerOracle.cpp
+++ b/src/hotspot/share/compiler/compilerOracle.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
 #include "oops/klass.hpp"
 #include "oops/method.hpp"
 #include "oops/symbol.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/jniHandles.hpp"
 #include "runtime/os.hpp"
diff --git a/src/hotspot/share/compiler/tieredThresholdPolicy.cpp b/src/hotspot/share/compiler/tieredThresholdPolicy.cpp
index a380e90e49d..5f062650f25 100644
--- a/src/hotspot/share/compiler/tieredThresholdPolicy.cpp
+++ b/src/hotspot/share/compiler/tieredThresholdPolicy.cpp
@@ -29,6 +29,7 @@
 #include "memory/resourceArea.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/frame.inline.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/safepointVerifiers.hpp"
diff --git a/src/hotspot/share/gc/epsilon/epsilonArguments.cpp b/src/hotspot/share/gc/epsilon/epsilonArguments.cpp
index 52652ed687c..17cac8d86bf 100644
--- a/src/hotspot/share/gc/epsilon/epsilonArguments.cpp
+++ b/src/hotspot/share/gc/epsilon/epsilonArguments.cpp
@@ -28,7 +28,6 @@
 #include "gc/shared/gcArguments.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
-#include "runtime/vm_version.hpp"
 #include "utilities/macros.hpp"
 
 size_t EpsilonArguments::conservative_max_heap_alignment() {
diff --git a/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp
index da48b3f1ec5..b039a949dcf 100644
--- a/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp
+++ b/src/hotspot/share/gc/epsilon/epsilonBarrierSet.cpp
@@ -41,7 +41,7 @@ EpsilonBarrierSet::EpsilonBarrierSet() : BarrierSet(
           make_barrier_set_c1<BarrierSetC1>(),
           make_barrier_set_c2<BarrierSetC2>(),
           NULL /* barrier_set_nmethod */,
-          BarrierSet::FakeRtti(BarrierSet::EpsilonBarrierSet)) {};
+          BarrierSet::FakeRtti(BarrierSet::EpsilonBarrierSet)) {}
 
 void EpsilonBarrierSet::on_thread_create(Thread *thread) {
   EpsilonThreadLocalData::create(thread);
diff --git a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp
index 78d08a4dd5a..7e77026ac5a 100644
--- a/src/hotspot/share/gc/epsilon/epsilonHeap.cpp
+++ b/src/hotspot/share/gc/epsilon/epsilonHeap.cpp
@@ -46,7 +46,6 @@ jint EpsilonHeap::initialize() {
   _virtual_space.initialize(heap_rs, init_byte_size);
 
   MemRegion committed_region((HeapWord*)_virtual_space.low(),          (HeapWord*)_virtual_space.high());
-  MemRegion  reserved_region((HeapWord*)_virtual_space.low_boundary(), (HeapWord*)_virtual_space.high_boundary());
 
   initialize_reserved_region(heap_rs);
 
diff --git a/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp b/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp
index c18bc1d8206..1006e848b5d 100644
--- a/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp
+++ b/src/hotspot/share/gc/epsilon/epsilonInitLogger.cpp
@@ -27,6 +27,7 @@
 #include "gc/epsilon/epsilonInitLogger.hpp"
 #include "logging/log.hpp"
 #include "runtime/globals.hpp"
+#include "runtime/globals_extension.hpp"
 #include "utilities/globalDefinitions.hpp"
 
 void EpsilonInitLogger::print_gc_specific() {
diff --git a/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp
index 666cbfdebe7..6ced6ae55f7 100644
--- a/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp
+++ b/src/hotspot/share/gc/epsilon/epsilonMonitoringSupport.cpp
@@ -27,7 +27,6 @@
 #include "gc/epsilon/epsilonHeap.hpp"
 #include "gc/shared/generationCounters.hpp"
 #include "memory/allocation.hpp"
-#include "memory/allocation.inline.hpp"
 #include "memory/metaspaceCounters.hpp"
 #include "memory/resourceArea.hpp"
 #include "services/memoryService.hpp"
diff --git a/src/hotspot/share/gc/epsilon/epsilon_globals.hpp b/src/hotspot/share/gc/epsilon/epsilon_globals.hpp
index 2387240bc1a..fbcb9c47aab 100644
--- a/src/hotspot/share/gc/epsilon/epsilon_globals.hpp
+++ b/src/hotspot/share/gc/epsilon/epsilon_globals.hpp
@@ -33,65 +33,61 @@
 //
 
 #define GC_EPSILON_FLAGS(develop,                                           \
-                    develop_pd,                                             \
-                    product,                                                \
-                    product_pd,                                             \
-                    diagnostic,                                             \
-                    diagnostic_pd,                                          \
-                    experimental,                                           \
-                    notproduct,                                             \
-                    manageable,                                             \
-                    product_rw,                                             \
-                    lp64_product,                                           \
-                    range,                                                  \
-                    constraint)                                             \
+                         develop_pd,                                        \
+                         product,                                           \
+                         product_pd,                                        \
+                         notproduct,                                        \
+                         range,                                             \
+                         constraint)                                        \
                                                                             \
-  experimental(size_t, EpsilonPrintHeapSteps, 20,                           \
+  product(size_t, EpsilonPrintHeapSteps, 20, EXPERIMENTAL,                  \
           "Print heap occupancy stats with this number of steps. "          \
           "0 turns the printing off.")                                      \
           range(0, max_intx)                                                \
                                                                             \
-  experimental(size_t, EpsilonUpdateCountersStep, 1 * M,                    \
+  product(size_t, EpsilonUpdateCountersStep, 1 * M, EXPERIMENTAL,           \
           "Update heap occupancy counters after allocating this much "      \
           "memory. Higher values would make allocations faster at "         \
           "the expense of lower resolution in heap counters.")              \
           range(1, max_intx)                                                \
                                                                             \
-  experimental(size_t, EpsilonMaxTLABSize, 4 * M,                           \
+  product(size_t, EpsilonMaxTLABSize, 4 * M, EXPERIMENTAL,                  \
           "Max TLAB size to use with Epsilon GC. Larger value improves "    \
           "performance at the expense of per-thread memory waste. This "    \
           "asks TLAB machinery to cap TLAB sizes at this value.")           \
           range(1, max_intx)                                                \
                                                                             \
-  experimental(bool, EpsilonElasticTLAB, true,                              \
+  product(bool, EpsilonElasticTLAB, true, EXPERIMENTAL,                     \
           "Use elastic policy to manage TLAB sizes. This conserves memory " \
           "for non-actively allocating threads, even when they request "    \
           "large TLABs for themselves. Active threads would experience "    \
           "smaller TLABs until policy catches up.")                         \
                                                                             \
-  experimental(bool, EpsilonElasticTLABDecay, true,                         \
+  product(bool, EpsilonElasticTLABDecay, true, EXPERIMENTAL,                \
           "Use timed decays to shrik TLAB sizes. This conserves memory "    \
           "for the threads that allocate in bursts of different sizes, "    \
           "for example the small/rare allocations coming after the initial "\
           "large burst.")                                                   \
                                                                             \
-  experimental(double, EpsilonTLABElasticity, 1.1,                          \
+  product(double, EpsilonTLABElasticity, 1.1, EXPERIMENTAL,                 \
           "Multiplier to use when deciding on next TLAB size. Larger value "\
           "improves performance at the expense of per-thread memory waste. "\
           "Lower value improves memory footprint, but penalizes actively "  \
           "allocating threads.")                                            \
           range(1.0, DBL_MAX)                                               \
                                                                             \
-  experimental(size_t, EpsilonTLABDecayTime, 1000,                          \
+  product(size_t, EpsilonTLABDecayTime, 1000, EXPERIMENTAL,                 \
           "TLAB sizing policy decays to initial size after thread had not " \
           "allocated for this long. Time is in milliseconds. Lower value "  \
           "improves memory footprint, but penalizes actively allocating "   \
           "threads.")                                                       \
           range(1, max_intx)                                                \
                                                                             \
-  experimental(size_t, EpsilonMinHeapExpand, 128 * M,                       \
+  product(size_t, EpsilonMinHeapExpand, 128 * M, EXPERIMENTAL,              \
           "Min expansion step for heap. Larger value improves performance " \
           "at the potential expense of memory waste.")                      \
           range(1, max_intx)
 
+// end of GC_EPSILON_FLAGS
+
 #endif // SHARE_GC_EPSILON_EPSILON_GLOBALS_HPP
diff --git a/src/hotspot/share/gc/g1/g1Analytics.cpp b/src/hotspot/share/gc/g1/g1Analytics.cpp
index 853de98da24..966d017e786 100644
--- a/src/hotspot/share/gc/g1/g1Analytics.cpp
+++ b/src/hotspot/share/gc/g1/g1Analytics.cpp
@@ -151,7 +151,8 @@ void G1Analytics::report_alloc_rate_ms(double alloc_rate) {
 
 void G1Analytics::compute_pause_time_ratios(double end_time_sec, double pause_time_ms) {
   double long_interval_ms = (end_time_sec - oldest_known_gc_end_time_sec()) * 1000.0;
-  _long_term_pause_time_ratio = _recent_gc_times_ms->sum() / long_interval_ms;
+  double gc_pause_time_ms = _recent_gc_times_ms->sum() - _recent_gc_times_ms->oldest() + pause_time_ms;
+  _long_term_pause_time_ratio = gc_pause_time_ms / long_interval_ms;
   _long_term_pause_time_ratio = clamp(_long_term_pause_time_ratio, 0.0, 1.0);
 
   double short_interval_ms = (end_time_sec - most_recent_gc_end_time_sec()) * 1000.0;
@@ -224,7 +225,11 @@ void G1Analytics::report_rs_length(double rs_length) {
 }
 
 double G1Analytics::predict_alloc_rate_ms() const {
-  return predict_zero_bounded(_alloc_rate_ms_seq);
+  if (enough_samples_available(_alloc_rate_ms_seq)) {
+    return predict_zero_bounded(_alloc_rate_ms_seq);
+  } else {
+    return 0.0;
+  }
 }
 
 double G1Analytics::predict_concurrent_refine_rate_ms() const {
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
index ab28e850a33..b09262048a8 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp
@@ -1677,21 +1677,21 @@ jint G1CollectedHeap::initialize() {
   // 6843694 - ensure that the maximum region index can fit
   // in the remembered set structures.
   const uint max_region_idx = (1U << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1;
-  guarantee((max_regions() - 1) <= max_region_idx, "too many regions");
+  guarantee((max_reserved_regions() - 1) <= max_region_idx, "too many regions");
 
   // The G1FromCardCache reserves card with value 0 as "invalid", so the heap must not
   // start within the first card.
   guarantee(heap_rs.base() >= (char*)G1CardTable::card_size, "Java heap must not start within the first card.");
   // Also create a G1 rem set.
   _rem_set = new G1RemSet(this, _card_table, _hot_card_cache);
-  _rem_set->initialize(max_regions());
+  _rem_set->initialize(max_reserved_regions());
 
   size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1;
   guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized");
   guarantee(HeapRegion::CardsPerRegion < max_cards_per_region,
             "too many cards per region");
 
-  FreeRegionList::set_unrealistically_long_length(max_expandable_regions() + 1);
+  FreeRegionList::set_unrealistically_long_length(max_regions() + 1);
 
   _bot = new G1BlockOffsetTable(reserved(), bot_storage);
 
@@ -1713,7 +1713,7 @@ jint G1CollectedHeap::initialize() {
   _numa->set_region_info(HeapRegion::GrainBytes, page_size);
 
   // Create the G1ConcurrentMark data structure and thread.
-  // (Must do this late, so that "max_regions" is defined.)
+  // (Must do this late, so that "max_[reserved_]regions" is defined.)
   _cm = new G1ConcurrentMark(this, prev_bitmap_storage, next_bitmap_storage);
   _cm_thread = _cm->cm_thread();
 
@@ -1765,7 +1765,7 @@ jint G1CollectedHeap::initialize() {
 
   _preserved_marks_set.init(ParallelGCThreads);
 
-  _collection_set.initialize(max_regions());
+  _collection_set.initialize(max_reserved_regions());
 
   G1InitLogger::print();
 
@@ -2391,7 +2391,7 @@ size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const {
 }
 
 size_t G1CollectedHeap::max_capacity() const {
-  return _hrm->max_expandable_length() * HeapRegion::GrainBytes;
+  return max_regions() * HeapRegion::GrainBytes;
 }
 
 void G1CollectedHeap::deduplicate_string(oop str) {
diff --git a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
index 2f325819186..546a25e7c5d 100644
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp
@@ -101,7 +101,7 @@ class G1EvacSummary;
 typedef OverflowTaskQueue<ScannerTask, mtGC>           G1ScannerTasksQueue;
 typedef GenericTaskQueueSet<G1ScannerTasksQueue, mtGC> G1ScannerTasksQueueSet;
 
-typedef int RegionIdx_t;   // needs to hold [ 0..max_regions() )
+typedef int RegionIdx_t;   // needs to hold [ 0..max_reserved_regions() )
 typedef int CardIdx_t;     // needs to hold [ 0..CardsPerRegion )
 
 // The G1 STW is alive closure.
@@ -1061,11 +1061,12 @@ class G1CollectedHeap : public CollectedHeap {
   // The current number of regions in the heap.
   uint num_regions() const { return _hrm->length(); }
 
-  // The max number of regions in the heap.
-  uint max_regions() const { return _hrm->max_length(); }
+  // The max number of regions reserved for the heap. Except for static array
+  // sizing purposes you probably want to use max_regions().
+  uint max_reserved_regions() const { return _hrm->reserved_length(); }
 
-  // Max number of regions that can be comitted.
-  uint max_expandable_regions() const { return _hrm->max_expandable_length(); }
+  // Max number of regions that can be committed.
+  uint max_regions() const { return _hrm->max_length(); }
 
   // The number of regions that are completely free.
   uint num_free_regions() const { return _hrm->num_free_regions(); }
diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
index 30b2cdeaf7a..db39d0a3d31 100644
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp
@@ -62,6 +62,7 @@
 #include "oops/access.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/orderAccess.hpp"
@@ -405,8 +406,8 @@ G1ConcurrentMark::G1ConcurrentMark(G1CollectedHeap* g1h,
   _num_concurrent_workers(0),
   _max_concurrent_workers(0),
 
-  _region_mark_stats(NEW_C_HEAP_ARRAY(G1RegionMarkStats, _g1h->max_regions(), mtGC)),
-  _top_at_rebuild_starts(NEW_C_HEAP_ARRAY(HeapWord*, _g1h->max_regions(), mtGC))
+  _region_mark_stats(NEW_C_HEAP_ARRAY(G1RegionMarkStats, _g1h->max_reserved_regions(), mtGC)),
+  _top_at_rebuild_starts(NEW_C_HEAP_ARRAY(HeapWord*, _g1h->max_reserved_regions(), mtGC))
 {
   assert(CGC_lock != NULL, "CGC_lock must be initialized");
 
@@ -462,8 +463,8 @@ void G1ConcurrentMark::reset() {
     _tasks[i]->reset(_next_mark_bitmap);
   }
 
-  uint max_regions = _g1h->max_regions();
-  for (uint i = 0; i < max_regions; i++) {
+  uint max_reserved_regions = _g1h->max_reserved_regions();
+  for (uint i = 0; i < max_reserved_regions; i++) {
     _top_at_rebuild_starts[i] = NULL;
     _region_mark_stats[i].clear();
   }
@@ -518,8 +519,8 @@ void G1ConcurrentMark::reset_marking_for_restart() {
   if (has_overflown()) {
     _global_mark_stack.expand();
 
-    uint max_regions = _g1h->max_regions();
-    for (uint i = 0; i < max_regions; i++) {
+    uint max_reserved_regions = _g1h->max_reserved_regions();
+    for (uint i = 0; i < max_reserved_regions; i++) {
       _region_mark_stats[i].clear_during_overflow();
     }
   }
@@ -1738,8 +1739,7 @@ class G1RemarkThreadsClosure : public ThreadClosure {
         // * Weakly reachable otherwise
         // Some objects reachable from nmethods, such as the class loader (or klass_holder) of the receiver should be
         // live by the SATB invariant but other oops recorded in nmethods may behave differently.
-        JavaThread* jt = (JavaThread*)thread;
-        jt->nmethods_do(&_code_cl);
+        thread->as_Java_thread()->nmethods_do(&_code_cl);
       }
     }
   }
diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp
index 3189c27db7b..bd797e6eb9c 100644
--- a/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp
+++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.inline.hpp
@@ -182,13 +182,13 @@ inline size_t G1CMTask::scan_objArray(objArrayOop obj, MemRegion mr) {
 }
 
 inline HeapWord* G1ConcurrentMark::top_at_rebuild_start(uint region) const {
-  assert(region < _g1h->max_regions(), "Tried to access TARS for region %u out of bounds", region);
+  assert(region < _g1h->max_reserved_regions(), "Tried to access TARS for region %u out of bounds", region);
   return _top_at_rebuild_starts[region];
 }
 
 inline void G1ConcurrentMark::update_top_at_rebuild_start(HeapRegion* r) {
   uint const region = r->hrm_index();
-  assert(region < _g1h->max_regions(), "Tried to access TARS for region %u out of bounds", region);
+  assert(region < _g1h->max_reserved_regions(), "Tried to access TARS for region %u out of bounds", region);
   assert(_top_at_rebuild_starts[region] == NULL,
          "TARS for region %u has already been set to " PTR_FORMAT " should be NULL",
          region, p2i(_top_at_rebuild_starts[region]));
diff --git a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
index b8bd67eb07a..bb9731f8b41 100644
--- a/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
+++ b/src/hotspot/share/gc/g1/g1ConcurrentRefine.cpp
@@ -30,6 +30,7 @@
 #include "logging/log.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/iterator.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/thread.hpp"
 #include "utilities/debug.hpp"
diff --git a/src/hotspot/share/gc/g1/g1FromCardCache.cpp b/src/hotspot/share/gc/g1/g1FromCardCache.cpp
index 1ef65898ec7..a0dcadde611 100644
--- a/src/hotspot/share/gc/g1/g1FromCardCache.cpp
+++ b/src/hotspot/share/gc/g1/g1FromCardCache.cpp
@@ -29,26 +29,26 @@
 #include "utilities/debug.hpp"
 
 uintptr_t** G1FromCardCache::_cache = NULL;
-uint        G1FromCardCache::_max_regions = 0;
+uint        G1FromCardCache::_max_reserved_regions = 0;
 size_t      G1FromCardCache::_static_mem_size = 0;
 #ifdef ASSERT
 uint   G1FromCardCache::_max_workers = 0;
 #endif
 
-void G1FromCardCache::initialize(uint num_par_rem_sets, uint max_num_regions) {
-  guarantee(max_num_regions > 0, "Heap size must be valid");
+void G1FromCardCache::initialize(uint num_par_rem_sets, uint max_reserved_regions) {
+  guarantee(max_reserved_regions > 0, "Heap size must be valid");
   guarantee(_cache == NULL, "Should not call this multiple times");
 
-  _max_regions = max_num_regions;
+  _max_reserved_regions = max_reserved_regions;
 #ifdef ASSERT
   _max_workers = num_par_rem_sets;
 #endif
-  _cache = Padded2DArray<uintptr_t, mtGC>::create_unfreeable(_max_regions,
+  _cache = Padded2DArray<uintptr_t, mtGC>::create_unfreeable(_max_reserved_regions,
                                                              num_par_rem_sets,
                                                              &_static_mem_size);
 
   if (AlwaysPreTouch) {
-    invalidate(0, _max_regions);
+    invalidate(0, _max_reserved_regions);
   }
 }
 
@@ -57,7 +57,7 @@ void G1FromCardCache::invalidate(uint start_idx, size_t new_num_regions) {
             "Trying to invalidate beyond maximum region, from %u size " SIZE_FORMAT,
             start_idx, new_num_regions);
   uint end_idx = (start_idx + (uint)new_num_regions);
-  assert(end_idx <= _max_regions, "Must be within max.");
+  assert(end_idx <= _max_reserved_regions, "Must be within max.");
 
   for (uint i = 0; i < G1RemSet::num_par_rem_sets(); i++) {
     for (uint j = start_idx; j < end_idx; j++) {
@@ -69,7 +69,7 @@ void G1FromCardCache::invalidate(uint start_idx, size_t new_num_regions) {
 #ifndef PRODUCT
 void G1FromCardCache::print(outputStream* out) {
   for (uint i = 0; i < G1RemSet::num_par_rem_sets(); i++) {
-    for (uint j = 0; j < _max_regions; j++) {
+    for (uint j = 0; j < _max_reserved_regions; j++) {
       out->print_cr("_from_card_cache[%u][%u] = " SIZE_FORMAT ".",
                     i, j, at(i, j));
     }
diff --git a/src/hotspot/share/gc/g1/g1FromCardCache.hpp b/src/hotspot/share/gc/g1/g1FromCardCache.hpp
index 22f837dd2ef..c234b3021a0 100644
--- a/src/hotspot/share/gc/g1/g1FromCardCache.hpp
+++ b/src/hotspot/share/gc/g1/g1FromCardCache.hpp
@@ -38,14 +38,14 @@ class G1FromCardCache : public AllStatic {
   // freeing. I.e. a single clear of a single memory area instead of multiple separate
   // accesses with a large stride per region.
   static uintptr_t** _cache;
-  static uint _max_regions;
+  static uint _max_reserved_regions;
   static size_t _static_mem_size;
 #ifdef ASSERT
   static uint _max_workers;
 
   static void check_bounds(uint worker_id, uint region_idx) {
     assert(worker_id < _max_workers, "Worker_id %u is larger than maximum %u", worker_id, _max_workers);
-    assert(region_idx < _max_regions, "Region_idx %u is larger than maximum %u", region_idx, _max_regions);
+    assert(region_idx < _max_reserved_regions, "Region_idx %u is larger than maximum %u", region_idx, _max_reserved_regions);
   }
 #endif
 
@@ -79,7 +79,7 @@ class G1FromCardCache : public AllStatic {
     _cache[region_idx][worker_id] = val;
   }
 
-  static void initialize(uint num_par_rem_sets, uint max_num_regions);
+  static void initialize(uint num_par_rem_sets, uint max_reserved_regions);
 
   static void invalidate(uint start_idx, size_t num_regions);
 
diff --git a/src/hotspot/share/gc/g1/g1Policy.cpp b/src/hotspot/share/gc/g1/g1Policy.cpp
index c7bda3940f2..1357393f2b9 100644
--- a/src/hotspot/share/gc/g1/g1Policy.cpp
+++ b/src/hotspot/share/gc/g1/g1Policy.cpp
@@ -46,6 +46,7 @@
 #include "gc/shared/gcPolicyCounters.hpp"
 #include "logging/log.hpp"
 #include "runtime/arguments.hpp"
+#include "runtime/globals.hpp"
 #include "runtime/java.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "utilities/debug.hpp"
@@ -61,8 +62,8 @@ G1Policy::G1Policy(STWGCTimer* gc_timer) :
   _ihop_control(create_ihop_control(&_old_gen_alloc_tracker, &_predictor)),
   _policy_counters(new GCPolicyCounters("GarbageFirst", 1, 2)),
   _full_collection_start_sec(0.0),
+  _young_list_desired_length(0),
   _young_list_target_length(0),
-  _young_list_fixed_length(0),
   _young_list_max_length(0),
   _eden_surv_rate_group(new G1SurvRateGroup()),
   _survivor_surv_rate_group(new G1SurvRateGroup()),
@@ -107,14 +108,11 @@ void G1Policy::init(G1CollectedHeap* g1h, G1CollectionSet* collection_set) {
 
   assert(Heap_lock->owned_by_self(), "Locking discipline.");
 
-  if (!use_adaptive_young_list_length()) {
-    _young_list_fixed_length = _young_gen_sizer->min_desired_young_length();
-  }
-  _young_gen_sizer->adjust_max_new_size(_g1h->max_expandable_regions());
+  _young_gen_sizer->adjust_max_new_size(_g1h->max_regions());
 
   _free_regions_at_end_of_collection = _g1h->num_free_regions();
 
-  update_young_list_max_and_target_length();
+  update_young_length_bounds();
   // We may immediately start allocating regions and placing them on the
   // collection set list. Initialize the per-collection set info
   _collection_set->start_incremental_building();
@@ -189,158 +187,255 @@ void G1Policy::record_new_heap_size(uint new_number_of_regions) {
   _ihop_control->update_target_occupancy(new_number_of_regions * HeapRegion::GrainBytes);
 }
 
-uint G1Policy::calculate_young_list_desired_min_length(uint base_min_length) const {
+uint G1Policy::calculate_desired_eden_length_by_mmu() const {
+  // One could argue that any useful eden length to keep any MMU would be 1, but
+  // in theory this is possible. Other constraints enforce a minimum eden of 1
+  // anyway.
   uint desired_min_length = 0;
   if (use_adaptive_young_list_length()) {
-    if (_analytics->num_alloc_rate_ms() > 3) {
-      double now_sec = os::elapsedTime();
-      double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0;
-      double alloc_rate_ms = _analytics->predict_alloc_rate_ms();
-      desired_min_length = (uint) ceil(alloc_rate_ms * when_ms);
-    } else {
-      // otherwise we don't have enough info to make the prediction
-    }
+    double now_sec = os::elapsedTime();
+    double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0;
+    double alloc_rate_ms = _analytics->predict_alloc_rate_ms();
+    desired_min_length = (uint) ceil(alloc_rate_ms * when_ms);
   }
-  desired_min_length += base_min_length;
-  // make sure we don't go below any user-defined minimum bound
-  return MAX2(_young_gen_sizer->min_desired_young_length(), desired_min_length);
-}
-
-uint G1Policy::calculate_young_list_desired_max_length() const {
-  // Here, we might want to also take into account any additional
-  // constraints (i.e., user-defined minimum bound). Currently, we
-  // effectively don't set this bound.
-  return _young_gen_sizer->max_desired_young_length();
-}
-
-uint G1Policy::update_young_list_max_and_target_length() {
-  return update_young_list_max_and_target_length(_analytics->predict_rs_length());
-}
-
-uint G1Policy::update_young_list_max_and_target_length(size_t rs_length) {
-  uint unbounded_target_length = update_young_list_target_length(rs_length);
-  update_max_gc_locker_expansion();
-  return unbounded_target_length;
-}
+  return desired_min_length;
+}
+
+void G1Policy::update_young_length_bounds() {
+  update_young_length_bounds(_analytics->predict_rs_length());
+}
+
+void G1Policy::update_young_length_bounds(size_t rs_length) {
+  _young_list_desired_length = calculate_young_desired_length(rs_length);
+  _young_list_target_length = calculate_young_target_length(_young_list_desired_length);
+  _young_list_max_length = calculate_young_max_length(_young_list_target_length);
+
+  log_debug(gc,ergo,heap)("Young list lengths: desired: %u, target: %u, max: %u",
+                          _young_list_desired_length,
+                          _young_list_target_length,
+                          _young_list_max_length);
+}
+
+// Calculates desired young gen length. It is calculated from:
+//
+// - sizer min/max bounds on young gen
+// - pause time goal for whole young gen evacuation
+// - MMU goal influencing eden to make GCs spaced apart.
+// - a minimum one eden region length.
+//
+// We may enter with already allocated eden and survivor regions, that may be
+// higher than the maximum, or the above goals may result in a desired value
+// smaller than are already allocated.
+// The main reason is revising young length, with or without the GCLocker being
+// active.
+//
+uint G1Policy::calculate_young_desired_length(size_t rs_length) const {
+  uint min_young_length_by_sizer = _young_gen_sizer->min_desired_young_length();
+  uint max_young_length_by_sizer = _young_gen_sizer->max_desired_young_length();
+
+  assert(min_young_length_by_sizer >= 1, "invariant");
+  assert(max_young_length_by_sizer >= min_young_length_by_sizer, "invariant");
+
+  // Absolute minimum eden length.
+  // Enforcing a minimum eden length helps at startup when the predictors are not
+  // yet trained on the application to avoid unnecessary (but very short) full gcs
+  // on very small (initial) heaps.
+  uint const MinDesiredEdenLength = 1;
 
-uint G1Policy::update_young_list_target_length(size_t rs_length) {
-  YoungTargetLengths young_lengths = young_list_target_lengths(rs_length);
-  _young_list_target_length = young_lengths.first;
+  // Calculate the absolute and desired min bounds first.
 
-  return young_lengths.second;
-}
+  // This is how many survivor regions we already have.
+  const uint survivor_length = _g1h->survivor_regions_count();
+  // Size of the already allocated young gen.
+  const uint allocated_young_length = _g1h->young_regions_count();
+  // This is the absolute minimum young length that we can return. Ensure that we
+  // don't go below any user-defined minimum bound; but we might have already
+  // allocated more than that for various reasons. In this case, use that.
+  uint absolute_min_young_length = MAX2(allocated_young_length, min_young_length_by_sizer);
+  // Calculate the absolute max bounds. After evac failure or when revising the
+  // young length we might have exceeded absolute min length or absolute_max_length,
+  // so adjust the result accordingly.
+  uint absolute_max_young_length = MAX2(max_young_length_by_sizer, absolute_min_young_length);
+
+  uint desired_eden_length_by_mmu = 0;
+  uint desired_eden_length_by_pause = 0;
+
+  uint desired_young_length = 0;
+  if (use_adaptive_young_list_length()) {
+    desired_eden_length_by_mmu = calculate_desired_eden_length_by_mmu();
 
-G1Policy::YoungTargetLengths G1Policy::young_list_target_lengths(size_t rs_length) const {
-  YoungTargetLengths result;
+    const size_t pending_cards = _analytics->predict_pending_cards();
+    double survivor_base_time_ms = predict_base_elapsed_time_ms(pending_cards, rs_length);
 
-  // Calculate the absolute and desired min bounds first.
+    desired_eden_length_by_pause =
+      calculate_desired_eden_length_by_pause(survivor_base_time_ms,
+                                             absolute_min_young_length - survivor_length,
+                                             absolute_max_young_length - survivor_length);
 
-  // This is how many young regions we already have (currently: the survivors).
-  const uint base_min_length = _g1h->survivor_regions_count();
-  uint desired_min_length = calculate_young_list_desired_min_length(base_min_length);
-  // This is the absolute minimum young length. Ensure that we
-  // will at least have one eden region available for allocation.
-  uint absolute_min_length = base_min_length + MAX2(_g1h->eden_regions_count(), (uint)1);
-  // If we shrank the young list target it should not shrink below the current size.
-  desired_min_length = MAX2(desired_min_length, absolute_min_length);
-  // Calculate the absolute and desired max bounds.
+    // Incorporate MMU concerns; assume that it overrides the pause time
+    // goal, as the default value has been chosen to effectively disable it.
+    // Also request at least one eden region, see above for reasons.
+    uint desired_eden_length = MAX3(desired_eden_length_by_pause,
+                                    desired_eden_length_by_mmu,
+                                    MinDesiredEdenLength);
 
-  uint desired_max_length = calculate_young_list_desired_max_length();
-
-  uint young_list_target_length = 0;
-  if (use_adaptive_young_list_length()) {
-    if (collector_state()->in_young_only_phase()) {
-      young_list_target_length =
-                        calculate_young_list_target_length(rs_length,
-                                                           base_min_length,
-                                                           desired_min_length,
-                                                           desired_max_length);
-    } else {
-      // Don't calculate anything and let the code below bound it to
-      // the desired_min_length, i.e., do the next GC as soon as
-      // possible to maximize how many old regions we can add to it.
-    }
+    desired_young_length = desired_eden_length + survivor_length;
   } else {
     // The user asked for a fixed young gen so we'll fix the young gen
     // whether the next GC is young or mixed.
-    young_list_target_length = _young_list_fixed_length;
-  }
-
-  result.second = young_list_target_length;
-
-  // We will try our best not to "eat" into the reserve.
-  uint absolute_max_length = 0;
-  if (_free_regions_at_end_of_collection > _reserve_regions) {
-    absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions;
+    desired_young_length = min_young_length_by_sizer;
   }
-  if (desired_max_length > absolute_max_length) {
-    desired_max_length = absolute_max_length;
+  // Clamp to absolute min/max after we determined desired lengths.
+  desired_young_length = clamp(desired_young_length, absolute_min_young_length, absolute_max_young_length);
+
+  log_trace(gc, ergo, heap)("Young desired length %u "
+                            "survivor length %u "
+                            "allocated young length %u "
+                            "absolute min young length %u "
+                            "absolute max young length %u "
+                            "desired eden length by mmu %u "
+                            "desired eden length by pause %u "
+                            "desired eden length by default %u",
+                            desired_young_length, survivor_length,
+                            allocated_young_length, absolute_min_young_length,
+                            absolute_max_young_length, desired_eden_length_by_mmu,
+                            desired_eden_length_by_pause,
+                            MinDesiredEdenLength);
+
+  assert(desired_young_length >= allocated_young_length, "must be");
+  return desired_young_length;
+}
+
+// Limit the desired (wished) young length by current free regions. If the request
+// can be satisfied without using up reserve regions, do so, otherwise eat into
+// the reserve, giving away at most what the heap sizer allows.
+uint G1Policy::calculate_young_target_length(uint desired_young_length) const {
+  uint allocated_young_length = _g1h->young_regions_count();
+
+  uint receiving_additional_eden;
+  if (allocated_young_length >= desired_young_length) {
+    // Already used up all we actually want (may happen as G1 revises the
+    // young list length concurrently, or caused by gclocker). Do not allow more,
+    // potentially resulting in GC.
+    receiving_additional_eden = 0;
+    log_trace(gc, ergo, heap)("Young target length: Already used up desired young %u allocated %u",
+                              desired_young_length,
+                              allocated_young_length);
+  } else {
+    // Now look at how many free regions are there currently, and the heap reserve.
+    // We will try our best not to "eat" into the reserve as long as we can. If we
+    // do, we at most eat the sizer's minimum regions into the reserve or half the
+    // reserve rounded up (if possible; this is an arbitrary value).
+
+    uint max_to_eat_into_reserve = MIN2(_young_gen_sizer->min_desired_young_length(),
+                                        (_reserve_regions + 1) / 2);
+
+    log_trace(gc, ergo, heap)("Young target length: Common "
+                              "free regions at end of collection %u "
+                              "desired young length %u "
+                              "reserve region %u "
+                              "max to eat into reserve %u",
+                              _free_regions_at_end_of_collection,
+                              desired_young_length,
+                              _reserve_regions,
+                              max_to_eat_into_reserve);
+
+    if (_free_regions_at_end_of_collection <= _reserve_regions) {
+      // Fully eat (or already eating) into the reserve, hand back at most absolute_min_length regions.
+      uint receiving_young = MIN3(_free_regions_at_end_of_collection,
+                                  desired_young_length,
+                                  max_to_eat_into_reserve);
+      // We could already have allocated more regions than what we could get
+      // above.
+      receiving_additional_eden = allocated_young_length < receiving_young ?
+                                  receiving_young - allocated_young_length : 0;
+
+      log_trace(gc, ergo, heap)("Young target length: Fully eat into reserve "
+                                "receiving young %u receiving additional eden %u",
+                                receiving_young,
+                                receiving_additional_eden);
+    } else if (_free_regions_at_end_of_collection < (desired_young_length + _reserve_regions)) {
+      // Partially eat into the reserve, at most max_to_eat_into_reserve regions.
+      uint free_outside_reserve = _free_regions_at_end_of_collection - _reserve_regions;
+      assert(free_outside_reserve < desired_young_length,
+             "must be %u %u",
+             free_outside_reserve, desired_young_length);
+
+      uint receiving_within_reserve = MIN2(desired_young_length - free_outside_reserve,
+                                           max_to_eat_into_reserve);
+      uint receiving_young = free_outside_reserve + receiving_within_reserve;
+      // Again, we could have already allocated more than we could get.
+      receiving_additional_eden = allocated_young_length < receiving_young ?
+                                  receiving_young - allocated_young_length : 0;
+
+      log_trace(gc, ergo, heap)("Young target length: Partially eat into reserve "
+                                "free outside reserve %u "
+                                "receiving within reserve %u "
+                                "receiving young %u "
+                                "receiving additional eden %u",
+                                free_outside_reserve, receiving_within_reserve,
+                                receiving_young, receiving_additional_eden);
+    } else {
+      // No need to use the reserve.
+      receiving_additional_eden = desired_young_length - allocated_young_length;
+      log_trace(gc, ergo, heap)("Young target length: No need to use reserve "
+                                "receiving additional eden %u",
+                                receiving_additional_eden);
+    }
   }
 
-  // Make sure we don't go over the desired max length, nor under the
-  // desired min length. In case they clash, desired_min_length wins
-  // which is why that test is second.
-  if (young_list_target_length > desired_max_length) {
-    young_list_target_length = desired_max_length;
-  }
-  if (young_list_target_length < desired_min_length) {
-    young_list_target_length = desired_min_length;
-  }
+  uint target_young_length = allocated_young_length + receiving_additional_eden;
 
-  assert(young_list_target_length > base_min_length,
-         "we should be able to allocate at least one eden region");
-  assert(young_list_target_length >= absolute_min_length, "post-condition");
+  assert(target_young_length >= allocated_young_length, "must be");
 
-  result.first = young_list_target_length;
-  return result;
+  log_trace(gc, ergo, heap)("Young target length: "
+                            "young target length %u "
+                            "allocated young length %u "
+                            "received additional eden %u",
+                            target_young_length, allocated_young_length,
+                            receiving_additional_eden);
+  return target_young_length;
 }
 
-uint G1Policy::calculate_young_list_target_length(size_t rs_length,
-                                                  uint base_min_length,
-                                                  uint desired_min_length,
-                                                  uint desired_max_length) const {
-  assert(use_adaptive_young_list_length(), "pre-condition");
-  assert(collector_state()->in_young_only_phase(), "only call this for young GCs");
-
-  // In case some edge-condition makes the desired max length too small...
-  if (desired_max_length <= desired_min_length) {
-    return desired_min_length;
+uint G1Policy::calculate_desired_eden_length_by_pause(double base_time_ms,
+                                                      uint min_eden_length,
+                                                      uint max_eden_length) const {
+  if (!next_gc_should_be_mixed(NULL, NULL)) {
+    return calculate_desired_eden_length_before_young_only(base_time_ms,
+                                                           min_eden_length,
+                                                           max_eden_length);
+  } else {
+    return calculate_desired_eden_length_before_mixed(base_time_ms,
+                                                      min_eden_length,
+                                                      max_eden_length);
   }
+}
+
+
+uint G1Policy::calculate_desired_eden_length_before_young_only(double base_time_ms,
+                                                               uint min_eden_length,
+                                                               uint max_eden_length) const {
+  assert(use_adaptive_young_list_length(), "pre-condition");
 
-  // We'll adjust min_young_length and max_young_length not to include
-  // the already allocated young regions (i.e., so they reflect the
-  // min and max eden regions we'll allocate). The base_min_length
-  // will be reflected in the predictions by the
-  // survivor_regions_evac_time prediction.
-  assert(desired_min_length > base_min_length, "invariant");
-  uint min_young_length = desired_min_length - base_min_length;
-  assert(desired_max_length > base_min_length, "invariant");
-  uint max_young_length = desired_max_length - base_min_length;
-
-  const double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
-  const size_t pending_cards = _analytics->predict_pending_cards();
-  const double base_time_ms = predict_base_elapsed_time_ms(pending_cards, rs_length);
-  const uint available_free_regions = _free_regions_at_end_of_collection;
-  const uint base_free_regions =
-    available_free_regions > _reserve_regions ? available_free_regions - _reserve_regions : 0;
+  assert(min_eden_length <= max_eden_length, "must be %u %u", min_eden_length, max_eden_length);
 
   // Here, we will make sure that the shortest young length that
   // makes sense fits within the target pause time.
 
   G1YoungLengthPredictor p(base_time_ms,
-                           base_free_regions,
-                           target_pause_time_ms,
+                           _free_regions_at_end_of_collection,
+                           _mmu_tracker->max_gc_time() * 1000.0,
                            this);
-  if (p.will_fit(min_young_length)) {
+  if (p.will_fit(min_eden_length)) {
     // The shortest young length will fit into the target pause time;
     // we'll now check whether the absolute maximum number of young
     // regions will fit in the target pause time. If not, we'll do
     // a binary search between min_young_length and max_young_length.
-    if (p.will_fit(max_young_length)) {
+    if (p.will_fit(max_eden_length)) {
       // The maximum young length will fit into the target pause time.
       // We are done so set min young length to the maximum length (as
       // the result is assumed to be returned in min_young_length).
-      min_young_length = max_young_length;
+      min_eden_length = max_eden_length;
     } else {
       // The maximum possible number of young regions will not fit within
       // the target pause time so we'll search for the optimal
@@ -357,37 +452,56 @@ uint G1Policy::calculate_young_list_target_length(size_t rs_length,
       // does, it becomes the new min. If it doesn't, it becomes
       // the new max. This way we maintain the loop invariants.
 
-      assert(min_young_length < max_young_length, "invariant");
-      uint diff = (max_young_length - min_young_length) / 2;
+      assert(min_eden_length < max_eden_length, "invariant");
+      uint diff = (max_eden_length - min_eden_length) / 2;
       while (diff > 0) {
-        uint young_length = min_young_length + diff;
-        if (p.will_fit(young_length)) {
-          min_young_length = young_length;
+        uint eden_length = min_eden_length + diff;
+        if (p.will_fit(eden_length)) {
+          min_eden_length = eden_length;
         } else {
-          max_young_length = young_length;
+          max_eden_length = eden_length;
         }
-        assert(min_young_length <  max_young_length, "invariant");
-        diff = (max_young_length - min_young_length) / 2;
+        assert(min_eden_length <  max_eden_length, "invariant");
+        diff = (max_eden_length - min_eden_length) / 2;
       }
       // The results is min_young_length which, according to the
       // loop invariants, should fit within the target pause time.
 
       // These are the post-conditions of the binary search above:
-      assert(min_young_length < max_young_length,
-             "otherwise we should have discovered that max_young_length "
+      assert(min_eden_length < max_eden_length,
+             "otherwise we should have discovered that max_eden_length "
              "fits into the pause target and not done the binary search");
-      assert(p.will_fit(min_young_length),
-             "min_young_length, the result of the binary search, should "
+      assert(p.will_fit(min_eden_length),
+             "min_eden_length, the result of the binary search, should "
              "fit into the pause target");
-      assert(!p.will_fit(min_young_length + 1),
-             "min_young_length, the result of the binary search, should be "
+      assert(!p.will_fit(min_eden_length + 1),
+             "min_eden_length, the result of the binary search, should be "
              "optimal, so no larger length should fit into the pause target");
     }
   } else {
     // Even the minimum length doesn't fit into the pause time
     // target, return it as the result nevertheless.
   }
-  return base_min_length + min_young_length;
+  return min_eden_length;
+}
+
+uint G1Policy::calculate_desired_eden_length_before_mixed(double survivor_base_time_ms,
+                                                          uint min_eden_length,
+                                                          uint max_eden_length) const {
+  G1CollectionSetCandidates* candidates = _collection_set->candidates();
+
+  uint min_old_regions_end = MIN2(candidates->cur_idx() + calc_min_old_cset_length(), candidates->num_regions());
+  double predicted_region_evac_time_ms = survivor_base_time_ms;
+  for (uint i = candidates->cur_idx(); i < min_old_regions_end; i++) {
+    HeapRegion* r = candidates->at(i);
+    predicted_region_evac_time_ms += predict_region_total_time_ms(r, false);
+  }
+  uint desired_eden_length_by_min_cset_length =
+     calculate_desired_eden_length_before_young_only(predicted_region_evac_time_ms,
+                                                     min_eden_length,
+                                                     max_eden_length);
+
+  return desired_eden_length_by_min_cset_length;
 }
 
 double G1Policy::predict_survivor_regions_evac_time() const {
@@ -417,8 +531,7 @@ void G1Policy::revise_young_list_target_length_if_necessary(size_t rs_length) {
     // add 10% to avoid having to recalculate often
     size_t rs_length_prediction = rs_length * 1100 / 1000;
     update_rs_length_prediction(rs_length_prediction);
-
-    update_young_list_max_and_target_length(rs_length_prediction);
+    update_young_length_bounds(rs_length_prediction);
   }
 }
 
@@ -466,7 +579,7 @@ void G1Policy::record_full_collection_end() {
 
   _free_regions_at_end_of_collection = _g1h->num_free_regions();
   _survivor_surv_rate_group->reset();
-  update_young_list_max_and_target_length();
+  update_young_length_bounds();
   update_rs_length_prediction();
 
   _old_gen_alloc_tracker.reset_after_gc(_g1h->humongous_regions_count() * HeapRegion::GrainBytes);
@@ -798,15 +911,10 @@ void G1Policy::record_collection_pause_end(double pause_time_ms) {
   // Do not update dynamic IHOP due to G1 periodic collection as it is highly likely
   // that in this case we are not running in a "normal" operating mode.
   if (_g1h->gc_cause() != GCCause::_g1_periodic_collection) {
-    // IHOP control wants to know the expected young gen length if it were not
-    // restrained by the heap reserve. Using the actual length would make the
-    // prediction too small and the limit the young gen every time we get to the
-    // predicted target occupancy.
-    size_t last_unrestrained_young_length = update_young_list_max_and_target_length();
+    update_young_length_bounds();
 
     _old_gen_alloc_tracker.reset_after_gc(_g1h->humongous_regions_count() * HeapRegion::GrainBytes);
     update_ihop_prediction(app_time_ms / 1000.0,
-                           last_unrestrained_young_length * HeapRegion::GrainBytes,
                            is_young_only_pause(this_pause));
 
     _ihop_control->send_trace_event(_g1h->gc_tracer_stw());
@@ -857,7 +965,6 @@ G1IHOPControl* G1Policy::create_ihop_control(const G1OldGenAllocationTracker* ol
 }
 
 void G1Policy::update_ihop_prediction(double mutator_time_s,
-                                      size_t young_gen_size,
                                       bool this_gc_was_young_only) {
   // Always try to update IHOP prediction. Even evacuation failures give information
   // about e.g. whether to start IHOP earlier next time.
@@ -885,6 +992,11 @@ void G1Policy::update_ihop_prediction(double mutator_time_s,
   // marking, which makes any prediction useless. This increases the accuracy of the
   // prediction.
   if (this_gc_was_young_only && mutator_time_s > min_valid_time) {
+    // IHOP control wants to know the expected young gen length if it were not
+    // restrained by the heap reserve. Using the actual length would make the
+    // prediction too small and the limit the young gen every time we get to the
+    // predicted target occupancy.
+    size_t young_gen_size = young_list_desired_length() * HeapRegion::GrainBytes;
     _ihop_control->update_allocation_info(mutator_time_s, young_gen_size);
     report = true;
   }
@@ -991,7 +1103,7 @@ void G1Policy::print_age_table() {
   _survivors_age_table.print_age_table(_tenuring_threshold);
 }
 
-void G1Policy::update_max_gc_locker_expansion() {
+uint G1Policy::calculate_young_max_length(uint target_young_length) const {
   uint expansion_region_num = 0;
   if (GCLockerEdenExpansionPercent > 0) {
     double perc = (double) GCLockerEdenExpansionPercent / 100.0;
@@ -999,11 +1111,10 @@ void G1Policy::update_max_gc_locker_expansion() {
     // We use ceiling so that if expansion_region_num_d is > 0.0 (but
     // less than 1.0) we'll get 1.
     expansion_region_num = (uint) ceil(expansion_region_num_d);
-  } else {
-    assert(expansion_region_num == 0, "sanity");
   }
-  _young_list_max_length = _young_list_target_length + expansion_region_num;
-  assert(_young_list_target_length <= _young_list_max_length, "post-condition");
+  uint max_length = target_young_length + expansion_region_num;
+  assert(target_young_length <= max_length, "overflow");
+  return max_length;
 }
 
 // Calculates survivor space parameters.
@@ -1238,8 +1349,10 @@ bool G1Policy::next_gc_should_be_mixed(const char* true_action_str,
                                        const char* false_action_str) const {
   G1CollectionSetCandidates* candidates = _collection_set->candidates();
 
-  if (candidates->is_empty()) {
-    log_debug(gc, ergo)("%s (candidate old regions not available)", false_action_str);
+  if (candidates == NULL || candidates->is_empty()) {
+    if (false_action_str != NULL) {
+      log_debug(gc, ergo)("%s (candidate old regions not available)", false_action_str);
+    }
     return false;
   }
 
@@ -1248,12 +1361,24 @@ bool G1Policy::next_gc_should_be_mixed(const char* true_action_str,
   double reclaimable_percent = reclaimable_bytes_percent(reclaimable_bytes);
   double threshold = (double) G1HeapWastePercent;
   if (reclaimable_percent <= threshold) {
-    log_debug(gc, ergo)("%s (reclaimable percentage not over threshold). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT,
-                        false_action_str, candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, G1HeapWastePercent);
+    if (false_action_str != NULL) {
+      log_debug(gc, ergo)("%s (reclaimable percentage below threshold). "
+                          "candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) "
+                          "threshold: " UINTX_FORMAT,
+                          false_action_str,
+                          candidates->num_remaining(), reclaimable_bytes, reclaimable_percent,
+                          G1HeapWastePercent);
+    }
     return false;
   }
-  log_debug(gc, ergo)("%s (candidate old regions available). candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) threshold: " UINTX_FORMAT,
-                      true_action_str, candidates->num_remaining(), reclaimable_bytes, reclaimable_percent, G1HeapWastePercent);
+  if (true_action_str != NULL) {
+    log_debug(gc, ergo)("%s (candidate old regions available). "
+                        "candidate old regions: %u reclaimable: " SIZE_FORMAT " (%1.2f) "
+                        "threshold: " UINTX_FORMAT,
+                        true_action_str,
+                        candidates->num_remaining(), reclaimable_bytes, reclaimable_percent,
+                        G1HeapWastePercent);
+  }
   return true;
 }
 
diff --git a/src/hotspot/share/gc/g1/g1Policy.hpp b/src/hotspot/share/gc/g1/g1Policy.hpp
index dff561fbdc8..677b012ffd8 100644
--- a/src/hotspot/share/gc/g1/g1Policy.hpp
+++ b/src/hotspot/share/gc/g1/g1Policy.hpp
@@ -60,7 +60,6 @@ class G1Policy: public CHeapObj<mtGC> {
                                             const G1Predictions* predictor);
   // Update the IHOP control with necessary statistics.
   void update_ihop_prediction(double mutator_time_s,
-                              size_t young_gen_size,
                               bool this_gc_was_young_only);
   void report_ihop_statistics();
 
@@ -78,8 +77,8 @@ class G1Policy: public CHeapObj<mtGC> {
 
   double _full_collection_start_sec;
 
+  uint _young_list_desired_length;
   uint _young_list_target_length;
-  uint _young_list_fixed_length;
 
   // The max number of regions we can extend the eden by while the GC
   // locker is active. This should be >= _young_list_target_length;
@@ -168,6 +167,10 @@ class G1Policy: public CHeapObj<mtGC> {
 
 private:
   G1CollectionSet* _collection_set;
+
+  bool next_gc_should_be_mixed(const char* true_action_str,
+                               const char* false_action_str) const;
+
   double average_time_ms(G1GCPhaseTimes::GCParPhases phase) const;
   double other_time_ms(double pause_time_ms) const;
 
@@ -189,44 +192,44 @@ class G1Policy: public CHeapObj<mtGC> {
   double _mark_remark_start_sec;
   double _mark_cleanup_start_sec;
 
-  // Updates the internal young list maximum and target lengths. Returns the
-  // unbounded young list target length. If no rs_length parameter is passed,
-  // predict the RS length using the prediction model, otherwise use the
-  // given rs_length as the prediction.
-  uint update_young_list_max_and_target_length();
-  uint update_young_list_max_and_target_length(size_t rs_length);
-
-  // Update the young list target length either by setting it to the
-  // desired fixed value or by calculating it using G1's pause
-  // prediction model.
-  // Returns the unbounded young list target length.
-  uint update_young_list_target_length(size_t rs_length);
-
-  // Calculate and return the minimum desired young list target
-  // length. This is the minimum desired young list length according
-  // to the user's inputs.
-  uint calculate_young_list_desired_min_length(uint base_min_length) const;
-
-  // Calculate and return the maximum desired young list target
-  // length. This is the maximum desired young list length according
-  // to the user's inputs.
-  uint calculate_young_list_desired_max_length() const;
-
-  // Calculate and return the maximum young list target length that
-  // can fit into the pause time goal. The parameters are: rs_length
-  // represent the prediction of how large the young RSet lengths will
-  // be, base_min_length is the already existing number of regions in
-  // the young list, min_length and max_length are the desired min and
-  // max young list length according to the user's inputs.
-  uint calculate_young_list_target_length(size_t rs_length,
-                                          uint base_min_length,
-                                          uint desired_min_length,
-                                          uint desired_max_length) const;
-
-  // Result of the bounded_young_list_target_length() method, containing both the
-  // bounded as well as the unbounded young list target lengths in this order.
-  typedef Pair<uint, uint, StackObj> YoungTargetLengths;
-  YoungTargetLengths young_list_target_lengths(size_t rs_length) const;
+  // Updates the internal young gen maximum and target and desired lengths.
+  // If no rs_length parameter is passed, predict the RS length using the
+  // prediction model, otherwise use the given rs_length as the prediction.
+  void update_young_length_bounds();
+  void update_young_length_bounds(size_t rs_length);
+
+  // Calculate and return the minimum desired eden length based on the MMU target.
+  uint calculate_desired_eden_length_by_mmu() const;
+
+  // Calculate the desired eden length meeting the pause time goal.
+  // The parameters are: rs_length represents the prediction of how large the
+  // young RSet lengths will be, min_eden_length and max_eden_length are the bounds
+  // (inclusive) within eden can grow.
+  uint calculate_desired_eden_length_by_pause(double base_time_ms,
+                                              uint min_eden_length,
+                                              uint max_eden_length) const;
+
+  // Calculate the desired eden length that can fit into the pause time
+  // goal before young only gcs.
+  uint calculate_desired_eden_length_before_young_only(double base_time_ms,
+                                                       uint min_eden_length,
+                                                       uint max_eden_length) const;
+
+  // Calculates the desired eden length before mixed gc so that after adding the
+  // minimum amount of old gen regions from the collection set, the eden fits into
+  // the pause time goal.
+  uint calculate_desired_eden_length_before_mixed(double survivor_base_time_ms,
+                                                  uint min_eden_length,
+                                                  uint max_eden_length) const;
+
+  // Calculate desired young length based on current situation without taking actually
+  // available free regions into account.
+  uint calculate_young_desired_length(size_t rs_length) const;
+  // Limit the given desired young length to available free regions.
+  uint calculate_young_target_length(uint desired_young_length) const;
+  // The GCLocker might cause us to need more regions than the target. Calculate
+  // the maximum number of regions to use in that case.
+  uint calculate_young_max_length(uint target_young_length) const;
 
   void update_rs_length_prediction();
   void update_rs_length_prediction(size_t prediction);
@@ -337,9 +340,6 @@ class G1Policy: public CHeapObj<mtGC> {
 
   void print_phases();
 
-  bool next_gc_should_be_mixed(const char* true_action_str,
-                               const char* false_action_str) const;
-
   // Calculate and return the number of initial and optional old gen regions from
   // the given collection set candidates and the remaining time.
   void calculate_old_collection_set_regions(G1CollectionSetCandidates* candidates,
@@ -376,6 +376,7 @@ class G1Policy: public CHeapObj<mtGC> {
   // the concurrent start work and start a marking cycle.
   void decide_on_conc_mark_initiation();
 
+  uint young_list_desired_length() const { return _young_list_desired_length; }
   size_t young_list_target_length() const { return _young_list_target_length; }
 
   bool should_allocate_mutator_region() const;
@@ -436,8 +437,6 @@ class G1Policy: public CHeapObj<mtGC> {
 
   void print_age_table();
 
-  void update_max_gc_locker_expansion();
-
   void update_survivors_policy();
 
   virtual bool force_upgrade_to_full() {
diff --git a/src/hotspot/share/gc/g1/g1RemSet.cpp b/src/hotspot/share/gc/g1/g1RemSet.cpp
index 354cc5ed8f0..7ff5bce8694 100644
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp
@@ -86,7 +86,7 @@
 class G1RemSetScanState : public CHeapObj<mtGC> {
   class G1DirtyRegions;
 
-  size_t _max_regions;
+  size_t _max_reserved_regions;
 
   // Has this region that is part of the regions in the collection set been processed yet.
   typedef bool G1RemsetIterState;
@@ -141,16 +141,16 @@ class G1RemSetScanState : public CHeapObj<mtGC> {
   class G1DirtyRegions : public CHeapObj<mtGC> {
     uint* _buffer;
     uint _cur_idx;
-    size_t _max_regions;
+    size_t _max_reserved_regions;
 
     bool* _contains;
 
   public:
-    G1DirtyRegions(size_t max_regions) :
-      _buffer(NEW_C_HEAP_ARRAY(uint, max_regions, mtGC)),
+    G1DirtyRegions(size_t max_reserved_regions) :
+      _buffer(NEW_C_HEAP_ARRAY(uint, max_reserved_regions, mtGC)),
       _cur_idx(0),
-      _max_regions(max_regions),
-      _contains(NEW_C_HEAP_ARRAY(bool, max_regions, mtGC)) {
+      _max_reserved_regions(max_reserved_regions),
+      _contains(NEW_C_HEAP_ARRAY(bool, max_reserved_regions, mtGC)) {
 
       reset();
     }
@@ -164,7 +164,7 @@ class G1RemSetScanState : public CHeapObj<mtGC> {
 
     void reset() {
       _cur_idx = 0;
-      ::memset(_contains, false, _max_regions * sizeof(bool));
+      ::memset(_contains, false, _max_reserved_regions * sizeof(bool));
     }
 
     uint size() const { return _cur_idx; }
@@ -273,7 +273,7 @@ class G1RemSetScanState : public CHeapObj<mtGC> {
 
 public:
   G1RemSetScanState() :
-    _max_regions(0),
+    _max_reserved_regions(0),
     _collection_set_iter_state(NULL),
     _card_table_scan_state(NULL),
     _scan_chunks_per_region(get_chunks_per_region(HeapRegion::LogOfHRGrainBytes)),
@@ -293,16 +293,16 @@ class G1RemSetScanState : public CHeapObj<mtGC> {
     FREE_C_HEAP_ARRAY(HeapWord*, _scan_top);
   }
 
-  void initialize(size_t max_regions) {
+  void initialize(size_t max_reserved_regions) {
     assert(_collection_set_iter_state == NULL, "Must not be initialized twice");
-    _max_regions = max_regions;
-    _collection_set_iter_state = NEW_C_HEAP_ARRAY(G1RemsetIterState, max_regions, mtGC);
-    _card_table_scan_state = NEW_C_HEAP_ARRAY(uint, max_regions, mtGC);
-    _num_total_scan_chunks = max_regions * _scan_chunks_per_region;
+    _max_reserved_regions = max_reserved_regions;
+    _collection_set_iter_state = NEW_C_HEAP_ARRAY(G1RemsetIterState, max_reserved_regions, mtGC);
+    _card_table_scan_state = NEW_C_HEAP_ARRAY(uint, max_reserved_regions, mtGC);
+    _num_total_scan_chunks = max_reserved_regions * _scan_chunks_per_region;
     _region_scan_chunks = NEW_C_HEAP_ARRAY(bool, _num_total_scan_chunks, mtGC);
 
     _scan_chunks_shift = (uint8_t)log2_intptr(HeapRegion::CardsPerRegion / _scan_chunks_per_region);
-    _scan_top = NEW_C_HEAP_ARRAY(HeapWord*, max_regions, mtGC);
+    _scan_top = NEW_C_HEAP_ARRAY(HeapWord*, max_reserved_regions, mtGC);
   }
 
   void prepare() {
@@ -310,20 +310,20 @@ class G1RemSetScanState : public CHeapObj<mtGC> {
     // regions currently not available or free. Since regions might
     // become used during the collection these values must be valid
     // for those regions as well.
-    for (size_t i = 0; i < _max_regions; i++) {
+    for (size_t i = 0; i < _max_reserved_regions; i++) {
       reset_region_claim((uint)i);
       clear_scan_top((uint)i);
     }
 
-    _all_dirty_regions = new G1DirtyRegions(_max_regions);
-    _next_dirty_regions = new G1DirtyRegions(_max_regions);
+    _all_dirty_regions = new G1DirtyRegions(_max_reserved_regions);
+    _next_dirty_regions = new G1DirtyRegions(_max_reserved_regions);
   }
 
   void prepare_for_merge_heap_roots() {
     _all_dirty_regions->merge(_next_dirty_regions);
 
     _next_dirty_regions->reset();
-    for (size_t i = 0; i < _max_regions; i++) {
+    for (size_t i = 0; i < _max_reserved_regions; i++) {
       _card_table_scan_state[i] = 0;
     }
 
@@ -416,7 +416,7 @@ class G1RemSetScanState : public CHeapObj<mtGC> {
   // Attempt to claim the given region in the collection set for iteration. Returns true
   // if this call caused the transition from Unclaimed to Claimed.
   inline bool claim_collection_set_region(uint region) {
-    assert(region < _max_regions, "Tried to access invalid region %u", region);
+    assert(region < _max_reserved_regions, "Tried to access invalid region %u", region);
     if (_collection_set_iter_state[region]) {
       return false;
     }
@@ -424,12 +424,12 @@ class G1RemSetScanState : public CHeapObj<mtGC> {
   }
 
   bool has_cards_to_scan(uint region) {
-    assert(region < _max_regions, "Tried to access invalid region %u", region);
+    assert(region < _max_reserved_regions, "Tried to access invalid region %u", region);
     return _card_table_scan_state[region] < HeapRegion::CardsPerRegion;
   }
 
   uint claim_cards_to_scan(uint region, uint increment) {
-    assert(region < _max_regions, "Tried to access invalid region %u", region);
+    assert(region < _max_reserved_regions, "Tried to access invalid region %u", region);
     return Atomic::fetch_and_add(&_card_table_scan_state[region], increment);
   }
 
@@ -485,9 +485,9 @@ uint G1RemSet::num_par_rem_sets() {
   return G1DirtyCardQueueSet::num_par_ids() + G1ConcurrentRefine::max_num_threads() + MAX2(ConcGCThreads, ParallelGCThreads);
 }
 
-void G1RemSet::initialize(uint max_regions) {
-  G1FromCardCache::initialize(num_par_rem_sets(), max_regions);
-  _scan_state->initialize(max_regions);
+void G1RemSet::initialize(uint max_reserved_regions) {
+  G1FromCardCache::initialize(num_par_rem_sets(), max_reserved_regions);
+  _scan_state->initialize(max_reserved_regions);
 }
 
 // Helper class to scan and detect ranges of cards that need to be scanned on the
diff --git a/src/hotspot/share/gc/g1/g1RemSet.hpp b/src/hotspot/share/gc/g1/g1RemSet.hpp
index 186c52e5211..e2762758053 100644
--- a/src/hotspot/share/gc/g1/g1RemSet.hpp
+++ b/src/hotspot/share/gc/g1/g1RemSet.hpp
@@ -78,7 +78,7 @@ class G1RemSet: public CHeapObj<mtGC> {
   static uint num_par_rem_sets();
 
   // Initialize data that depends on the heap size being known.
-  void initialize(uint max_regions);
+  void initialize(uint max_reserved_regions);
 
   G1RemSet(G1CollectedHeap* g1h,
            G1CardTable* ct,
diff --git a/src/hotspot/share/gc/g1/g1_globals.hpp b/src/hotspot/share/gc/g1/g1_globals.hpp
index 202af2e70cf..8cc6e0c814e 100644
--- a/src/hotspot/share/gc/g1/g1_globals.hpp
+++ b/src/hotspot/share/gc/g1/g1_globals.hpp
@@ -35,13 +35,7 @@
                     develop_pd,                                             \
                     product,                                                \
                     product_pd,                                             \
-                    diagnostic,                                             \
-                    diagnostic_pd,                                          \
-                    experimental,                                           \
                     notproduct,                                             \
-                    manageable,                                             \
-                    product_rw,                                             \
-                    lp64_product,                                           \
                     range,                                                  \
                     constraint)                                             \
                                                                             \
@@ -51,7 +45,7 @@
           "attempts to start marking in time based on application "         \
           "behavior.")                                                      \
                                                                             \
-  experimental(size_t, G1AdaptiveIHOPNumInitialSamples, 3,                  \
+  product(size_t, G1AdaptiveIHOPNumInitialSamples, 3, EXPERIMENTAL,         \
           "How many completed time periods from concurrent start to first " \
           "mixed gc are required to use the input values for prediction "   \
           "of the optimal occupancy to start marking.")                     \
@@ -61,7 +55,7 @@
           "Confidence level for MMU/pause predictions")                     \
           range(0, 100)                                                     \
                                                                             \
-  diagnostic(intx, G1SummarizeRSetStatsPeriod, 0,                           \
+  product(intx, G1SummarizeRSetStatsPeriod, 0, DIAGNOSTIC,                  \
           "The period (in number of GCs) at which we will generate "        \
           "update buffer processing info "                                  \
           "(0 means do not periodically generate this info); "              \
@@ -79,11 +73,11 @@
           "draining concurrent marking work queues.")                       \
           range(1, INT_MAX)                                                 \
                                                                             \
-  experimental(bool, G1UseReferencePrecleaning, true,                       \
+  product(bool, G1UseReferencePrecleaning, true, EXPERIMENTAL,              \
                "Concurrently preclean java.lang.ref.references instances "  \
                "before the Remark pause.")                                  \
                                                                             \
-  experimental(double, G1LastPLABAverageOccupancy, 50.0,                    \
+  product(double, G1LastPLABAverageOccupancy, 50.0, EXPERIMENTAL,           \
                "The expected average occupancy of the last PLAB in "        \
                "percent.")                                                  \
                range(0.001, 100.0)                                          \
@@ -104,7 +98,7 @@
           "specifies that mutator threads should not do such filtering.")   \
           range(0, 100)                                                     \
                                                                             \
-  experimental(intx, G1ExpandByPercentOfAvailable, 20,                      \
+  product(intx, G1ExpandByPercentOfAvailable, 20, EXPERIMENTAL,             \
           "When expanding, % of uncommitted space to claim.")               \
           range(0, 100)                                                     \
                                                                             \
@@ -212,19 +206,19 @@
           "Raise a fatal VM exit out of memory failure in the event "       \
           " that heap expansion fails due to running out of swap.")         \
                                                                             \
-  experimental(uintx, G1MaxNewSizePercent, 60,                              \
+  product(uintx, G1MaxNewSizePercent, 60, EXPERIMENTAL,                     \
           "Percentage (0-100) of the heap size to use as default "          \
           " maximum young gen size.")                                       \
           range(0, 100)                                                     \
           constraint(G1MaxNewSizePercentConstraintFunc,AfterErgo)           \
                                                                             \
-  experimental(uintx, G1NewSizePercent, 5,                                  \
+  product(uintx, G1NewSizePercent, 5, EXPERIMENTAL,                         \
           "Percentage (0-100) of the heap size to use as default "          \
           "minimum young gen size.")                                        \
           range(0, 100)                                                     \
           constraint(G1NewSizePercentConstraintFunc,AfterErgo)              \
                                                                             \
-  experimental(uintx, G1MixedGCLiveThresholdPercent, 85,                    \
+  product(uintx, G1MixedGCLiveThresholdPercent, 85, EXPERIMENTAL,           \
           "Threshold for regions to be considered for inclusion in the "    \
           "collection set of mixed GCs. "                                   \
           "Regions with live bytes exceeding this will not be collected.")  \
@@ -239,18 +233,18 @@
           "The target number of mixed GCs after a marking cycle.")          \
           range(0, max_uintx)                                               \
                                                                             \
-  experimental(bool, G1EagerReclaimHumongousObjects, true,                  \
+  product(bool, G1EagerReclaimHumongousObjects, true, EXPERIMENTAL,         \
           "Try to reclaim dead large objects at every young GC.")           \
                                                                             \
-  experimental(bool, G1EagerReclaimHumongousObjectsWithStaleRefs, true,     \
+  product(bool, G1EagerReclaimHumongousObjectsWithStaleRefs, true, EXPERIMENTAL, \
           "Try to reclaim dead large objects that have a few stale "        \
           "references at every young GC.")                                  \
                                                                             \
-  experimental(size_t, G1RebuildRemSetChunkSize, 256 * K,                   \
+  product(size_t, G1RebuildRemSetChunkSize, 256 * K, EXPERIMENTAL,          \
           "Chunk size used for rebuilding the remembered set.")             \
           range(4 * K, 32 * M)                                              \
                                                                             \
-  experimental(uintx, G1OldCSetRegionThresholdPercent, 10,                  \
+  product(uintx, G1OldCSetRegionThresholdPercent, 10, EXPERIMENTAL,         \
           "An upper bound for the number of old CSet regions expressed "    \
           "as a percentage of the heap size.")                              \
           range(0, 100)                                                     \
@@ -283,17 +277,17 @@
           "Force use of evacuation failure handling during mixed "          \
           "evacuation pauses")                                              \
                                                                             \
-  diagnostic(bool, G1VerifyRSetsDuringFullGC, false,                        \
+  product(bool, G1VerifyRSetsDuringFullGC, false, DIAGNOSTIC,               \
           "If true, perform verification of each heap region's "            \
           "remembered set when verifying the heap during a full GC.")       \
                                                                             \
-  diagnostic(bool, G1VerifyHeapRegionCodeRoots, false,                      \
+  product(bool, G1VerifyHeapRegionCodeRoots, false, DIAGNOSTIC,             \
           "Verify the code root lists attached to each heap region.")       \
                                                                             \
   develop(bool, G1VerifyBitmaps, false,                                     \
           "Verifies the consistency of the marking bitmaps")                \
                                                                             \
-  manageable(uintx, G1PeriodicGCInterval, 0,                                \
+  product(uintx, G1PeriodicGCInterval, 0, MANAGEABLE,                       \
           "Number of milliseconds after a previous GC to wait before "      \
           "triggering a periodic gc. A value of zero disables periodically "\
           "enforced gc cycles.")                                            \
@@ -303,21 +297,22 @@
           "perform a concurrent GC as periodic GC, otherwise use a STW "    \
           "Full GC.")                                                       \
                                                                             \
-  manageable(double, G1PeriodicGCSystemLoadThreshold, 0.0,                  \
+  product(double, G1PeriodicGCSystemLoadThreshold, 0.0, MANAGEABLE,         \
           "Maximum recent system wide load as returned by the 1m value "    \
           "of getloadavg() at which G1 triggers a periodic GC. A load "     \
           "above this value cancels a given periodic GC. A value of zero "  \
           "disables this check.")                                           \
           range(0.0, (double)max_uintx)                                     \
                                                                             \
-  experimental(uintx, G1YoungExpansionBufferPercent, 10,                    \
+  product(uintx, G1YoungExpansionBufferPercent, 10, EXPERIMENTAL,           \
                "When heterogenous heap is enabled by AllocateOldGenAt "     \
                "option, after every GC, young gen is re-sized which "       \
                "involves system calls to commit/uncommit memory. To "       \
                "reduce these calls, we keep a buffer of extra regions to "  \
                "absorb small changes in young gen length. This flag takes " \
                "the buffer size as an percentage of young gen length")      \
-               range(0, 100)                                                \
+               range(0, 100)
 
+// end of GC_G1_FLAGS
 
 #endif // SHARE_GC_G1_G1_GLOBALS_HPP
diff --git a/src/hotspot/share/gc/g1/heapRegion.cpp b/src/hotspot/share/gc/g1/heapRegion.cpp
index ce63b911dab..eadde715f6f 100644
--- a/src/hotspot/share/gc/g1/heapRegion.cpp
+++ b/src/hotspot/share/gc/g1/heapRegion.cpp
@@ -43,6 +43,7 @@
 #include "oops/access.inline.hpp"
 #include "oops/compressedOops.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/globals_extension.hpp"
 #include "utilities/powerOfTwo.hpp"
 
 int    HeapRegion::LogOfHRGrainBytes = 0;
diff --git a/src/hotspot/share/gc/g1/heapRegionManager.cpp b/src/hotspot/share/gc/g1/heapRegionManager.cpp
index 15892182d29..8255be42a2e 100644
--- a/src/hotspot/share/gc/g1/heapRegionManager.cpp
+++ b/src/hotspot/share/gc/g1/heapRegionManager.cpp
@@ -85,11 +85,11 @@ HeapRegionManager* HeapRegionManager::create_manager(G1CollectedHeap* heap) {
 }
 
 void HeapRegionManager::initialize(G1RegionToSpaceMapper* heap_storage,
-                               G1RegionToSpaceMapper* prev_bitmap,
-                               G1RegionToSpaceMapper* next_bitmap,
-                               G1RegionToSpaceMapper* bot,
-                               G1RegionToSpaceMapper* cardtable,
-                               G1RegionToSpaceMapper* card_counts) {
+                                   G1RegionToSpaceMapper* prev_bitmap,
+                                   G1RegionToSpaceMapper* next_bitmap,
+                                   G1RegionToSpaceMapper* bot,
+                                   G1RegionToSpaceMapper* cardtable,
+                                   G1RegionToSpaceMapper* card_counts) {
   _allocated_heapregions_length = 0;
 
   _heap_mapper = heap_storage;
@@ -184,7 +184,8 @@ HeapRegion* HeapRegionManager::new_heap_region(uint hrm_index) {
 
 void HeapRegionManager::commit_regions(uint index, size_t num_regions, WorkGang* pretouch_gang) {
   guarantee(num_regions > 0, "Must commit more than zero regions");
-  guarantee(_num_committed + num_regions <= max_length(), "Cannot commit more than the maximum amount of regions");
+  guarantee(num_regions <= available(),
+            "Cannot commit more than the maximum amount of regions");
 
   _num_committed += (uint)num_regions;
 
@@ -321,16 +322,19 @@ void HeapRegionManager::expand_exact(uint start, uint num_regions, WorkGang* pre
 
 uint HeapRegionManager::expand_on_preferred_node(uint preferred_index) {
   uint expand_candidate = UINT_MAX;
-  for (uint i = 0; i < max_length(); i++) {
-    if (is_available(i)) {
-      // Already in use continue
-      continue;
-    }
-    // Always save the candidate so we can expand later on.
-    expand_candidate = i;
-    if (is_on_preferred_index(expand_candidate, preferred_index)) {
-      // We have found a candidate on the preffered node, break.
-      break;
+
+  if (available() >= 1) {
+    for (uint i = 0; i < reserved_length(); i++) {
+      if (is_available(i)) {
+        // Already in use continue
+        continue;
+      }
+      // Always save the candidate so we can expand later on.
+      expand_candidate = i;
+      if (is_on_preferred_index(expand_candidate, preferred_index)) {
+        // We have found a candidate on the preferred node, break.
+        break;
+      }
     }
   }
 
@@ -397,14 +401,18 @@ uint HeapRegionManager::find_contiguous_in_free_list(uint num_regions) {
     range_start = _available_map.get_next_one_offset(range_end);
     range_end = _available_map.get_next_zero_offset(range_start);
     candidate = find_contiguous_in_range((uint) range_start, (uint) range_end, num_regions);
-  } while (candidate == G1_NO_HRM_INDEX && range_end < max_length());
+  } while (candidate == G1_NO_HRM_INDEX && range_end < reserved_length());
 
   return candidate;
 }
 
 uint HeapRegionManager::find_contiguous_allow_expand(uint num_regions) {
+  // Check if we can actually satisfy the allocation.
+  if (num_regions > available()) {
+    return G1_NO_HRM_INDEX;
+  }
   // Find any candidate.
-  return find_contiguous_in_range(0, max_length(), num_regions);
+  return find_contiguous_in_range(0, reserved_length(), num_regions);
 }
 
 HeapRegion* HeapRegionManager::next_region_in_heap(const HeapRegion* r) const {
@@ -420,7 +428,7 @@ HeapRegion* HeapRegionManager::next_region_in_heap(const HeapRegion* r) const {
 }
 
 void HeapRegionManager::iterate(HeapRegionClosure* blk) const {
-  uint len = max_length();
+  uint len = reserved_length();
 
   for (uint i = 0; i < len; i++) {
     if (!is_available(i)) {
@@ -436,13 +444,13 @@ void HeapRegionManager::iterate(HeapRegionClosure* blk) const {
 }
 
 HeapRegionRange HeapRegionManager::find_unavailable_from_idx(uint index) const {
-  guarantee(index <= max_length(), "checking");
+  guarantee(index <= reserved_length(), "checking");
 
   // Find first unavailable region from offset.
   BitMap::idx_t start = _available_map.get_next_zero_offset(index);
   if (start == _available_map.size()) {
     // No unavailable regions found.
-    return HeapRegionRange(max_length(), max_length());
+    return HeapRegionRange(reserved_length(), reserved_length());
   }
 
   // The end of the range is the next available region.
@@ -452,6 +460,8 @@ HeapRegionRange HeapRegionManager::find_unavailable_from_idx(uint index) const {
   assert(!_available_map.at(end - 1), "Last region (" SIZE_FORMAT ") in range is not unavailable", end - 1);
   assert(end == _available_map.size() || _available_map.at(end), "Region (" SIZE_FORMAT ") is not available", end);
 
+  // Shrink returned range to number of regions left to commit if necessary.
+  end = MIN2(start + available(), end);
   return HeapRegionRange((uint) start, (uint) end);
 }
 
@@ -459,7 +469,7 @@ uint HeapRegionManager::find_highest_free(bool* expanded) {
   // Loop downwards from the highest region index, looking for an
   // entry which is either free or not yet committed.  If not yet
   // committed, expand_at that index.
-  uint curr = max_length() - 1;
+  uint curr = reserved_length() - 1;
   while (true) {
     HeapRegion *hr = _regions.get_by_index(curr);
     if (hr == NULL || !is_available(curr)) {
@@ -611,9 +621,12 @@ void HeapRegionManager::verify() {
   guarantee(length() <= _allocated_heapregions_length,
             "invariant: _length: %u _allocated_length: %u",
             length(), _allocated_heapregions_length);
-  guarantee(_allocated_heapregions_length <= max_length(),
+  guarantee(_allocated_heapregions_length <= reserved_length(),
             "invariant: _allocated_length: %u _max_length: %u",
-            _allocated_heapregions_length, max_length());
+            _allocated_heapregions_length, reserved_length());
+  guarantee(_num_committed <= max_length(),
+            "invariant: _num_committed: %u max_regions: %u",
+            _num_committed, max_length());
 
   bool prev_committed = true;
   uint num_committed = 0;
@@ -640,7 +653,7 @@ void HeapRegionManager::verify() {
     prev_committed = true;
     prev_end = hr->end();
   }
-  for (uint i = _allocated_heapregions_length; i < max_length(); i++) {
+  for (uint i = _allocated_heapregions_length; i < reserved_length(); i++) {
     guarantee(_regions.get_by_index(i) == NULL, "invariant i: %u", i);
   }
 
@@ -693,7 +706,7 @@ class G1RebuildFreeListTask : public AbstractGangTask {
       AbstractGangTask("G1 Rebuild Free List Task"),
       _hrm(hrm),
       _worker_freelists(NEW_C_HEAP_ARRAY(FreeRegionList, num_workers, mtGC)),
-      _worker_chunk_size((_hrm->max_length() + num_workers - 1) / num_workers),
+      _worker_chunk_size((_hrm->reserved_length() + num_workers - 1) / num_workers),
       _num_workers(num_workers) {
     for (uint worker = 0; worker < _num_workers; worker++) {
       ::new (&_worker_freelists[worker]) FreeRegionList("Appendable Worker Free List");
@@ -718,7 +731,7 @@ class G1RebuildFreeListTask : public AbstractGangTask {
     EventGCPhaseParallel event;
 
     uint start = worker_id * _worker_chunk_size;
-    uint end = MIN2(start + _worker_chunk_size, _hrm->max_length());
+    uint end = MIN2(start + _worker_chunk_size, _hrm->reserved_length());
 
     // If start is outside the heap, this worker has nothing to do.
     if (start > end) {
diff --git a/src/hotspot/share/gc/g1/heapRegionManager.hpp b/src/hotspot/share/gc/g1/heapRegionManager.hpp
index 4aad234dda1..c629b3ba562 100644
--- a/src/hotspot/share/gc/g1/heapRegionManager.hpp
+++ b/src/hotspot/share/gc/g1/heapRegionManager.hpp
@@ -73,13 +73,14 @@ class HeapRegionRange : public StackObj {
 // region we retain the HeapRegion to be able to re-use it in the
 // future (in case we recommit it).
 //
-// We keep track of three lengths:
+// We keep track of four lengths:
 //
 // * _num_committed (returned by length()) is the number of currently
 //   committed regions. These may not be contiguous.
 // * _allocated_heapregions_length (not exposed outside this class) is the
 //   number of regions+1 for which we have HeapRegions.
-// * max_length() returns the maximum number of regions the heap can have.
+// * max_length() returns the maximum number of regions the heap may commit.
+// * reserved_length() returns the maximum number of regions the heap has reserved.
 //
 
 class HeapRegionManager: public CHeapObj<mtGC> {
@@ -94,7 +95,7 @@ class HeapRegionManager: public CHeapObj<mtGC> {
   // for allocation.
   CHeapBitMap _available_map;
 
-   // The number of regions committed in the heap.
+  // The number of regions committed in the heap.
   uint _num_committed;
 
   // Internal only. The highest heap region +1 we allocated a HeapRegion instance for.
@@ -124,7 +125,7 @@ class HeapRegionManager: public CHeapObj<mtGC> {
 
   // Finds the next sequence of unavailable regions starting at the given index. Returns the
   // sequence found as a HeapRegionRange. If no regions can be found, both start and end of
-  // the returned range is equal to max_regions().
+  // the returned range is equal to reserved_length().
   HeapRegionRange find_unavailable_from_idx(uint index) const;
   // Finds the next sequence of empty regions starting from start_idx, going backwards in
   // the heap. Returns the length of the sequence found. If this value is zero, no
@@ -240,17 +241,17 @@ class HeapRegionManager: public CHeapObj<mtGC> {
     return num_free_regions() * HeapRegion::GrainBytes;
   }
 
-  // Return the number of available (uncommitted) regions.
+  // Return the number of regions available (uncommitted) regions.
   uint available() const { return max_length() - length(); }
 
   // Return the number of regions that have been committed in the heap.
   uint length() const { return _num_committed; }
 
-  // Return the maximum number of regions in the heap.
-  uint max_length() const { return (uint)_regions.length(); }
+  // The number of regions reserved for the heap.
+  uint reserved_length() const { return (uint)_regions.length(); }
 
   // Return maximum number of regions that heap can expand to.
-  virtual uint max_expandable_length() const { return (uint)_regions.length(); }
+  virtual uint max_length() const { return reserved_length(); }
 
   MemoryUsage get_auxiliary_data_memory_usage() const;
 
@@ -267,7 +268,7 @@ class HeapRegionManager: public CHeapObj<mtGC> {
   // this.
   virtual uint expand_at(uint start, uint num_regions, WorkGang* pretouch_workers);
 
-  // Try to expand on the given node index.
+  // Try to expand on the given node index, returning the index of the new region.
   virtual uint expand_on_preferred_node(uint node_index);
 
   HeapRegion* next_region_in_heap(const HeapRegion* r) const;
diff --git a/src/hotspot/share/gc/g1/heapRegionManager.inline.hpp b/src/hotspot/share/gc/g1/heapRegionManager.inline.hpp
index a72b5447c5f..e290ffb1abc 100644
--- a/src/hotspot/share/gc/g1/heapRegionManager.inline.hpp
+++ b/src/hotspot/share/gc/g1/heapRegionManager.inline.hpp
@@ -62,7 +62,7 @@ inline HeapRegion* HeapRegionManager::next_region_in_humongous(HeapRegion* hr) c
   assert(is_available(index), "pre-condition");
   assert(hr->is_humongous(), "next_region_in_humongous should only be called for a humongous region.");
   index++;
-  if (index < max_length() && is_available(index) && at(index)->is_continues_humongous()) {
+  if (index < reserved_length() && is_available(index) && at(index)->is_continues_humongous()) {
     return at(index);
   } else {
     return NULL;
diff --git a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp
index b38d9f66eab..f23932b9d0e 100644
--- a/src/hotspot/share/gc/g1/heapRegionRemSet.cpp
+++ b/src/hotspot/share/gc/g1/heapRegionRemSet.cpp
@@ -33,6 +33,7 @@
 #include "memory/padded.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/globals_extension.hpp"
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/formatBuffer.hpp"
@@ -267,7 +268,7 @@ PerRegionTable* OtherRegionsTable::delete_region_table(size_t& added_by_deleted)
     _coarse_map.at_put(max_hrm_index, true);
   } else {
     // This will lazily initialize an uninitialized bitmap
-    _coarse_map.reinitialize(G1CollectedHeap::heap()->max_regions());
+    _coarse_map.reinitialize(G1CollectedHeap::heap()->max_reserved_regions());
     assert(!_coarse_map.at(max_hrm_index), "No coarse entries");
     _coarse_map.at_put(max_hrm_index, true);
     // Release store guarantees that the bitmap has initialized before any
diff --git a/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.cpp b/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.cpp
index 69180522603..85a0af541f0 100644
--- a/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.cpp
+++ b/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.cpp
@@ -59,7 +59,7 @@ void HeterogeneousHeapRegionManager::initialize(G1RegionToSpaceMapper* heap_stor
 // Dram regions are committed later as needed during mutator region allocation or
 // when young list target length is determined after gc cycle.
 uint HeterogeneousHeapRegionManager::expand_by(uint num_regions, WorkGang* pretouch_workers) {
-  uint num_regions_possible = total_regions_committed() >= max_expandable_length() ? 0 : max_expandable_length() - total_regions_committed();
+  uint num_regions_possible = total_regions_committed() >= max_length() ? 0 : max_length() - total_regions_committed();
   uint num_expanded = expand_nvdimm(MIN2(num_regions, num_regions_possible), pretouch_workers);
   return num_expanded;
 }
@@ -71,11 +71,11 @@ uint HeterogeneousHeapRegionManager::expand_at(uint start, uint num_regions, Wor
   if (num_regions == 0) {
     return 0;
   }
-  uint target_num_regions = MIN2(num_regions, max_expandable_length() - total_regions_committed());
+  uint target_num_regions = MIN2(num_regions, max_length() - total_regions_committed());
   uint end = is_in_nvdimm(start) ? end_index_of_nvdimm() : end_index_of_dram();
 
   uint num_expanded = expand_in_range(start, end, target_num_regions, pretouch_workers);
-  assert(total_regions_committed() <= max_expandable_length(), "must be");
+  assert(total_regions_committed() <= max_length(), "must be");
   return num_expanded;
 }
 
@@ -140,13 +140,13 @@ uint HeterogeneousHeapRegionManager::num_committed_nvdimm() const {
 }
 
 // Return maximum number of regions that heap can expand to.
-uint HeterogeneousHeapRegionManager::max_expandable_length() const {
+uint HeterogeneousHeapRegionManager::max_length() const {
   return _max_regions;
 }
 
 uint HeterogeneousHeapRegionManager::find_unavailable_in_range(uint start_idx, uint end_idx, uint* res_idx) const {
   guarantee(res_idx != NULL, "checking");
-  guarantee(start_idx <= (max_length() + 1), "checking");
+  guarantee(start_idx <= (reserved_length() + 1), "checking");
 
   uint num_regions = 0;
 
@@ -232,8 +232,8 @@ uint HeterogeneousHeapRegionManager::shrink_in_range(uint start, uint end, uint
 
 uint HeterogeneousHeapRegionManager::find_empty_in_range_reverse(uint start_idx, uint end_idx, uint* res_idx) {
   guarantee(res_idx != NULL, "checking");
-  guarantee(start_idx < max_length(), "checking");
-  guarantee(end_idx < max_length(), "checking");
+  guarantee(start_idx < reserved_length(), "checking");
+  guarantee(end_idx < reserved_length(), "checking");
   if(start_idx > end_idx) {
     return 0;
   }
@@ -385,7 +385,7 @@ uint HeterogeneousHeapRegionManager::find_contiguous(size_t start, size_t end, s
                 "Found region sequence starting at " UINT32_FORMAT ", length " SIZE_FORMAT
                 " that is not empty at " UINT32_FORMAT ". Hr is " PTR_FORMAT, found, num, i, p2i(hr));
     }
-    if (!empty_only && length_unavailable > (max_expandable_length() - total_regions_committed())) {
+    if (!empty_only && length_unavailable > (max_length() - total_regions_committed())) {
       // if 'length_unavailable' number of regions will be made available, we will exceed max regions.
       return G1_NO_HRM_INDEX;
     }
diff --git a/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.hpp b/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.hpp
index 1e65c145396..ad4a446b6d2 100644
--- a/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.hpp
+++ b/src/hotspot/share/gc/g1/heterogeneousHeapRegionManager.hpp
@@ -124,7 +124,7 @@ class HeterogeneousHeapRegionManager : public HeapRegionManager {
   virtual HeapRegion* allocate_humongous_allow_expand(uint num_regions);
 
   // Return maximum number of regions that heap can expand to.
-  uint max_expandable_length() const;
+  uint max_length() const;
 
   // Override. Expand in nv-dimm.
   uint expand_by(uint num_regions, WorkGang* pretouch_workers);
diff --git a/src/hotspot/share/gc/g1/jvmFlagConstraintsG1.hpp b/src/hotspot/share/gc/g1/jvmFlagConstraintsG1.hpp
index 9ae5782850d..27ca9c8e585 100644
--- a/src/hotspot/share/gc/g1/jvmFlagConstraintsG1.hpp
+++ b/src/hotspot/share/gc/g1/jvmFlagConstraintsG1.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,18 +28,21 @@
 #include "runtime/flags/jvmFlag.hpp"
 #include "utilities/globalDefinitions.hpp"
 
-// G1 Flag Constraints
-JVMFlag::Error G1RSetRegionEntriesConstraintFunc(intx value, bool verbose);
-JVMFlag::Error G1RSetSparseRegionEntriesConstraintFunc(intx value, bool verbose);
-JVMFlag::Error G1HeapRegionSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error G1NewSizePercentConstraintFunc(uintx value, bool verbose);
-JVMFlag::Error G1MaxNewSizePercentConstraintFunc(uintx value, bool verbose);
+#define G1_GC_CONSTRAINTS(f)                          \
+                                                      \
+  /* G1 Flag Constraints */                           \
+  f(intx,   G1RSetRegionEntriesConstraintFunc)        \
+  f(intx,   G1RSetSparseRegionEntriesConstraintFunc)  \
+  f(size_t, G1HeapRegionSizeConstraintFunc)           \
+  f(uintx,  G1NewSizePercentConstraintFunc)           \
+  f(uintx,  G1MaxNewSizePercentConstraintFunc)        \
+                                                      \
+  /* G1 Subconstraints */                             \
+  f(uintx,  MaxGCPauseMillisConstraintFuncG1)         \
+  f(uintx,  GCPauseIntervalMillisConstraintFuncG1)    \
+  f(size_t, NewSizeConstraintFuncG1)
 
-// G1 Subconstraints
-JVMFlag::Error MaxGCPauseMillisConstraintFuncG1(uintx value, bool verbose);
-JVMFlag::Error GCPauseIntervalMillisConstraintFuncG1(uintx value, bool verbose);
-JVMFlag::Error MaxSizeForHeapAlignmentG1(const char* name, size_t value, bool verbose);
-JVMFlag::Error NewSizeConstraintFuncG1(size_t value, bool verbose);
+G1_GC_CONSTRAINTS(DECLARE_CONSTRAINT)
 
 size_t MaxSizeForHeapAlignmentG1();
 
diff --git a/src/hotspot/share/gc/parallel/jvmFlagConstraintsParallel.hpp b/src/hotspot/share/gc/parallel/jvmFlagConstraintsParallel.hpp
index cc35f62e9b9..2b5c79322e4 100644
--- a/src/hotspot/share/gc/parallel/jvmFlagConstraintsParallel.hpp
+++ b/src/hotspot/share/gc/parallel/jvmFlagConstraintsParallel.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,8 +29,11 @@
 #include "utilities/globalDefinitions.hpp"
 
 // Parallel Subconstraints
-JVMFlag::Error ParallelGCThreadsConstraintFuncParallel(uint value, bool verbose);
-JVMFlag::Error InitialTenuringThresholdConstraintFuncParallel(uintx value, bool verbose);
-JVMFlag::Error MaxTenuringThresholdConstraintFuncParallel(uintx value, bool verbose);
+#define PARALLEL_GC_CONSTRAINTS(f)                          \
+  f(uint, ParallelGCThreadsConstraintFuncParallel)          \
+  f(uintx, InitialTenuringThresholdConstraintFuncParallel)  \
+  f(uintx, MaxTenuringThresholdConstraintFuncParallel)
+
+PARALLEL_GC_CONSTRAINTS(DECLARE_CONSTRAINT)
 
 #endif // SHARE_GC_PARALLEL_JVMFLAGCONSTRAINTSPARALLEL_HPP
diff --git a/src/hotspot/share/gc/parallel/parallel_globals.hpp b/src/hotspot/share/gc/parallel/parallel_globals.hpp
index f949fa5f133..19953ca0b61 100644
--- a/src/hotspot/share/gc/parallel/parallel_globals.hpp
+++ b/src/hotspot/share/gc/parallel/parallel_globals.hpp
@@ -29,13 +29,7 @@
                           develop_pd,                                       \
                           product,                                          \
                           product_pd,                                       \
-                          diagnostic,                                       \
-                          diagnostic_pd,                                    \
-                          experimental,                                     \
                           notproduct,                                       \
-                          manageable,                                       \
-                          product_rw,                                       \
-                          lp64_product,                                     \
                           range,                                            \
                           constraint)                                       \
   product(uintx, HeapMaximumCompactionInterval, 20,                         \
@@ -67,4 +61,6 @@
   product(bool, PSChunkLargeArrays, true,                                   \
           "Process large arrays in chunks")
 
+// end of GC_PARALLEL_FLAGS
+
 #endif // SHARE_GC_PARALLEL_PARALLEL_GLOBALS_HPP
diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp
index 1a11abb2614..83a5e1f6412 100644
--- a/src/hotspot/share/gc/serial/defNewGeneration.cpp
+++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp
@@ -931,11 +931,7 @@ HeapWord* DefNewGeneration::allocate(size_t word_size, bool is_tlab) {
   // Note that since DefNewGeneration supports lock-free allocation, we
   // have to use it here, as well.
   HeapWord* result = eden()->par_allocate(word_size);
-  if (result != NULL) {
-    if (_old_gen != NULL) {
-      _old_gen->sample_eden_chunk();
-    }
-  } else {
+  if (result == NULL) {
     // If the eden is full and the last collection bailed out, we are running
     // out of heap space, and we try to allocate the from-space, too.
     // allocate_from_space can't be inlined because that would introduce a
@@ -947,11 +943,7 @@ HeapWord* DefNewGeneration::allocate(size_t word_size, bool is_tlab) {
 
 HeapWord* DefNewGeneration::par_allocate(size_t word_size,
                                          bool is_tlab) {
-  HeapWord* res = eden()->par_allocate(word_size);
-  if (_old_gen != NULL) {
-    _old_gen->sample_eden_chunk();
-  }
-  return res;
+  return eden()->par_allocate(word_size);
 }
 
 size_t DefNewGeneration::tlab_capacity() const {
diff --git a/src/hotspot/share/gc/serial/serial_globals.hpp b/src/hotspot/share/gc/serial/serial_globals.hpp
index 4da44ff2c55..91a9d8c52b9 100644
--- a/src/hotspot/share/gc/serial/serial_globals.hpp
+++ b/src/hotspot/share/gc/serial/serial_globals.hpp
@@ -25,18 +25,14 @@
 #ifndef SHARE_GC_SERIAL_SERIAL_GLOBALS_HPP
 #define SHARE_GC_SERIAL_SERIAL_GLOBALS_HPP
 
-#define GC_SERIAL_FLAGS(develop,                                            \
-                        develop_pd,                                         \
-                        product,                                            \
-                        product_pd,                                         \
-                        diagnostic,                                         \
-                        diagnostic_pd,                                      \
-                        experimental,                                       \
-                        notproduct,                                         \
-                        manageable,                                         \
-                        product_rw,                                         \
-                        lp64_product,                                       \
-                        range,                                              \
+#define GC_SERIAL_FLAGS(develop,     \
+                        develop_pd,  \
+                        product,     \
+                        product_pd,  \
+                        notproduct,  \
+                        range,       \
                         constraint)
 
+// end of GC_SERIAL_FLAGS
+
 #endif // SHARE_GC_SERIAL_SERIAL_GLOBALS_HPP
diff --git a/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp b/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp
index 34b74c951df..ebe04a23b23 100644
--- a/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp
+++ b/src/hotspot/share/gc/shared/cardTableBarrierSet.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -187,7 +187,7 @@ void CardTableBarrierSet::on_thread_detach(Thread* thread) {
   // card-table (or other remembered set structure) before GC starts
   // processing the card-table (or other remembered set).
   if (thread->is_Java_thread()) { // Only relevant for Java threads.
-    flush_deferred_card_mark_barrier((JavaThread*)thread);
+    flush_deferred_card_mark_barrier(thread->as_Java_thread());
   }
 }
 
diff --git a/src/hotspot/share/gc/shared/collectedHeap.cpp b/src/hotspot/share/gc/shared/collectedHeap.cpp
index 22ccd8c5f57..2e41655da99 100644
--- a/src/hotspot/share/gc/shared/collectedHeap.cpp
+++ b/src/hotspot/share/gc/shared/collectedHeap.cpp
@@ -36,6 +36,7 @@
 #include "gc/shared/gcWhen.hpp"
 #include "gc/shared/memAllocator.hpp"
 #include "logging/log.hpp"
+#include "logging/logStream.hpp"
 #include "memory/metaspace.hpp"
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
@@ -123,14 +124,28 @@ MetaspaceSummary CollectedHeap::create_metaspace_summary() {
 }
 
 void CollectedHeap::print_heap_before_gc() {
-  Universe::print_heap_before_gc();
+  LogTarget(Debug, gc, heap) lt;
+  if (lt.is_enabled()) {
+    LogStream ls(lt);
+    ls.print_cr("Heap before GC invocations=%u (full %u):", total_collections(), total_full_collections());
+    ResourceMark rm;
+    print_on(&ls);
+  }
+
   if (_gc_heap_log != NULL) {
     _gc_heap_log->log_heap_before(this);
   }
 }
 
 void CollectedHeap::print_heap_after_gc() {
-  Universe::print_heap_after_gc();
+  LogTarget(Debug, gc, heap) lt;
+  if (lt.is_enabled()) {
+    LogStream ls(lt);
+    ls.print_cr("Heap after GC invocations=%u (full %u):", total_collections(), total_full_collections());
+    ResourceMark rm;
+    print_on(&ls);
+  }
+
   if (_gc_heap_log != NULL) {
     _gc_heap_log->log_heap_after(this);
   }
diff --git a/src/hotspot/share/gc/shared/gcConfiguration.cpp b/src/hotspot/share/gc/shared/gcConfiguration.cpp
index 2a24e031b9c..195b64dcc3c 100644
--- a/src/hotspot/share/gc/shared/gcConfiguration.cpp
+++ b/src/hotspot/share/gc/shared/gcConfiguration.cpp
@@ -22,6 +22,7 @@
  *
  */
 #include "precompiled.hpp"
+#include "runtime/globals_extension.hpp"
 
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/gcArguments.hpp"
diff --git a/src/hotspot/share/gc/shared/gc_globals.hpp b/src/hotspot/share/gc/shared/gc_globals.hpp
index 811cfa3da51..956634b2066 100644
--- a/src/hotspot/share/gc/shared/gc_globals.hpp
+++ b/src/hotspot/share/gc/shared/gc_globals.hpp
@@ -50,13 +50,7 @@
                  develop_pd,                                                \
                  product,                                                   \
                  product_pd,                                                \
-                 diagnostic,                                                \
-                 diagnostic_pd,                                             \
-                 experimental,                                              \
                  notproduct,                                                \
-                 manageable,                                                \
-                 product_rw,                                                \
-                 lp64_product,                                              \
                  range,                                                     \
                  constraint)                                                \
                                                                             \
@@ -65,13 +59,7 @@
     develop_pd,                                                             \
     product,                                                                \
     product_pd,                                                             \
-    diagnostic,                                                             \
-    diagnostic_pd,                                                          \
-    experimental,                                                           \
     notproduct,                                                             \
-    manageable,                                                             \
-    product_rw,                                                             \
-    lp64_product,                                                           \
     range,                                                                  \
     constraint))                                                            \
                                                                             \
@@ -80,13 +68,7 @@
     develop_pd,                                                             \
     product,                                                                \
     product_pd,                                                             \
-    diagnostic,                                                             \
-    diagnostic_pd,                                                          \
-    experimental,                                                           \
     notproduct,                                                             \
-    manageable,                                                             \
-    product_rw,                                                             \
-    lp64_product,                                                           \
     range,                                                                  \
     constraint))                                                            \
                                                                             \
@@ -95,13 +77,7 @@
     develop_pd,                                                             \
     product,                                                                \
     product_pd,                                                             \
-    diagnostic,                                                             \
-    diagnostic_pd,                                                          \
-    experimental,                                                           \
     notproduct,                                                             \
-    manageable,                                                             \
-    product_rw,                                                             \
-    lp64_product,                                                           \
     range,                                                                  \
     constraint))                                                            \
                                                                             \
@@ -110,13 +86,7 @@
     develop_pd,                                                             \
     product,                                                                \
     product_pd,                                                             \
-    diagnostic,                                                             \
-    diagnostic_pd,                                                          \
-    experimental,                                                           \
     notproduct,                                                             \
-    manageable,                                                             \
-    product_rw,                                                             \
-    lp64_product,                                                           \
     range,                                                                  \
     constraint))                                                            \
                                                                             \
@@ -125,13 +95,7 @@
     develop_pd,                                                             \
     product,                                                                \
     product_pd,                                                             \
-    diagnostic,                                                             \
-    diagnostic_pd,                                                          \
-    experimental,                                                           \
     notproduct,                                                             \
-    manageable,                                                             \
-    product_rw,                                                             \
-    lp64_product,                                                           \
     range,                                                                  \
     constraint))                                                            \
                                                                             \
@@ -140,13 +104,7 @@
     develop_pd,                                                             \
     product,                                                                \
     product_pd,                                                             \
-    diagnostic,                                                             \
-    diagnostic_pd,                                                          \
-    experimental,                                                           \
     notproduct,                                                             \
-    manageable,                                                             \
-    product_rw,                                                             \
-    lp64_product,                                                           \
     range,                                                                  \
     constraint))                                                            \
                                                                             \
@@ -161,7 +119,7 @@
   product(bool, UseParallelGC, false,                                       \
           "Use the Parallel garbage collector.")                            \
                                                                             \
-  experimental(bool, UseEpsilonGC, false,                                   \
+  product(bool, UseEpsilonGC, false, EXPERIMENTAL,                          \
           "Use the Epsilon (no-op) garbage collector")                      \
                                                                             \
   product(bool, UseZGC, false,                                              \
@@ -179,14 +137,14 @@
           "ParallelGCThreads parallel collectors will use for garbage "     \
           "collection work")                                                \
                                                                             \
-  diagnostic(bool, InjectGCWorkerCreationFailure, false,                    \
+  product(bool, InjectGCWorkerCreationFailure, false, DIAGNOSTIC,           \
              "Inject thread creation failures for "                         \
              "UseDynamicNumberOfGCThreads")                                 \
                                                                             \
   product(size_t, HeapSizePerGCThread, ScaleForWordSize(32*M),              \
           "Size of heap (bytes) per GC thread used in calculating the "     \
           "number of GC threads")                                           \
-          range((size_t)os::vm_page_size(), (size_t)max_uintx)              \
+          constraint(VMPageSizeConstraintFunc, AtParse)                     \
                                                                             \
   product(uint, ConcGCThreads, 0,                                           \
           "Number of threads concurrent gc will use")                       \
@@ -211,7 +169,7 @@
           "is active (as a percentage)")                                    \
           range(0, 100)                                                     \
                                                                             \
-  diagnostic(uintx, GCLockerRetryAllocationCount, 2,                        \
+  product(uintx, GCLockerRetryAllocationCount, 2, DIAGNOSTIC,               \
           "Number of times to retry allocations when "                      \
           "blocked by the GC locker")                                       \
           range(0, max_uintx)                                               \
@@ -268,7 +226,7 @@
   product(bool, ParallelRefProcBalancingEnabled, true,                      \
           "Enable balancing of reference processing queues")                \
                                                                             \
-  experimental(size_t, ReferencesPerThread, 1000,                           \
+  product(size_t, ReferencesPerThread, 1000, EXPERIMENTAL,                  \
                "Ergonomically start one thread for this amount of "         \
                "references for reference processing if "                    \
                "ParallelRefProcEnabled is true. Specify 0 to disable and "  \
@@ -308,17 +266,17 @@
   develop(uintx, PromotionFailureALotInterval, 5,                           \
           "Total collections between promotion failures a lot")             \
                                                                             \
-  experimental(uintx, WorkStealingSleepMillis, 1,                           \
+  product(uintx, WorkStealingSleepMillis, 1, EXPERIMENTAL,                  \
           "Sleep time when sleep is used for yields")                       \
                                                                             \
-  experimental(uintx, WorkStealingYieldsBeforeSleep, 5000,                  \
+  product(uintx, WorkStealingYieldsBeforeSleep, 5000, EXPERIMENTAL,         \
           "Number of yields before a sleep is done during work stealing")   \
                                                                             \
-  experimental(uintx, WorkStealingHardSpins, 4096,                          \
+  product(uintx, WorkStealingHardSpins, 4096, EXPERIMENTAL,                 \
           "Number of iterations in a spin loop between checks on "          \
           "time out of hard spin")                                          \
                                                                             \
-  experimental(uintx, WorkStealingSpinToYieldRatio, 10,                     \
+  product(uintx, WorkStealingSpinToYieldRatio, 10, EXPERIMENTAL,            \
           "Ratio of hard spins to calls to yield")                          \
                                                                             \
   develop(uintx, ObjArrayMarkingStride, 2048,                               \
@@ -563,27 +521,27 @@
           "How many fields ahead to prefetch in oop scan (<= 0 means off)") \
           range(-1, max_jint)                                               \
                                                                             \
-  diagnostic(bool, VerifyDuringStartup, false,                              \
+  product(bool, VerifyDuringStartup, false, DIAGNOSTIC,                     \
           "Verify memory system before executing any Java code "            \
           "during VM initialization")                                       \
                                                                             \
-  diagnostic(bool, VerifyBeforeExit, trueInDebug,                           \
+  product(bool, VerifyBeforeExit, trueInDebug, DIAGNOSTIC,                  \
           "Verify system before exiting")                                   \
                                                                             \
-  diagnostic(bool, VerifyBeforeGC, false,                                   \
+  product(bool, VerifyBeforeGC, false, DIAGNOSTIC,                          \
           "Verify memory system before GC")                                 \
                                                                             \
-  diagnostic(bool, VerifyAfterGC, false,                                    \
+  product(bool, VerifyAfterGC, false, DIAGNOSTIC,                           \
           "Verify memory system after GC")                                  \
                                                                             \
-  diagnostic(bool, VerifyDuringGC, false,                                   \
+  product(bool, VerifyDuringGC, false, DIAGNOSTIC,                          \
           "Verify memory system during GC (between phases)")                \
                                                                             \
-  diagnostic(ccstrlist, VerifyGCType, "",                                   \
+  product(ccstrlist, VerifyGCType, "", DIAGNOSTIC,                          \
              "GC type(s) to verify when Verify*GC is enabled."              \
              "Available types are collector specific.")                     \
                                                                             \
-  diagnostic(ccstrlist, VerifySubSet, "",                                   \
+  product(ccstrlist, VerifySubSet, "", DIAGNOSTIC,                          \
           "Memory sub-systems to verify when Verify*GC flag(s) "            \
           "are enabled. One or more sub-systems can be specified "          \
           "in a comma separated string. Sub-systems are: "                  \
@@ -591,20 +549,20 @@
           "dictionary, classloader_data_graph, metaspace, jni_handles, "    \
           "codecache_oops")                                                 \
                                                                             \
-  diagnostic(bool, GCParallelVerificationEnabled, true,                     \
+  product(bool, GCParallelVerificationEnabled, true, DIAGNOSTIC,            \
           "Enable parallel memory system verification")                     \
                                                                             \
-  diagnostic(bool, DeferInitialCardMark, false,                             \
+  product(bool, DeferInitialCardMark, false, DIAGNOSTIC,                    \
           "When +ReduceInitialCardMarks, explicitly defer any that "        \
           "may arise from new_pre_store_barrier")                           \
                                                                             \
   product(bool, UseCondCardMark, false,                                     \
           "Check for already marked card before updating card table")       \
                                                                             \
-  diagnostic(bool, VerifyRememberedSets, false,                             \
+  product(bool, VerifyRememberedSets, false, DIAGNOSTIC,                    \
           "Verify GC remembered sets")                                      \
                                                                             \
-  diagnostic(bool, VerifyObjectStartArray, true,                            \
+  product(bool, VerifyObjectStartArray, true, DIAGNOSTIC,                   \
           "Verify GC object start array if verify before/after")            \
                                                                             \
   product(bool, DisableExplicitGC, false,                                   \
@@ -649,7 +607,7 @@
           "Maximum heap size (in bytes)")                                   \
           constraint(MaxHeapSizeConstraintFunc,AfterErgo)                   \
                                                                             \
-  manageable(size_t, SoftMaxHeapSize, 0,                                    \
+  product(size_t, SoftMaxHeapSize, 0, MANAGEABLE,                           \
           "Soft limit for maximum heap size (in bytes)")                    \
           constraint(SoftMaxHeapSizeConstraintFunc,AfterMemoryInit)         \
                                                                             \
@@ -730,11 +688,11 @@
           "will retry before printing a warning")                           \
           range(0, max_uintx)                                               \
                                                                             \
-  diagnostic(uintx, VerifyGCStartAt,   0,                                   \
+  product(uintx, VerifyGCStartAt,   0, DIAGNOSTIC,                          \
           "GC invoke count where +VerifyBefore/AfterGC kicks in")           \
           range(0, max_uintx)                                               \
                                                                             \
-  diagnostic(intx, VerifyGCLevel,     0,                                    \
+  product(intx, VerifyGCLevel,     0, DIAGNOSTIC,                           \
           "Generation level at which to start +VerifyBefore/AfterGC")       \
           range(0, 1)                                                       \
                                                                             \
@@ -775,4 +733,6 @@
           "during parallel gc")                                             \
           range(0, max_juint)
 
+// end of GC_FLAGS
+
 #endif // SHARE_GC_SHARED_GC_GLOBALS_HPP
diff --git a/src/hotspot/share/gc/shared/generation.hpp b/src/hotspot/share/gc/shared/generation.hpp
index 539e6675fc2..9643dd74db1 100644
--- a/src/hotspot/share/gc/shared/generation.hpp
+++ b/src/hotspot/share/gc/shared/generation.hpp
@@ -371,17 +371,6 @@ class Generation: public CHeapObj<mtGC> {
   virtual void post_compact() { ShouldNotReachHere(); }
 #endif
 
-  // Support for CMS's rescan. In this general form we return a pointer
-  // to an abstract object that can be used, based on specific previously
-  // decided protocols, to exchange information between generations,
-  // information that may be useful for speeding up certain types of
-  // garbage collectors. A NULL value indicates to the client that
-  // no data recording is expected by the provider. The data-recorder is
-  // expected to be GC worker thread-local, with the worker index
-  // indicated by "thr_num".
-  virtual void* get_data_recorder(int thr_num) { return NULL; }
-  virtual void sample_eden_chunk() {}
-
   // Some generations may require some cleanup actions before allowing
   // a verification.
   virtual void prepare_for_verify() {}
diff --git a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.hpp b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.hpp
index 12602a19fee..f2962b41c63 100644
--- a/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.hpp
+++ b/src/hotspot/share/gc/shared/jvmFlagConstraintsGC.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,38 +40,44 @@
  * whenever flag's value changes. If the constraint fails the function should return
  * an appropriate error value.
  */
+#define SHARED_GC_CONSTRAINTS(f)                               \
+ f(uint,   ParallelGCThreadsConstraintFunc)                    \
+ f(uint,   ConcGCThreadsConstraintFunc)                        \
+ f(size_t, YoungPLABSizeConstraintFunc)                        \
+ f(size_t, OldPLABSizeConstraintFunc)                          \
+ f(uintx,  MinHeapFreeRatioConstraintFunc)                     \
+ f(uintx,  MaxHeapFreeRatioConstraintFunc)                     \
+ f(intx,   SoftRefLRUPolicyMSPerMBConstraintFunc)              \
+ f(size_t, MarkStackSizeConstraintFunc)                        \
+ f(uintx,  MinMetaspaceFreeRatioConstraintFunc)                \
+ f(uintx,  MaxMetaspaceFreeRatioConstraintFunc)                \
+ f(uintx,  InitialTenuringThresholdConstraintFunc)             \
+ f(uintx,  MaxTenuringThresholdConstraintFunc)                 \
+                                                               \
+ f(uintx,  MaxGCPauseMillisConstraintFunc)                     \
+ f(uintx,  GCPauseIntervalMillisConstraintFunc)                \
+ f(size_t, InitialBootClassLoaderMetaspaceSizeConstraintFunc)  \
+ f(size_t, MinHeapSizeConstraintFunc)                          \
+ f(size_t, InitialHeapSizeConstraintFunc)                      \
+ f(size_t, MaxHeapSizeConstraintFunc)                          \
+ f(size_t, SoftMaxHeapSizeConstraintFunc)                      \
+ f(size_t, HeapBaseMinAddressConstraintFunc)                   \
+ f(size_t, NewSizeConstraintFunc)                              \
+ f(size_t, MinTLABSizeConstraintFunc)                          \
+ f(size_t, TLABSizeConstraintFunc)                             \
+ f(uintx,  TLABWasteIncrementConstraintFunc)                   \
+ f(uintx,  SurvivorRatioConstraintFunc)                        \
+ f(size_t, MetaspaceSizeConstraintFunc)                        \
+ f(size_t, MaxMetaspaceSizeConstraintFunc)                     \
+ f(intx,   SurvivorAlignmentInBytesConstraintFunc)
 
-JVMFlag::Error ParallelGCThreadsConstraintFunc(uint value, bool verbose);
-JVMFlag::Error ConcGCThreadsConstraintFunc(uint value, bool verbose);
-JVMFlag::Error YoungPLABSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error OldPLABSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error MinHeapFreeRatioConstraintFunc(uintx value, bool verbose);
-JVMFlag::Error MaxHeapFreeRatioConstraintFunc(uintx value, bool verbose);
-JVMFlag::Error SoftRefLRUPolicyMSPerMBConstraintFunc(intx value, bool verbose);
-JVMFlag::Error MarkStackSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error MinMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose);
-JVMFlag::Error MaxMetaspaceFreeRatioConstraintFunc(uintx value, bool verbose);
-JVMFlag::Error InitialTenuringThresholdConstraintFunc(uintx value, bool verbose);
-JVMFlag::Error MaxTenuringThresholdConstraintFunc(uintx value, bool verbose);
+SHARED_GC_CONSTRAINTS(DECLARE_CONSTRAINT)
 
-JVMFlag::Error MaxGCPauseMillisConstraintFunc(uintx value, bool verbose);
-JVMFlag::Error GCPauseIntervalMillisConstraintFunc(uintx value, bool verbose);
-JVMFlag::Error InitialBootClassLoaderMetaspaceSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error MinHeapSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error InitialHeapSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error MaxHeapSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error SoftMaxHeapSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error HeapBaseMinAddressConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error NewSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error MinTLABSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error TLABSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error TLABWasteIncrementConstraintFunc(uintx value, bool verbose);
-JVMFlag::Error SurvivorRatioConstraintFunc(uintx value, bool verbose);
-JVMFlag::Error MetaspaceSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error MaxMetaspaceSizeConstraintFunc(size_t value, bool verbose);
-JVMFlag::Error SurvivorAlignmentInBytesConstraintFunc(intx value, bool verbose);
-
-// Internal
 JVMFlag::Error MaxPLABSizeBounds(const char* name, size_t value, bool verbose);
 
+#define GC_CONSTRAINTS(f)                      \
+  SHARED_GC_CONSTRAINTS(f)                     \
+  G1GC_ONLY(G1_GC_CONSTRAINTS(f))              \
+  PARALLELGC_ONLY(PARALLEL_GC_CONSTRAINTS(f))
+
 #endif // SHARE_GC_SHARED_JVMFLAGCONSTRAINTSGC_HPP
diff --git a/src/hotspot/share/gc/shared/taskqueue.hpp b/src/hotspot/share/gc/shared/taskqueue.hpp
index 312050b4098..e20f77e0ebe 100644
--- a/src/hotspot/share/gc/shared/taskqueue.hpp
+++ b/src/hotspot/share/gc/shared/taskqueue.hpp
@@ -113,8 +113,8 @@ class TaskQueueSuper: public CHeapObj<F> {
 
   // N must be a power of 2 for computing modulo via masking.
   // N must be >= 2 for the algorithm to work at all, though larger is better.
-  // C++11: is_power_of_2 is not (yet) constexpr.
-  STATIC_ASSERT((N >= 2) && ((N & (N - 1)) == 0));
+  STATIC_ASSERT(N >= 2);
+  STATIC_ASSERT(is_power_of_2(N));
   static const uint MOD_N_MASK = N - 1;
 
   class Age {
diff --git a/src/hotspot/share/gc/shared/workerPolicy.cpp b/src/hotspot/share/gc/shared/workerPolicy.cpp
index 76f80dc1396..8116265bd01 100644
--- a/src/hotspot/share/gc/shared/workerPolicy.cpp
+++ b/src/hotspot/share/gc/shared/workerPolicy.cpp
@@ -27,6 +27,7 @@
 #include "gc/shared/workerPolicy.hpp"
 #include "logging/log.hpp"
 #include "memory/universe.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/os.inline.hpp"
 #include "runtime/vm_version.hpp"
 
diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp
index b64bf975ad6..4ce2366fe0c 100644
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp
@@ -23,7 +23,6 @@
  */
 
 #include "precompiled.hpp"
-
 #include "gc/shared/gcCause.hpp"
 #include "gc/shenandoah/shenandoahCollectionSet.inline.hpp"
 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
@@ -33,6 +32,7 @@
 #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
 #include "logging/log.hpp"
 #include "logging/logTag.hpp"
+#include "runtime/globals_extension.hpp"
 
 int ShenandoahHeuristics::compare_by_garbage(RegionData a, RegionData b) {
   if (a._garbage > b._garbage)
diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp
index 78564bd45e1..ca221567b2c 100644
--- a/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp
+++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahIUMode.cpp
@@ -31,6 +31,7 @@
 #include "gc/shenandoah/mode/shenandoahIUMode.hpp"
 #include "logging/log.hpp"
 #include "logging/logTag.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 
 void ShenandoahIUMode::initialize_flags() const {
diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp
index 1d5005f70b4..bb7d0c4660b 100644
--- a/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp
+++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahPassiveMode.cpp
@@ -27,6 +27,7 @@
 #include "gc/shenandoah/mode/shenandoahPassiveMode.hpp"
 #include "logging/log.hpp"
 #include "logging/logTag.hpp"
+#include "runtime/globals_extension.hpp"
 
 void ShenandoahPassiveMode::initialize_flags() const {
   // Do not allow concurrent cycles.
diff --git a/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp
index c6e7c8fc6a8..020df4b581a 100644
--- a/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp
+++ b/src/hotspot/share/gc/shenandoah/mode/shenandoahSATBMode.cpp
@@ -31,6 +31,7 @@
 #include "gc/shenandoah/mode/shenandoahSATBMode.hpp"
 #include "logging/log.hpp"
 #include "logging/logTag.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 
 void ShenandoahSATBMode::initialize_flags() const {
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp
index d146214f517..f0733a6fa45 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp
@@ -29,6 +29,7 @@
 #include "gc/shenandoah/shenandoahCollectorPolicy.hpp"
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahHeapRegion.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "utilities/defaultStream.hpp"
 
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
index 108952fa0e9..891ccfe93d6 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentMark.cpp
@@ -206,8 +206,7 @@ class ShenandoahSATBAndRemarkCodeRootsThreadsClosure : public ThreadClosure {
           // * Weakly reachable otherwise
           // Some objects reachable from nmethods, such as the class loader (or klass_holder) of the receiver should be
           // live by the SATB invariant but other oops recorded in nmethods may behave differently.
-          JavaThread* jt = (JavaThread*)thread;
-          jt->nmethods_do(_code_cl);
+          thread->as_Java_thread()->nmethods_do(_code_cl);
         }
       }
     }
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
index ea7cafbcd68..7df181fa2ca 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp
@@ -2162,10 +2162,11 @@ bool ShenandoahHeap::try_cancel_gc() {
     else if (prev == CANCELLED) return false;
     assert(ShenandoahSuspendibleWorkers, "should not get here when not using suspendible workers");
     assert(prev == NOT_CANCELLED, "must be NOT_CANCELLED");
-    if (Thread::current()->is_Java_thread()) {
+    Thread* thread = Thread::current();
+    if (thread->is_Java_thread()) {
       // We need to provide a safepoint here, otherwise we might
       // spin forever if a SP is pending.
-      ThreadBlockInVM sp(JavaThread::current());
+      ThreadBlockInVM sp(thread->as_Java_thread());
       SpinPause();
     }
   }
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp
index d50353eb455..2dd5f161d1d 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp
@@ -35,6 +35,7 @@
 #include "memory/universe.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp
index 39d7d2a9056..39470c1af2f 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.cpp
@@ -24,9 +24,7 @@
 
 #include "precompiled.hpp"
 
-#include "classfile/classLoaderDataGraph.hpp"
-#include "classfile/stringTable.hpp"
-#include "code/codeCache.hpp"
+#include "classfile/classLoaderData.hpp"
 #include "code/nmethod.hpp"
 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
@@ -34,7 +32,6 @@
 #include "gc/shenandoah/shenandoahHeap.inline.hpp"
 #include "gc/shenandoah/shenandoahPhaseTimings.hpp"
 #include "gc/shenandoah/shenandoahStringDedup.hpp"
-#include "gc/shenandoah/shenandoahVMOperations.hpp"
 #include "memory/iterator.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/thread.hpp"
@@ -209,7 +206,6 @@ void ShenandoahRootScanner::roots_do(uint worker_id, OopClosure* oops, CLDClosur
           "Expect class unloading when Shenandoah cycle is running");
   assert(clds != NULL, "Only possible with CLD closure");
 
-  AlwaysTrueClosure always_true;
   ShenandoahParallelOopsDoThreadClosure tc_cl(oops, code, tc);
 
   ResourceMark rm;
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp
index 592652440a3..883e8229961 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahRootProcessor.inline.hpp
@@ -26,8 +26,6 @@
 #define SHARE_GC_SHENANDOAH_SHENANDOAHROOTPROCESSOR_INLINE_HPP
 
 #include "classfile/classLoaderDataGraph.hpp"
-#include "classfile/stringTable.hpp"
-#include "classfile/systemDictionary.hpp"
 #include "gc/shared/oopStorageSetParState.inline.hpp"
 #include "gc/shenandoah/shenandoahClosures.inline.hpp"
 #include "gc/shenandoah/shenandoahConcurrentRoots.hpp"
@@ -37,7 +35,6 @@
 #include "gc/shenandoah/shenandoahUtils.hpp"
 #include "gc/shenandoah/heuristics/shenandoahHeuristics.hpp"
 #include "memory/resourceArea.hpp"
-#include "prims/resolvedMethodTable.hpp"
 #include "runtime/safepoint.hpp"
 
 template <bool CONCURRENT>
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp b/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp
index c62407d47fd..b9e47394200 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.cpp
@@ -50,7 +50,7 @@ ShenandoahStrDedupQueue::ShenandoahStrDedupQueue() :
 
 ShenandoahStrDedupQueue::~ShenandoahStrDedupQueue() {
   MonitorLocker ml(StringDedupQueue_lock, Mutex::_no_safepoint_check_flag);
-  for (size_t index = 0; index < num_queues(); index ++) {
+  for (size_t index = 0; index < num_queues_nv(); index ++) {
     release_buffers(queue_at(index));
   }
 
diff --git a/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.hpp b/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.hpp
index ca373f85c0a..1aa6d91971e 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoahStrDedupQueue.hpp
@@ -99,9 +99,11 @@ class ShenandoahStrDedupQueue : public StringDedupQueue {
   void verify_impl();
 
 protected:
-  size_t num_queues() const { return (_num_producer_queue + 2); }
+  size_t num_queues() const { return num_queues_nv(); }
 
 private:
+  inline size_t num_queues_nv() const { return (_num_producer_queue + 2); }
+
   ShenandoahQueueBuffer* new_buffer();
 
   void release_buffers(ShenandoahQueueBuffer* list);
@@ -111,8 +113,6 @@ class ShenandoahStrDedupQueue : public StringDedupQueue {
   bool pop_candidate(oop& obj);
 
   void set_producer_buffer(ShenandoahQueueBuffer* buf, size_t queue_id);
-
-  void verify(ShenandoahQueueBuffer* head);
 };
 
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHSTRDEDUPQUEUE_HPP
diff --git a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp
index 31d2c5382b1..98aa933e01c 100644
--- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp
+++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp
@@ -30,33 +30,27 @@
                             develop_pd,                                     \
                             product,                                        \
                             product_pd,                                     \
-                            diagnostic,                                     \
-                            diagnostic_pd,                                  \
-                            experimental,                                   \
                             notproduct,                                     \
-                            manageable,                                     \
-                            product_rw,                                     \
-                            lp64_product,                                   \
                             range,                                          \
                             constraint)                                     \
                                                                             \
-  experimental(size_t, ShenandoahRegionSize, 0,                             \
+  product(size_t, ShenandoahRegionSize, 0, EXPERIMENTAL,                    \
           "Static heap region size. Set zero to enable automatic sizing.")  \
                                                                             \
-  experimental(size_t, ShenandoahTargetNumRegions, 2048,                    \
+  product(size_t, ShenandoahTargetNumRegions, 2048, EXPERIMENTAL,           \
           "With automatic region sizing, this is the approximate number "   \
           "of regions that would be used, within min/max region size "      \
           "limits.")                                                        \
                                                                             \
-  experimental(size_t, ShenandoahMinRegionSize, 256 * K,                    \
+  product(size_t, ShenandoahMinRegionSize, 256 * K, EXPERIMENTAL,           \
           "With automatic region sizing, the regions would be at least "    \
           "this large.")                                                    \
                                                                             \
-  experimental(size_t, ShenandoahMaxRegionSize, 32 * M,                     \
+  product(size_t, ShenandoahMaxRegionSize, 32 * M, EXPERIMENTAL,            \
           "With automatic region sizing, the regions would be at most "     \
           "this large.")                                                    \
                                                                             \
-  experimental(intx, ShenandoahHumongousThreshold, 100,                     \
+  product(intx, ShenandoahHumongousThreshold, 100, EXPERIMENTAL,            \
           "Humongous objects are allocated in separate regions. "           \
           "This setting defines how large the object should be to be "      \
           "deemed humongous. Value is in  percents of heap region size. "   \
@@ -82,19 +76,19 @@
           " compact - run GC more frequently and with deeper targets to "   \
           "free up more memory.")                                           \
                                                                             \
-  experimental(uintx, ShenandoahRefProcFrequency, 5,                        \
+  product(uintx, ShenandoahRefProcFrequency, 5, EXPERIMENTAL,               \
           "Process process weak (soft, phantom, finalizers) references "    \
           "every Nth cycle. Normally affects concurrent GC cycles only, "   \
           "as degenerated and full GCs would try to process references "    \
           "regardless. Set to zero to disable reference processing "        \
           "completely.")                                                    \
                                                                             \
-  experimental(uintx, ShenandoahUnloadClassesFrequency, 1,                  \
+  product(uintx, ShenandoahUnloadClassesFrequency, 1, EXPERIMENTAL,         \
           "Unload the classes every Nth cycle. Normally affects concurrent "\
           "GC cycles, as degenerated and full GCs would try to unload "     \
           "classes regardless. Set to zero to disable class unloading.")    \
                                                                             \
-  experimental(uintx, ShenandoahGarbageThreshold, 25,                       \
+  product(uintx, ShenandoahGarbageThreshold, 25, EXPERIMENTAL,              \
           "How much garbage a region has to contain before it would be "    \
           "taken for collection. This a guideline only, as GC heuristics "  \
           "may select the region for collection even if it has little "     \
@@ -102,63 +96,63 @@
           "collector accepts. In percents of heap region size.")            \
           range(0,100)                                                      \
                                                                             \
-  experimental(uintx, ShenandoahInitFreeThreshold, 70,                      \
+  product(uintx, ShenandoahInitFreeThreshold, 70, EXPERIMENTAL,             \
           "How much heap should be free before some heuristics trigger the "\
           "initial (learning) cycles. Affects cycle frequency on startup "  \
           "and after drastic state changes, e.g. after degenerated/full "   \
           "GC cycles. In percents of (soft) max heap size.")                \
           range(0,100)                                                      \
                                                                             \
-  experimental(uintx, ShenandoahMinFreeThreshold, 10,                       \
+  product(uintx, ShenandoahMinFreeThreshold, 10, EXPERIMENTAL,              \
           "How much heap should be free before most heuristics trigger the "\
           "collection, even without other triggers. Provides the safety "   \
           "margin for many heuristics. In percents of (soft) max heap size.")\
           range(0,100)                                                      \
                                                                             \
-  experimental(uintx, ShenandoahAllocationThreshold, 0,                     \
+  product(uintx, ShenandoahAllocationThreshold, 0, EXPERIMENTAL,            \
           "How many new allocations should happen since the last GC cycle " \
           "before some heuristics trigger the collection. In percents of "  \
           "(soft) max heap size. Set to zero to effectively disable.")      \
           range(0,100)                                                      \
                                                                             \
-  experimental(uintx, ShenandoahAllocSpikeFactor, 5,                        \
+  product(uintx, ShenandoahAllocSpikeFactor, 5, EXPERIMENTAL,               \
           "How much of heap should some heuristics reserve for absorbing "  \
           "the allocation spikes. Larger value wastes more memory in "      \
           "non-emergency cases, but provides more safety in emergency "     \
           "cases. In percents of (soft) max heap size.")                    \
           range(0,100)                                                      \
                                                                             \
-  experimental(uintx, ShenandoahLearningSteps, 5,                           \
+  product(uintx, ShenandoahLearningSteps, 5, EXPERIMENTAL,                  \
           "The number of cycles some heuristics take to collect in order "  \
           "to learn application and GC performance.")                       \
           range(0,100)                                                      \
                                                                             \
-  experimental(uintx, ShenandoahImmediateThreshold, 90,                     \
+  product(uintx, ShenandoahImmediateThreshold, 90, EXPERIMENTAL,            \
           "The cycle may shortcut when enough garbage can be reclaimed "    \
           "from the immediate garbage (completely garbage regions). "       \
           "In percents of total garbage found. Setting this threshold "     \
           "to 100 effectively disables the shortcut.")                      \
           range(0,100)                                                      \
                                                                             \
-  experimental(uintx, ShenandoahGuaranteedGCInterval, 5*60*1000,            \
+  product(uintx, ShenandoahGuaranteedGCInterval, 5*60*1000, EXPERIMENTAL,   \
           "Many heuristics would guarantee a concurrent GC cycle at "       \
           "least with this interval. This is useful when large idle "       \
           "intervals are present, where GC can run without stealing "       \
           "time from active application. Time is in milliseconds. "         \
           "Setting this to 0 disables the feature.")                        \
                                                                             \
-  experimental(bool, ShenandoahAlwaysClearSoftRefs, false,                  \
+  product(bool, ShenandoahAlwaysClearSoftRefs, false, EXPERIMENTAL,         \
           "Unconditionally clear soft references, instead of using any "    \
           "other cleanup policy. This minimizes footprint at expense of"    \
           "more soft reference churn in applications.")                     \
                                                                             \
-  experimental(bool, ShenandoahUncommit, true,                              \
+  product(bool, ShenandoahUncommit, true, EXPERIMENTAL,                     \
           "Allow to uncommit memory under unused regions and metadata. "    \
           "This optimizes footprint at expense of allocation latency in "   \
           "regions that require committing back. Uncommits would be "       \
           "disabled by some heuristics, or with static heap size.")         \
                                                                             \
-  experimental(uintx, ShenandoahUncommitDelay, 5*60*1000,                   \
+  product(uintx, ShenandoahUncommitDelay, 5*60*1000, EXPERIMENTAL,          \
           "Uncommit memory for regions that were not used for more than "   \
           "this time. First use after that would incur allocation stalls. " \
           "Actively used regions would never be uncommitted, because they " \
@@ -166,37 +160,37 @@
           "milliseconds. Setting this delay to 0 effectively uncommits "    \
           "regions almost immediately after they become unused.")           \
                                                                             \
-  experimental(bool, ShenandoahRegionSampling, false,                       \
+  product(bool, ShenandoahRegionSampling, false, EXPERIMENTAL,              \
           "Provide heap region sampling data via jvmstat.")                 \
                                                                             \
-  experimental(int, ShenandoahRegionSamplingRate, 40,                       \
+  product(int, ShenandoahRegionSamplingRate, 40, EXPERIMENTAL,              \
           "Sampling rate for heap region sampling. In milliseconds between "\
           "the samples. Higher values provide more fidelity, at expense "   \
           "of more sampling overhead.")                                     \
                                                                             \
-  experimental(uintx, ShenandoahControlIntervalMin, 1,                      \
+  product(uintx, ShenandoahControlIntervalMin, 1, EXPERIMENTAL,             \
           "The minimum sleep interval for the control loop that drives "    \
           "the cycles. Lower values would increase GC responsiveness "      \
           "to changing heap conditions, at the expense of higher perf "     \
           "overhead. Time is in milliseconds.")                             \
                                                                             \
-  experimental(uintx, ShenandoahControlIntervalMax, 10,                     \
+  product(uintx, ShenandoahControlIntervalMax, 10, EXPERIMENTAL,            \
           "The maximum sleep interval for control loop that drives "        \
           "the cycles. Lower values would increase GC responsiveness "      \
           "to changing heap conditions, at the expense of higher perf "     \
           "overhead. Time is in milliseconds.")                             \
                                                                             \
-  experimental(uintx, ShenandoahControlIntervalAdjustPeriod, 1000,          \
+  product(uintx, ShenandoahControlIntervalAdjustPeriod, 1000, EXPERIMENTAL, \
           "The time period for one step in control loop interval "          \
           "adjustment. Lower values make adjustments faster, at the "       \
           "expense of higher perf overhead. Time is in milliseconds.")      \
                                                                             \
-  diagnostic(bool, ShenandoahVerify, false,                                 \
+  product(bool, ShenandoahVerify, false, DIAGNOSTIC,                        \
           "Enable internal verification. This would catch many GC bugs, "   \
           "but it would also stall the collector during the verification, " \
           "which prolongs the pauses and might hide other bugs.")           \
                                                                             \
-  diagnostic(intx, ShenandoahVerifyLevel, 4,                                \
+  product(intx, ShenandoahVerifyLevel, 4, DIAGNOSTIC,                       \
           "Verification level, higher levels check more, taking more time. "\
           "Accepted values are:"                                            \
           " 0 = basic heap checks; "                                        \
@@ -205,34 +199,34 @@
           " 3 = previous level, plus all reachable objects; "               \
           " 4 = previous level, plus all marked objects")                   \
                                                                             \
-  diagnostic(bool, ShenandoahElasticTLAB, true,                             \
+  product(bool, ShenandoahElasticTLAB, true, DIAGNOSTIC,                    \
           "Use Elastic TLABs with Shenandoah")                              \
                                                                             \
-  experimental(uintx, ShenandoahEvacReserve, 5,                             \
+  product(uintx, ShenandoahEvacReserve, 5, EXPERIMENTAL,                    \
           "How much of heap to reserve for evacuations. Larger values make "\
           "GC evacuate more live objects on every cycle, while leaving "    \
           "less headroom for application to allocate in. In percents of "   \
           "total heap size.")                                               \
           range(1,100)                                                      \
                                                                             \
-  experimental(double, ShenandoahEvacWaste, 1.2,                            \
+  product(double, ShenandoahEvacWaste, 1.2, EXPERIMENTAL,                   \
           "How much waste evacuations produce within the reserved space. "  \
           "Larger values make evacuations more resilient against "          \
           "evacuation conflicts, at expense of evacuating less on each "    \
           "GC cycle.")                                                      \
           range(1.0,100.0)                                                  \
                                                                             \
-  experimental(bool, ShenandoahEvacReserveOverflow, true,                   \
+  product(bool, ShenandoahEvacReserveOverflow, true, EXPERIMENTAL,          \
           "Allow evacuations to overflow the reserved space. Enabling it "  \
           "will make evacuations more resilient when evacuation "           \
           "reserve/waste is incorrect, at the risk that application "       \
           "runs out of memory too early.")                                  \
                                                                             \
-  experimental(bool, ShenandoahPacing, true,                                \
+  product(bool, ShenandoahPacing, true, EXPERIMENTAL,                       \
           "Pace application allocations to give GC chance to start "        \
           "and complete before allocation failure is reached.")             \
                                                                             \
-  experimental(uintx, ShenandoahPacingMaxDelay, 10,                         \
+  product(uintx, ShenandoahPacingMaxDelay, 10, EXPERIMENTAL,                \
           "Max delay for pacing application allocations. Larger values "    \
           "provide more resilience against out of memory, at expense at "   \
           "hiding the GC latencies in the allocation path. Time is in "     \
@@ -240,7 +234,7 @@
           "GC effectively stall the threads indefinitely instead of going " \
           "to degenerated or Full GC.")                                     \
                                                                             \
-  experimental(uintx, ShenandoahPacingIdleSlack, 2,                         \
+  product(uintx, ShenandoahPacingIdleSlack, 2, EXPERIMENTAL,                \
           "How much of heap counted as non-taxable allocations during idle "\
           "phases. Larger value makes the pacing milder when collector is " \
           "idle, requiring less rendezvous with control thread. Lower "     \
@@ -248,101 +242,101 @@
           "allocs. In percent of total heap size.")                         \
           range(0, 100)                                                     \
                                                                             \
-  experimental(uintx, ShenandoahPacingCycleSlack, 10,                       \
+  product(uintx, ShenandoahPacingCycleSlack, 10, EXPERIMENTAL,              \
           "How much of free space to take as non-taxable allocations "      \
           "the GC cycle. Larger value makes the pacing milder at the "      \
           "beginning of the GC cycle. Lower value makes the pacing less "   \
           "uniform during the cycle. In percent of free space.")            \
           range(0, 100)                                                     \
                                                                             \
-  experimental(double, ShenandoahPacingSurcharge, 1.1,                      \
+  product(double, ShenandoahPacingSurcharge, 1.1, EXPERIMENTAL,             \
           "Additional pacing tax surcharge to help unclutter the heap. "    \
           "Larger values makes the pacing more aggressive. Lower values "   \
           "risk GC cycles finish with less memory than were available at "  \
           "the beginning of it.")                                           \
           range(1.0, 100.0)                                                 \
                                                                             \
-  experimental(uintx, ShenandoahCriticalFreeThreshold, 1,                   \
+  product(uintx, ShenandoahCriticalFreeThreshold, 1, EXPERIMENTAL,          \
           "How much of the heap needs to be free after recovery cycles, "   \
           "either Degenerated or Full GC to be claimed successful. If this "\
           "much space is not available, next recovery step would be "       \
           "triggered.")                                                     \
           range(0, 100)                                                     \
                                                                             \
-  diagnostic(bool, ShenandoahDegeneratedGC, true,                           \
+  product(bool, ShenandoahDegeneratedGC, true, DIAGNOSTIC,                  \
           "Enable Degenerated GC as the graceful degradation step. "        \
           "Disabling this option leads to degradation to Full GC instead. " \
           "When running in passive mode, this can be toggled to measure "   \
           "either Degenerated GC or Full GC costs.")                        \
                                                                             \
-  experimental(uintx, ShenandoahFullGCThreshold, 3,                         \
+  product(uintx, ShenandoahFullGCThreshold, 3, EXPERIMENTAL,                \
           "How many back-to-back Degenerated GCs should happen before "     \
           "going to a Full GC.")                                            \
                                                                             \
-  experimental(bool, ShenandoahImplicitGCInvokesConcurrent, false,          \
+  product(bool, ShenandoahImplicitGCInvokesConcurrent, false, EXPERIMENTAL, \
           "Should internally-caused GC requests invoke concurrent cycles, " \
           "should they do the stop-the-world (Degenerated / Full GC)? "     \
           "Many heuristics automatically enable this. This option is "      \
           "similar to global ExplicitGCInvokesConcurrent.")                 \
                                                                             \
-  diagnostic(bool, ShenandoahHumongousMoves, true,                          \
+  product(bool, ShenandoahHumongousMoves, true, DIAGNOSTIC,                 \
           "Allow moving humongous regions. This makes GC more resistant "   \
           "to external fragmentation that may otherwise fail other "        \
           "humongous allocations, at the expense of higher GC copying "     \
           "costs. Currently affects stop-the-world (Full) cycle only.")     \
                                                                             \
-  diagnostic(bool, ShenandoahOOMDuringEvacALot, false,                      \
+  product(bool, ShenandoahOOMDuringEvacALot, false, DIAGNOSTIC,             \
           "Testing: simulate OOM during evacuation.")                       \
                                                                             \
-  diagnostic(bool, ShenandoahAllocFailureALot, false,                       \
+  product(bool, ShenandoahAllocFailureALot, false, DIAGNOSTIC,              \
           "Testing: make lots of artificial allocation failures.")          \
                                                                             \
-  experimental(intx, ShenandoahMarkScanPrefetch, 32,                        \
+  product(intx, ShenandoahMarkScanPrefetch, 32, EXPERIMENTAL,               \
           "How many objects to prefetch ahead when traversing mark bitmaps."\
           "Set to 0 to disable prefetching.")                               \
           range(0, 256)                                                     \
                                                                             \
-  experimental(uintx, ShenandoahMarkLoopStride, 1000,                       \
+  product(uintx, ShenandoahMarkLoopStride, 1000, EXPERIMENTAL,              \
           "How many items to process during one marking iteration before "  \
           "checking for cancellation, yielding, etc. Larger values improve "\
           "marking performance at expense of responsiveness.")              \
                                                                             \
-  experimental(uintx, ShenandoahParallelRegionStride, 1024,                 \
+  product(uintx, ShenandoahParallelRegionStride, 1024, EXPERIMENTAL,        \
           "How many regions to process at once during parallel region "     \
           "iteration. Affects heaps with lots of regions.")                 \
                                                                             \
-  experimental(size_t, ShenandoahSATBBufferSize, 1 * K,                     \
+  product(size_t, ShenandoahSATBBufferSize, 1 * K, EXPERIMENTAL,            \
           "Number of entries in an SATB log buffer.")                       \
           range(1, max_uintx)                                               \
                                                                             \
-  experimental(uintx, ShenandoahSATBBufferFlushInterval, 100,               \
+  product(uintx, ShenandoahSATBBufferFlushInterval, 100, EXPERIMENTAL,      \
           "Forcefully flush non-empty SATB buffers at this interval. "      \
           "Time is in milliseconds.")                                       \
                                                                             \
-  diagnostic(bool, ShenandoahPreclean, true,                                \
+  product(bool, ShenandoahPreclean, true, DIAGNOSTIC,                       \
           "Do concurrent preclean phase before final mark: process "        \
           "definitely alive references to avoid dealing with them during "  \
           "pause.")                                                         \
                                                                             \
-  experimental(bool, ShenandoahSuspendibleWorkers, false,                   \
+  product(bool, ShenandoahSuspendibleWorkers, false, EXPERIMENTAL,          \
           "Suspend concurrent GC worker threads at safepoints")             \
                                                                             \
-  diagnostic(bool, ShenandoahSATBBarrier, true,                             \
+  product(bool, ShenandoahSATBBarrier, true, DIAGNOSTIC,                    \
           "Turn on/off SATB barriers in Shenandoah")                        \
                                                                             \
-  diagnostic(bool, ShenandoahStoreValEnqueueBarrier, false,                 \
+  product(bool, ShenandoahStoreValEnqueueBarrier, false, DIAGNOSTIC,        \
           "Turn on/off enqueuing of oops for storeval barriers")            \
                                                                             \
-  diagnostic(bool, ShenandoahCASBarrier, true,                              \
+  product(bool, ShenandoahCASBarrier, true, DIAGNOSTIC,                     \
           "Turn on/off CAS barriers in Shenandoah")                         \
                                                                             \
-  diagnostic(bool, ShenandoahCloneBarrier, true,                            \
+  product(bool, ShenandoahCloneBarrier, true, DIAGNOSTIC,                   \
           "Turn on/off clone barriers in Shenandoah")                       \
                                                                             \
-  diagnostic(bool, ShenandoahLoadRefBarrier, true,                          \
+  product(bool, ShenandoahLoadRefBarrier, true, DIAGNOSTIC,                 \
           "Turn on/off load-reference barriers in Shenandoah")              \
                                                                             \
-  diagnostic(uintx, ShenandoahCodeRootsStyle, 2,                            \
+  product(uintx, ShenandoahCodeRootsStyle, 2, DIAGNOSTIC,                   \
           "Use this style to scan the code cache roots:"                    \
           " 0 - sequential iterator;"                                       \
           " 1 - parallel iterator;"                                         \
@@ -351,12 +345,13 @@
   develop(bool, ShenandoahVerifyOptoBarriers, false,                        \
           "Verify no missing barriers in C2.")                              \
                                                                             \
-  diagnostic(bool, ShenandoahLoopOptsAfterExpansion, true,                  \
+  product(bool, ShenandoahLoopOptsAfterExpansion, true, DIAGNOSTIC,         \
           "Attempt more loop opts after barrier expansion.")                \
                                                                             \
-  diagnostic(bool, ShenandoahSelfFixing, true,                              \
+  product(bool, ShenandoahSelfFixing, true, DIAGNOSTIC,                     \
           "Fix references with load reference barrier. Disabling this "     \
-          "might degrade performance.")                                     \
+          "might degrade performance.")
 
+// end of GC_SHENANDOAH_FLAGS
 
 #endif // SHARE_GC_SHENANDOAH_SHENANDOAH_GLOBALS_HPP
diff --git a/src/hotspot/share/gc/z/zForwardingEntry.hpp b/src/hotspot/share/gc/z/zForwardingEntry.hpp
index a6db411c314..2aa538f0ec2 100644
--- a/src/hotspot/share/gc/z/zForwardingEntry.hpp
+++ b/src/hotspot/share/gc/z/zForwardingEntry.hpp
@@ -27,6 +27,7 @@
 #include "gc/z/zBitField.hpp"
 #include "memory/allocation.hpp"
 #include "metaprogramming/primitiveConversions.hpp"
+#include <type_traits>
 
 //
 // Forwarding entry layout
@@ -46,7 +47,7 @@
 //
 
 class ZForwardingEntry {
-  friend class PrimitiveConversions;
+  friend struct PrimitiveConversions::Translate<ZForwardingEntry>;
 
 private:
   typedef ZBitField<uint64_t, bool,   0,   1> field_populated;
@@ -79,7 +80,7 @@ class ZForwardingEntry {
 
 // Needed to allow atomic operations on ZForwardingEntry
 template <>
-struct PrimitiveConversions::Translate<ZForwardingEntry> : public TrueType {
+struct PrimitiveConversions::Translate<ZForwardingEntry> : public std::true_type {
   typedef ZForwardingEntry Value;
   typedef uint64_t         Decayed;
 
diff --git a/src/hotspot/share/gc/z/zFuture.inline.hpp b/src/hotspot/share/gc/z/zFuture.inline.hpp
index 26d58b69d49..1919438d06d 100644
--- a/src/hotspot/share/gc/z/zFuture.inline.hpp
+++ b/src/hotspot/share/gc/z/zFuture.inline.hpp
@@ -46,7 +46,7 @@ inline T ZFuture<T>::get() {
   // Wait for notification
   Thread* const thread = Thread::current();
   if (thread->is_Java_thread()) {
-    _sema.wait_with_safepoint_check((JavaThread*)thread);
+    _sema.wait_with_safepoint_check(thread->as_Java_thread());
   } else {
     _sema.wait();
   }
diff --git a/src/hotspot/share/gc/z/zGlobals.hpp b/src/hotspot/share/gc/z/zGlobals.hpp
index 138b9486f03..690227e3a8d 100644
--- a/src/hotspot/share/gc/z/zGlobals.hpp
+++ b/src/hotspot/share/gc/z/zGlobals.hpp
@@ -149,6 +149,6 @@ const size_t      ZMarkProactiveFlushMax        = 10;
 const size_t      ZMarkTerminateFlushMax        = 3;
 
 // Try complete mark timeout
-const uint64_t    ZMarkCompleteTimeout          = 1; // ms
+const uint64_t    ZMarkCompleteTimeout          = 1000; // us
 
 #endif // SHARE_GC_Z_ZGLOBALS_HPP
diff --git a/src/hotspot/share/gc/z/zMark.cpp b/src/hotspot/share/gc/z/zMark.cpp
index 8ea20b97fa4..ed409b58e87 100644
--- a/src/hotspot/share/gc/z/zMark.cpp
+++ b/src/hotspot/share/gc/z/zMark.cpp
@@ -563,9 +563,9 @@ class ZMarkTimeout : public StackObj {
   bool           _expired;
 
 public:
-  ZMarkTimeout(uint64_t timeout_in_millis) :
+  ZMarkTimeout(uint64_t timeout_in_micros) :
       _start(Ticks::now()),
-      _timeout(_start.value() + TimeHelper::millis_to_counter(timeout_in_millis)),
+      _timeout(_start.value() + TimeHelper::micros_to_counter(timeout_in_micros)),
       _check_interval(200),
       _check_at(_check_interval),
       _check_count(0),
@@ -591,9 +591,9 @@ class ZMarkTimeout : public StackObj {
   }
 };
 
-void ZMark::work_with_timeout(ZMarkCache* cache, ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks, uint64_t timeout_in_millis) {
+void ZMark::work_with_timeout(ZMarkCache* cache, ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks, uint64_t timeout_in_micros) {
   ZStatTimer timer(ZSubPhaseMarkTryComplete);
-  ZMarkTimeout timeout(timeout_in_millis);
+  ZMarkTimeout timeout(timeout_in_micros);
 
   for (;;) {
     if (!drain_and_flush(stripe, stacks, cache, &timeout)) {
@@ -611,15 +611,15 @@ void ZMark::work_with_timeout(ZMarkCache* cache, ZMarkStripe* stripe, ZMarkThrea
   }
 }
 
-void ZMark::work(uint64_t timeout_in_millis) {
+void ZMark::work(uint64_t timeout_in_micros) {
   ZMarkCache cache(_stripes.nstripes());
   ZMarkStripe* const stripe = _stripes.stripe_for_worker(_nworkers, ZThread::worker_id());
   ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(Thread::current());
 
-  if (timeout_in_millis == 0) {
+  if (timeout_in_micros == 0) {
     work_without_timeout(&cache, stripe, stacks);
   } else {
-    work_with_timeout(&cache, stripe, stacks, timeout_in_millis);
+    work_with_timeout(&cache, stripe, stacks, timeout_in_micros);
   }
 
   // Make sure stacks have been flushed
@@ -668,13 +668,13 @@ class ZMarkConcurrentRootsTask : public ZTask {
 class ZMarkTask : public ZTask {
 private:
   ZMark* const   _mark;
-  const uint64_t _timeout_in_millis;
+  const uint64_t _timeout_in_micros;
 
 public:
-  ZMarkTask(ZMark* mark, uint64_t timeout_in_millis = 0) :
+  ZMarkTask(ZMark* mark, uint64_t timeout_in_micros = 0) :
       ZTask("ZMarkTask"),
       _mark(mark),
-      _timeout_in_millis(timeout_in_millis) {
+      _timeout_in_micros(timeout_in_micros) {
     _mark->prepare_work();
   }
 
@@ -683,7 +683,7 @@ class ZMarkTask : public ZTask {
   }
 
   virtual void work() {
-    _mark->work(_timeout_in_millis);
+    _mark->work(_timeout_in_micros);
   }
 };
 
diff --git a/src/hotspot/share/gc/z/zObjArrayAllocator.cpp b/src/hotspot/share/gc/z/zObjArrayAllocator.cpp
index 9250623740f..32c16fd959e 100644
--- a/src/hotspot/share/gc/z/zObjArrayAllocator.cpp
+++ b/src/hotspot/share/gc/z/zObjArrayAllocator.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,7 +55,7 @@ oop ZObjArrayAllocator::finish(HeapWord* mem) const {
 
     if (remaining > 0) {
       // Safepoint
-      ThreadBlockInVM tbivm((JavaThread*)_thread);
+      ThreadBlockInVM tbivm(_thread->as_Java_thread());
     }
   }
 
diff --git a/src/hotspot/share/gc/z/z_globals.hpp b/src/hotspot/share/gc/z/z_globals.hpp
index b89a3c0ef13..5d921def086 100644
--- a/src/hotspot/share/gc/z/z_globals.hpp
+++ b/src/hotspot/share/gc/z/z_globals.hpp
@@ -28,13 +28,7 @@
                    develop_pd,                                              \
                    product,                                                 \
                    product_pd,                                              \
-                   diagnostic,                                              \
-                   diagnostic_pd,                                           \
-                   experimental,                                            \
                    notproduct,                                              \
-                   manageable,                                              \
-                   product_rw,                                              \
-                   lp64_product,                                            \
                    range,                                                   \
                    constraint)                                              \
                                                                             \
@@ -61,23 +55,25 @@
           "Uncommit memory if it has been unused for the specified "        \
           "amount of time (in seconds)")                                    \
                                                                             \
-  diagnostic(uint, ZStatisticsInterval, 10,                                 \
+  product(uint, ZStatisticsInterval, 10, DIAGNOSTIC,                        \
           "Time between statistics print outs (in seconds)")                \
           range(1, (uint)-1)                                                \
                                                                             \
-  diagnostic(bool, ZVerifyViews, false,                                     \
+  product(bool, ZVerifyViews, false, DIAGNOSTIC,                            \
           "Verify heap view accesses")                                      \
                                                                             \
-  diagnostic(bool, ZVerifyRoots, trueInDebug,                               \
+  product(bool, ZVerifyRoots, trueInDebug, DIAGNOSTIC,                      \
           "Verify roots")                                                   \
                                                                             \
-  diagnostic(bool, ZVerifyObjects, false,                                   \
+  product(bool, ZVerifyObjects, false, DIAGNOSTIC,                          \
           "Verify objects")                                                 \
                                                                             \
-  diagnostic(bool, ZVerifyMarking, trueInDebug,                             \
+  product(bool, ZVerifyMarking, trueInDebug, DIAGNOSTIC,                    \
           "Verify marking stacks")                                          \
                                                                             \
-  diagnostic(bool, ZVerifyForwarding, false,                                \
+  product(bool, ZVerifyForwarding, false, DIAGNOSTIC,                       \
           "Verify forwarding tables")
 
+// end of GC_Z_FLAGS
+
 #endif // SHARE_GC_Z_Z_GLOBALS_HPP
diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h
index a4b97139e58..15b064dcb7d 100644
--- a/src/hotspot/share/include/jvm.h
+++ b/src/hotspot/share/include/jvm.h
@@ -490,6 +490,14 @@ JVM_AddModuleExportsToAll(JNIEnv *env, jobject from_module, jstring package);
 JNIEXPORT void JNICALL
 JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject source_module);
 
+/*
+ * Define all modules that have been stored in the CDS archived heap.
+ *  platform_loader: the built-in platform class loader
+ *  system_loader:   the built-in system class loader
+ */
+JNIEXPORT void JNICALL
+JVM_DefineArchivedModules(JNIEnv *env, jobject platform_loader, jobject system_loader);
+
 /*
  * Reflection support functions
  */
diff --git a/src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp b/src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp
index 100d9deb371..4dc9fba7ae5 100644
--- a/src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp
+++ b/src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp
@@ -68,12 +68,6 @@ static bool update_class_file_load_hook_event(jvmtiEventMode mode) {
   return set_event_notification_mode(mode, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
 }
 
-static JavaThread* current_java_thread() {
-  Thread* this_thread = Thread::current();
-  assert(this_thread != NULL && this_thread->is_Java_thread(), "invariant");
-  return static_cast<JavaThread*>(this_thread);
-}
-
 // jvmti event callbacks require C linkage
 extern "C" void JNICALL jfr_on_class_file_load_hook(jvmtiEnv *jvmti_env,
                                                     JNIEnv* jni_env,
@@ -104,7 +98,7 @@ extern "C" void JNICALL jfr_on_class_file_load_hook(jvmtiEnv *jvmti_env,
 static jclass* create_classes_array(jint classes_count, TRAPS) {
   assert(classes_count > 0, "invariant");
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
-  ThreadInVMfromNative tvmfn((JavaThread*)THREAD);
+  ThreadInVMfromNative tvmfn(THREAD->as_Java_thread());
   jclass* const classes = NEW_RESOURCE_ARRAY_IN_THREAD_RETURN_NULL(THREAD, jclass, classes_count);
   if (NULL == classes) {
     char error_buffer[ERROR_MSG_BUFFER_SIZE];
@@ -121,7 +115,7 @@ static jclass* create_classes_array(jint classes_count, TRAPS) {
 static void log_and_throw(jvmtiError error, TRAPS) {
   if (!HAS_PENDING_EXCEPTION) {
     DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
-    ThreadInVMfromNative tvmfn((JavaThread*)THREAD);
+    ThreadInVMfromNative tvmfn(THREAD->as_Java_thread());
     const char base_error_msg[] = "JfrJvmtiAgent::retransformClasses failed: ";
     size_t length = sizeof base_error_msg; // includes terminating null
     const char* const jvmti_error_name = JvmtiUtil::error_name(error);
@@ -142,7 +136,7 @@ static void check_exception_and_log(JNIEnv* env, TRAPS) {
   if (env->ExceptionOccurred()) {
     // array index out of bound
     DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
-    ThreadInVMfromNative tvmfn((JavaThread*)THREAD);
+    ThreadInVMfromNative tvmfn(THREAD->as_Java_thread());
     log_error(jfr, system)("GetObjectArrayElement threw an exception");
     return;
   }
@@ -171,7 +165,7 @@ void JfrJvmtiAgent::retransform_classes(JNIEnv* env, jobjectArray classes_array,
   }
   {
     // inspecting the oop/klass requires a thread transition
-    ThreadInVMfromNative transition((JavaThread*)THREAD);
+    ThreadInVMfromNative transition(THREAD->as_Java_thread());
     for (jint i = 0; i < classes_count; ++i) {
       jclass clz = classes[i];
       if (!JdkJfrEvent::is_a(clz)) {
@@ -233,7 +227,7 @@ static bool unregister_callbacks(JavaThread* jt) {
 JfrJvmtiAgent::JfrJvmtiAgent() {}
 
 JfrJvmtiAgent::~JfrJvmtiAgent() {
-  JavaThread* jt = current_java_thread();
+  JavaThread* jt = JavaThread::current();
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(jt));
   if (jfr_jvmti_env != NULL) {
     ThreadToNativeFromVM transition(jt);
@@ -273,7 +267,7 @@ static void log_and_throw_illegal_state_exception(TRAPS) {
 
 bool JfrJvmtiAgent::create() {
   assert(agent == NULL, "invariant");
-  JavaThread* const jt = current_java_thread();
+  JavaThread* const jt = JavaThread::current();
   if (!is_valid_jvmti_phase()) {
     log_and_throw_illegal_state_exception(jt);
     return false;
diff --git a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp
index 423f0a0be1b..c7c38378b1f 100644
--- a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp
+++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp
@@ -51,20 +51,17 @@
 #ifdef ASSERT
 void JfrJavaSupport::check_java_thread_in_vm(Thread* t) {
   assert(t != NULL, "invariant");
-  assert(t->is_Java_thread(), "invariant");
-  assert(((JavaThread*)t)->thread_state() == _thread_in_vm, "invariant");
+  assert(t->as_Java_thread()->thread_state() == _thread_in_vm, "invariant");
 }
 
 void JfrJavaSupport::check_java_thread_in_native(Thread* t) {
   assert(t != NULL, "invariant");
-  assert(t->is_Java_thread(), "invariant");
-  assert(((JavaThread*)t)->thread_state() == _thread_in_native, "invariant");
+  assert(t->as_Java_thread()->thread_state() == _thread_in_native, "invariant");
 }
 
 static void check_new_unstarted_java_thread(Thread* t) {
   assert(t != NULL, "invariant");
-  assert(t->is_Java_thread(), "invariant");
-  assert(((JavaThread*)t)->thread_state() == _thread_new, "invariant");
+  assert(t->as_Java_thread()->thread_state() == _thread_new, "invariant");
 }
 #endif
 
@@ -836,7 +833,7 @@ void JfrJavaSupport::on_thread_start(Thread* t) {
   }
   DEBUG_ONLY(check_new_unstarted_java_thread(t);)
   HandleMark hm(t);
-  if (check_exclusion_state_on_thread_start((JavaThread*)t)) {
+  if (check_exclusion_state_on_thread_start(t->as_Java_thread())) {
     JfrThreadLocal::exclude(t);
   }
 }
diff --git a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp
index 0faf97ac7cf..479fca01324 100644
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleCheckpoint.cpp
@@ -261,10 +261,10 @@ static void install_stack_traces(const ObjectSampler* sampler, JfrStackTraceRepo
 void ObjectSampleCheckpoint::on_rotation(const ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repo) {
   assert(sampler != NULL, "invariant");
   assert(LeakProfiler::is_running(), "invariant");
-  Thread* const thread = Thread::current();
+  JavaThread* const thread = JavaThread::current();
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(thread);)
   // can safepoint here
-  ThreadInVMfromNative transition((JavaThread*)thread);
+  ThreadInVMfromNative transition(thread);
   MutexLocker lock(ClassLoaderDataGraph_lock);
   // the lock is needed to ensure the unload lists do not grow in the middle of inspection.
   install_stack_traces(sampler, stack_trace_repo);
diff --git a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp
index d8d72a916da..5295b137ccf 100644
--- a/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp
+++ b/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp
@@ -179,7 +179,7 @@ TRACE_REQUEST_FUNC(CPULoad) {
   {
     // Can take some time on certain platforms, especially under heavy load.
     // Transition to native to avoid unnecessary stalls for pending safepoint synchronizations.
-    ThreadToNativeFromVM transition((JavaThread*)Thread::current());
+    ThreadToNativeFromVM transition(JavaThread::current());
     ret_val = JfrOSInterface::cpu_loads_process(&u, &s, &t);
   }
   if (ret_val == OS_ERR) {
@@ -259,7 +259,7 @@ TRACE_REQUEST_FUNC(ThreadContextSwitchRate) {
   {
     // Can take some time on certain platforms, especially under heavy load.
     // Transition to native to avoid unnecessary stalls for pending safepoint synchronizations.
-    ThreadToNativeFromVM transition((JavaThread*)Thread::current());
+    ThreadToNativeFromVM transition(JavaThread::current());
     ret_val = JfrOSInterface::context_switch_rate(&rate);
   }
   if (ret_val == OS_ERR) {
@@ -643,4 +643,3 @@ TRACE_REQUEST_FUNC(ShenandoahHeapRegionInformation) {
   }
 #endif
 }
-
diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp
index 602b10859a4..3d66f12e87d 100644
--- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp
+++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp
@@ -174,7 +174,7 @@ void OSThreadSampler::do_task(const os::SuspendedThreadTaskContext& context) {
 * using a signal handler / __try block. Don't take locks, rely on destructors or
 * leave memory (in case of signal / exception) in an inconsistent state. */
 void OSThreadSampler::protected_task(const os::SuspendedThreadTaskContext& context) {
-  JavaThread* jth = (JavaThread*)context.thread();
+  JavaThread* jth = context.thread()->as_Java_thread();
   // Skip sample if we signaled a thread that moved to other state
   if (!thread_state_in_java(jth)) {
     return;
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
index 3ba27e40386..a66241b1fcf 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp
@@ -387,7 +387,7 @@ size_t JfrCheckpointManager::write_static_type_set(Thread* thread) {
 size_t JfrCheckpointManager::write_threads(Thread* thread) {
   assert(thread != NULL, "invariant");
   // can safepoint here
-  ThreadInVMfromNative transition((JavaThread*)thread);
+  ThreadInVMfromNative transition(thread->as_Java_thread());
   ResetNoHandleMark rnhm;
   ResourceMark rm(thread);
   HandleMark hm(thread);
@@ -412,10 +412,10 @@ void JfrCheckpointManager::on_rotation() {
 
 void JfrCheckpointManager::clear_type_set() {
   assert(!JfrRecorder::is_recording(), "invariant");
-  Thread* t = Thread::current();
+  JavaThread* t = JavaThread::current();
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(t));
   // can safepoint here
-  ThreadInVMfromNative transition((JavaThread*)t);
+  ThreadInVMfromNative transition(t);
   ResetNoHandleMark rnhm;
   MutexLocker cld_lock(ClassLoaderDataGraph_lock);
   MutexLocker module_lock(Module_lock);
@@ -424,10 +424,10 @@ void JfrCheckpointManager::clear_type_set() {
 
 void JfrCheckpointManager::write_type_set() {
   {
-    Thread* const thread = Thread::current();
+    JavaThread* const thread = JavaThread::current();
     DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(thread));
     // can safepoint here
-    ThreadInVMfromNative transition((JavaThread*)thread);
+    ThreadInVMfromNative transition(thread);
     ResetNoHandleMark rnhm;
     MutexLocker cld_lock(thread, ClassLoaderDataGraph_lock);
     MutexLocker module_lock(thread, Module_lock);
@@ -467,7 +467,7 @@ size_t JfrCheckpointManager::flush_type_set() {
     Thread* const thread = Thread::current();
     if (thread->is_Java_thread()) {
       // can safepoint here
-      ThreadInVMfromNative transition((JavaThread*)thread);
+      ThreadInVMfromNative transition(thread->as_Java_thread());
       ResetNoHandleMark rnhm;
       elements = ::flush_type_set(thread);
     } else {
@@ -496,9 +496,8 @@ class JfrNotifyClosure : public ThreadClosure {
  public:
   void do_thread(Thread* thread) {
     assert(thread != NULL, "invariant");
-    assert(thread->is_Java_thread(), "invariant");
     assert_locked_or_safepoint(Threads_lock);
-    JfrJavaEventWriter::notify((JavaThread*)thread);
+    JfrJavaEventWriter::notify(thread->as_Java_thread());
   }
 };
 
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp b/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp
index 704e7fd6012..57407699e55 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrMetadataEvent.cpp
@@ -56,7 +56,7 @@ void JfrMetadataEvent::write(JfrChunkWriter& chunkwriter) {
   if (last_metadata_id == metadata_id && chunkwriter.has_metadata()) {
     return;
   }
-  JavaThread* const jt = (JavaThread*)Thread::current();
+  JavaThread* const jt = JavaThread::current();
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(jt));
   // can safepoint here
   ThreadInVMfromNative transition(jt);
@@ -76,8 +76,7 @@ void JfrMetadataEvent::write(JfrChunkWriter& chunkwriter) {
 }
 
 void JfrMetadataEvent::update(jbyteArray metadata) {
-  JavaThread* thread = (JavaThread*)Thread::current();
-  assert(thread->is_Java_thread(), "invariant");
+  JavaThread* thread = JavaThread::current();
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(thread));
   if (metadata_blob != NULL) {
     JfrJavaSupport::destroy_global_jni_handle(metadata_blob);
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp
index cff49b23c5b..8e747142f80 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrThreadState.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -89,8 +89,7 @@ traceid JfrThreadId::id(const Thread* t) {
   if (!t->is_Java_thread()) {
     return os_id(t);
   }
-  const JavaThread* const jt = (JavaThread*)t;
-  const oop thread_obj = jt->threadObj();
+  const oop thread_obj = t->as_Java_thread()->threadObj();
   return thread_obj != NULL ? java_lang_Thread::thread_id(thread_obj) : 0;
 }
 
@@ -108,8 +107,7 @@ traceid JfrThreadId::jfr_id(const Thread* t) {
 // caller needs ResourceMark
 const char* get_java_thread_name(const Thread* t) {
   assert(t != NULL, "invariant");
-  assert(t->is_Java_thread(), "invariant");
-  const JavaThread* const jt = ((JavaThread*)t);
+  const JavaThread* const jt = t->as_Java_thread();
   const char* name_str = "<no-name - thread name unresolved>";
   const oop thread_obj = jt->threadObj();
   if (thread_obj != NULL) {
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp
index 047ac8f5f7a..840d79d24ef 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/jfrType.cpp
@@ -98,7 +98,7 @@ void JfrCheckpointThreadClosure::do_thread(Thread* t) {
   if (t->is_Java_thread()) {
     _writer.write(name);
     _writer.write(JfrThreadId::id(t));
-    _writer.write(JfrThreadGroup::thread_group_id((JavaThread*)t, _curthread));
+    _writer.write(JfrThreadGroup::thread_group_id(t->as_Java_thread(), _curthread));
     return;
   }
   _writer.write((const char*)NULL); // java name
@@ -274,7 +274,7 @@ void JfrThreadConstant::serialize(JfrCheckpointWriter& writer) {
   if (_thread->is_Java_thread()) {
     writer.write(name);
     writer.write(JfrThreadId::id(_thread));
-    JavaThread* const jt = (JavaThread*)_thread;
+    JavaThread* const jt = _thread->as_Java_thread();
     const traceid thread_group_id = JfrThreadGroup::thread_group_id(jt, jt);
     writer.write(thread_group_id);
     JfrThreadGroup::serialize(&writer, thread_group_id);
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp
index 138a85ed005..6b2c91a9442 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp
@@ -154,7 +154,7 @@ traceid JfrTraceId::assign_thread_id() {
 
 traceid JfrTraceId::load_raw(jclass jc) {
   assert(jc != NULL, "invariant");
-  assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_vm, "invariant");
+  assert(JavaThread::current()->thread_state() == _thread_in_vm, "invariant");
   const oop my_oop = JNIHandles::resolve(jc);
   assert(my_oop != NULL, "invariant");
   return load_raw(java_lang_Class::as_Klass(my_oop));
@@ -190,7 +190,7 @@ void JfrTraceId::restore(const Klass* k) {
 
 bool JfrTraceId::in_visible_set(const jclass jc) {
   assert(jc != NULL, "invariant");
-  assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_vm, "invariant");
+  assert(JavaThread::current()->thread_state() == _thread_in_vm, "invariant");
   const oop mirror = JNIHandles::resolve(jc);
   assert(mirror != NULL, "invariant");
   return in_visible_set(java_lang_Class::as_Klass(mirror));
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp
index e7225fdf2f0..ffd56852b49 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp
@@ -100,7 +100,7 @@ inline traceid JfrTraceId::load_raw(const ClassLoaderData* cld) {
 
 inline bool JfrTraceId::in_visible_set(const Klass* klass) {
   assert(klass != NULL, "invariant");
-  assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_vm, "invariant");
+  assert(JavaThread::current()->thread_state() == _thread_in_vm, "invariant");
   return (IS_JDK_JFR_EVENT_SUBKLASS(klass) && !klass->is_abstract()) || IS_EVENT_HOST_KLASS(klass);
 }
 
diff --git a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.cpp b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.cpp
index 8dd5fef8e55..863429a1313 100644
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.cpp
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceIdLoadBarrier.cpp
@@ -73,7 +73,7 @@ void JfrTraceIdLoadBarrier::do_klasses(klass_callback callback, bool previous_ep
 
 traceid JfrTraceIdLoadBarrier::load(jclass jc) {
   assert(jc != NULL, "invariant");
-  assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_vm, "invariant");
+  assert(JavaThread::current()->thread_state() == _thread_in_vm, "invariant");
   const oop my_oop = JNIHandles::resolve(jc);
   assert(my_oop != NULL, "invariant");
   return load(java_lang_Class::as_Klass(my_oop));
diff --git a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp
index 4a71437e7e1..90ec9b356ab 100644
--- a/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp
+++ b/src/hotspot/share/jfr/recorder/repository/jfrChunkRotation.cpp
@@ -53,9 +53,9 @@ static jobject get_chunk_monitor(Thread* thread) {
 }
 
 static void notify() {
-  Thread* const thread = Thread::current();
+  JavaThread* const thread = JavaThread::current();
   // can safepoint here
-  ThreadInVMfromNative transition((JavaThread*)thread);
+  ThreadInVMfromNative transition(thread);
   ResetNoHandleMark rnhm;
   JfrJavaSupport::notify_all(get_chunk_monitor(thread), thread);
 }
diff --git a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp
index a77a5405761..dd2ffefff8b 100644
--- a/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp
+++ b/src/hotspot/share/jfr/recorder/repository/jfrEmergencyDump.cpp
@@ -504,7 +504,7 @@ class JavaThreadInVMAndNative : public StackObj {
   JavaThreadState _original_state;
  public:
 
-  JavaThreadInVMAndNative(Thread* t) : _jt(t->is_Java_thread() ? (JavaThread*)t : NULL),
+  JavaThreadInVMAndNative(Thread* t) : _jt(t->is_Java_thread() ? t->as_Java_thread() : NULL),
                                        _original_state(_thread_max_state) {
     if (_jt != NULL) {
       _original_state = _jt->thread_state();
diff --git a/src/hotspot/share/jfr/recorder/service/jfrPostBox.cpp b/src/hotspot/share/jfr/recorder/service/jfrPostBox.cpp
index 8477a805a6d..bfade7236b7 100644
--- a/src/hotspot/share/jfr/recorder/service/jfrPostBox.cpp
+++ b/src/hotspot/share/jfr/recorder/service/jfrPostBox.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@ JfrPostBox::JfrPostBox() :
 
 static bool is_thread_lock_aversive() {
   Thread* const thread = Thread::current();
-  return (thread->is_Java_thread() && ((JavaThread*)thread)->thread_state() != _thread_in_vm) || thread->is_VM_thread();
+  return (thread->is_Java_thread() && thread->as_Java_thread()->thread_state() != _thread_in_vm) || thread->is_VM_thread();
 }
 
 static bool is_synchronous(int messages) {
diff --git a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp
index 5d1f0eeeff2..dc6c812e3ae 100644
--- a/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp
+++ b/src/hotspot/share/jfr/recorder/service/jfrRecorderService.cpp
@@ -450,7 +450,7 @@ void JfrRecorderService::pre_safepoint_clear() {
 
 void JfrRecorderService::invoke_safepoint_clear() {
   JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_clear> safepoint_task(*this);
-  ThreadInVMfromNative transition((JavaThread*)Thread::current());
+  ThreadInVMfromNative transition(JavaThread::current());
   VMThread::execute(&safepoint_task);
 }
 
@@ -561,7 +561,7 @@ void JfrRecorderService::pre_safepoint_write() {
 void JfrRecorderService::invoke_safepoint_write() {
   JfrVMOperation<JfrRecorderService, &JfrRecorderService::safepoint_write> safepoint_task(*this);
   // can safepoint here
-  ThreadInVMfromNative transition((JavaThread*)Thread::current());
+  ThreadInVMfromNative transition(JavaThread::current());
   VMThread::execute(&safepoint_task);
 }
 
diff --git a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp
index 82e84542d9e..d62ad184cdd 100644
--- a/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp
+++ b/src/hotspot/share/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -142,7 +142,7 @@ traceid JfrStackTraceRepository::record(Thread* thread, int skip /* 0 */) {
   }
   assert(frames != NULL, "invariant");
   assert(tl->stackframes() == frames, "invariant");
-  return instance().record_for((JavaThread*)thread, skip, frames, tl->stackdepth());
+  return instance().record_for(thread->as_Java_thread(), skip, frames, tl->stackdepth());
 }
 
 traceid JfrStackTraceRepository::record_for(JavaThread* thread, int skip, JfrStackFrame *frames, u4 max_frames) {
diff --git a/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp b/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp
index d23ca077564..4c852faaa86 100644
--- a/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp
+++ b/src/hotspot/share/jfr/support/jfrAllocationTracer.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -30,9 +30,8 @@
 
 JfrAllocationTracer::JfrAllocationTracer(HeapWord* obj, size_t alloc_size, Thread* thread) : _tl(NULL) {
   if (LeakProfiler::is_running()) {
-    assert(thread->is_Java_thread(), "invariant");
     _tl = thread->jfr_thread_local();
-    LeakProfiler::sample(obj, alloc_size, (JavaThread*)thread);
+    LeakProfiler::sample(obj, alloc_size, thread->as_Java_thread());
   }
 }
 
diff --git a/src/hotspot/share/jfr/support/jfrEpochSynchronization.cpp b/src/hotspot/share/jfr/support/jfrEpochSynchronization.cpp
index c14b766332d..bc013e56ad6 100644
--- a/src/hotspot/share/jfr/support/jfrEpochSynchronization.cpp
+++ b/src/hotspot/share/jfr/support/jfrEpochSynchronization.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
@@ -31,10 +31,7 @@
 JfrEpochSynchronization::JfrEpochSynchronization() {
   if (JfrTraceIdEpoch::is_synchronizing()) {
     // only at a safepoint
-    Thread* thread = Thread::current();
-    assert(thread != NULL, "invariant");
-    assert(thread->is_Java_thread(), "invariant");
-    JavaThread* const jt = (JavaThread*)thread;
+    JavaThread* const jt = JavaThread::current();
     assert(jt->thread_state() == _thread_in_native, "invariant");
     // use ordinary transition to have the thread block and await the new epoch
     ThreadInVMfromNative transition(jt);
diff --git a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp
index 60077418bba..48b6d657ebc 100644
--- a/src/hotspot/share/jfr/support/jfrThreadLocal.cpp
+++ b/src/hotspot/share/jfr/support/jfrThreadLocal.cpp
@@ -95,7 +95,7 @@ void JfrThreadLocal::on_start(Thread* t) {
     JfrCheckpointManager::write_thread_checkpoint(t);
     if (!t->jfr_thread_local()->is_excluded()) {
       if (t->is_Java_thread()) {
-        send_java_thread_start_event((JavaThread*)t);
+        send_java_thread_start_event(t->as_Java_thread());
       }
     }
   }
@@ -160,7 +160,7 @@ void JfrThreadLocal::on_exit(Thread* t) {
   assert(!tl->is_dead(), "invariant");
   if (JfrRecorder::is_recording()) {
     if (t->is_Java_thread()) {
-      JavaThread* const jt = (JavaThread*)t;
+      JavaThread* const jt = t->as_Java_thread();
       ObjectSampleCheckpoint::on_thread_exit(jt);
       send_java_thread_end_events(tl->thread_id(), jt);
     }
diff --git a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp
index d4dcdeb58d2..a69e4bed216 100644
--- a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp
+++ b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp
@@ -171,7 +171,7 @@ class JfrJavaEventWriterNotificationClosure : public ThreadClosure {
  public:
    void do_thread(Thread* t) {
      if (t->is_Java_thread()) {
-       JfrJavaEventWriter::notify((JavaThread*)t);
+       JfrJavaEventWriter::notify(t->as_Java_thread());
      }
    }
 };
diff --git a/src/hotspot/share/jvmci/jvmci.cpp b/src/hotspot/share/jvmci/jvmci.cpp
index e3ad542543c..ab0cde9f922 100644
--- a/src/hotspot/share/jvmci/jvmci.cpp
+++ b/src/hotspot/share/jvmci/jvmci.cpp
@@ -23,9 +23,11 @@
 
 #include "precompiled.hpp"
 #include "classfile/systemDictionary.hpp"
+#include "compiler/compileTask.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "jvmci/jvmci.hpp"
 #include "jvmci/jvmciJavaClasses.hpp"
+#include "jvmci/jvmciEnv.hpp"
 #include "jvmci/jvmciRuntime.hpp"
 #include "jvmci/metadataHandles.hpp"
 #include "memory/resourceArea.hpp"
@@ -123,6 +125,18 @@ void JVMCI::initialize_globals() {
   }
 }
 
+JavaThread* JVMCI::compilation_tick(JavaThread* thread) {
+  if (thread->is_Compiler_thread()) {
+    CompileTask *task = thread->as_CompilerThread()->task();
+    if (task != NULL) {
+      JVMCICompileState *state = task->blocking_jvmci_compile_state();
+      if (state != NULL) {
+        state->inc_compilation_ticks();
+      }
+    }
+  }
+  return thread;
+}
 
 void JVMCI::metadata_do(void f(Metadata*)) {
   if (_java_runtime != NULL) {
diff --git a/src/hotspot/share/jvmci/jvmci.hpp b/src/hotspot/share/jvmci/jvmci.hpp
index f5df7f13532..e1b0cc0bf5b 100644
--- a/src/hotspot/share/jvmci/jvmci.hpp
+++ b/src/hotspot/share/jvmci/jvmci.hpp
@@ -110,6 +110,11 @@ class JVMCI : public AllStatic {
 
   static void initialize_compiler(TRAPS);
 
+  // Increments a value indicating some JVMCI compilation activity
+  // happened on `thread` if it is a CompilerThread.
+  // Returns `thread`.
+  static JavaThread* compilation_tick(JavaThread* thread);
+
   static JVMCIRuntime* compiler_runtime() { return _compiler_runtime; }
   // Gets the single runtime for JVMCI on the Java heap. This is the only
   // JVMCI runtime available when !UseJVMCINativeLibrary.
diff --git a/src/hotspot/share/jvmci/jvmciCompiler.cpp b/src/hotspot/share/jvmci/jvmciCompiler.cpp
index 804c38fe85a..bda41203993 100644
--- a/src/hotspot/share/jvmci/jvmciCompiler.cpp
+++ b/src/hotspot/share/jvmci/jvmciCompiler.cpp
@@ -37,6 +37,7 @@ JVMCICompiler::JVMCICompiler() : AbstractCompiler(compiler_jvmci) {
   _bootstrapping = false;
   _bootstrap_compilation_request_handled = false;
   _methods_compiled = 0;
+  _global_compilation_ticks = 0;
   assert(_instance == NULL, "only one instance allowed");
   _instance = this;
 }
@@ -83,7 +84,7 @@ void JVMCICompiler::bootstrap(TRAPS) {
   do {
     // Loop until there is something in the queue.
     do {
-      ((JavaThread*)THREAD)->sleep(100);
+      THREAD->as_Java_thread()->sleep(100);
       qsize = CompileBroker::queue_size(CompLevel_full_optimization);
     } while (!_bootstrap_compilation_request_handled && first_round && qsize == 0);
     first_round = false;
@@ -154,3 +155,12 @@ void JVMCICompiler::print_compilation_timers() {
     tty->print_cr("    JVMCI code install time:        %6.3f s", code_install_time);
   }
 }
+
+void JVMCICompiler::inc_methods_compiled() {
+  Atomic::inc(&_methods_compiled);
+  Atomic::inc(&_global_compilation_ticks);
+}
+
+void JVMCICompiler::inc_global_compilation_ticks() {
+  Atomic::inc(&_global_compilation_ticks);
+}
\ No newline at end of file
diff --git a/src/hotspot/share/jvmci/jvmciCompiler.hpp b/src/hotspot/share/jvmci/jvmciCompiler.hpp
index b522a54f525..db032b3c8ac 100644
--- a/src/hotspot/share/jvmci/jvmciCompiler.hpp
+++ b/src/hotspot/share/jvmci/jvmciCompiler.hpp
@@ -42,6 +42,10 @@ class JVMCICompiler : public AbstractCompiler {
    */
   volatile int _methods_compiled;
 
+  // Incremented periodically by JVMCI compiler threads
+  // to indicate JVMCI compilation activity.
+  volatile int _global_compilation_ticks;
+
   static JVMCICompiler* _instance;
 
   static elapsedTimer _codeInstallTimer;
@@ -99,15 +103,16 @@ class JVMCICompiler : public AbstractCompiler {
   // Print compilation timers and statistics
   virtual void print_timers();
 
-  /**
-   * Gets the number of methods that have been successfully compiled by
-   * a call to JVMCICompiler::compile_method().
-   */
+  // Gets the number of methods that have been successfully compiled by
+  // a call to JVMCICompiler::compile_method().
   int methods_compiled() { return _methods_compiled; }
+  void inc_methods_compiled();
 
-  void inc_methods_compiled() {
-    Atomic::inc(&_methods_compiled);
-  }
+  // Gets a value indicating JVMCI compilation activity on any thread.
+  // If successive calls to this method return a different value, then
+  // some degree of JVMCI compilation occurred between the calls.
+  int global_compilation_ticks() const { return _global_compilation_ticks; }
+  void inc_global_compilation_ticks();
 
   // Print compilation timers and statistics
   static void print_compilation_timers();
diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
index df006cd6487..b0443078a0b 100644
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp
@@ -48,6 +48,7 @@
 #include "runtime/deoptimization.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
 #include "runtime/frame.inline.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/reflectionUtils.hpp"
@@ -132,7 +133,7 @@ Handle JavaArgumentUnboxer::next_arg(BasicType expectedType) {
   TRACE_CALL(result_type, jvmci_ ## name signature)  \
   JVMCI_VM_ENTRY_MARK;                               \
   ResourceMark rm;                                   \
-  JNI_JVMCIENV(thread, env);
+  JNI_JVMCIENV(JVMCI::compilation_tick(thread), env);
 
 static JavaThread* get_current_thread(bool allow_null=true) {
   Thread* thread = Thread::current_or_null_safe();
@@ -140,8 +141,7 @@ static JavaThread* get_current_thread(bool allow_null=true) {
     assert(allow_null, "npe");
     return NULL;
   }
-  assert(thread->is_Java_thread(), "must be");
-  return (JavaThread*) thread;
+  return thread->as_Java_thread();
 }
 
 // Entry to native method implementation that transitions
@@ -2640,19 +2640,11 @@ C2V_VMENTRY_0(jlong, ticksNow, (JNIEnv* env, jobject))
   return CompilerEvent::ticksNow();
 }
 
-C2V_VMENTRY_0(jint, registerCompilerPhases, (JNIEnv* env, jobject, jobjectArray jphases))
+C2V_VMENTRY_0(jint, registerCompilerPhase, (JNIEnv* env, jobject, jstring jphase_name))
 #if INCLUDE_JFR
-  if (jphases == NULL) {
-    return -1;
-  }
-  JVMCIObjectArray phases = JVMCIENV->wrap(jphases);
-  int len = JVMCIENV->get_length(phases);
-  GrowableArray<const char*>* jvmci_phase_names = new GrowableArray<const char*>(len);
-  for (int i = 0; i < len; i++) {
-    JVMCIObject phase = JVMCIENV->get_object_at(phases, i);
-    jvmci_phase_names->append(strdup(JVMCIENV->as_utf8_string(phase)));
-  }
-  return CompilerEvent::PhaseEvent::register_phases(jvmci_phase_names);
+  JVMCIObject phase_name = JVMCIENV->wrap(jphase_name);
+  const char *name = JVMCIENV->as_utf8_string(phase_name);
+  return CompilerEvent::PhaseEvent::get_phase_id(name, true, true, true);
 #else
   return -1;
 #endif // !INCLUDE_JFR
@@ -2824,7 +2816,7 @@ JNINativeMethod CompilerToVM::methods[] = {
   {CC "addFailedSpeculation",                         CC "(J[B)Z",                                                                          FN_PTR(addFailedSpeculation)},
   {CC "callSystemExit",                               CC "(I)V",                                                                            FN_PTR(callSystemExit)},
   {CC "ticksNow",                                     CC "()J",                                                                             FN_PTR(ticksNow)},
-  {CC "registerCompilerPhases",                       CC "([" STRING ")I",                                                                  FN_PTR(registerCompilerPhases)},
+  {CC "registerCompilerPhase",                        CC "(" STRING ")I",                                                                   FN_PTR(registerCompilerPhase)},
   {CC "notifyCompilerPhaseEvent",                     CC "(JIII)V",                                                                         FN_PTR(notifyCompilerPhaseEvent)},
   {CC "notifyCompilerInliningEvent",                  CC "(I" HS_RESOLVED_METHOD HS_RESOLVED_METHOD "ZLjava/lang/String;I)V",               FN_PTR(notifyCompilerInliningEvent)},
 };
diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp
index a900859b667..b87314f9156 100644
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp
@@ -36,10 +36,12 @@
 #include "runtime/jniHandles.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "jvmci/jniAccessMark.inline.hpp"
+#include "jvmci/jvmciCompiler.hpp"
 #include "jvmci/jvmciRuntime.hpp"
 
-JVMCICompileState::JVMCICompileState(CompileTask* task):
+JVMCICompileState::JVMCICompileState(CompileTask* task, JVMCICompiler* compiler):
   _task(task),
+  _compiler(compiler),
   _retryable(true),
   _failure_reason(NULL),
   _failure_reason_on_C_heap(false) {
@@ -51,6 +53,20 @@ JVMCICompileState::JVMCICompileState(CompileTask* task):
   _jvmti_can_post_on_exceptions         = JvmtiExport::can_post_on_exceptions() ? 1 : 0;
   _jvmti_can_pop_frame                  = JvmtiExport::can_pop_frame() ? 1 : 0;
   _target_method_is_old                 = _task != NULL && _task->method()->is_old();
+  if (task->is_blocking()) {
+    task->set_blocking_jvmci_compile_state(this);
+  }
+}
+
+// Update global JVMCI compilation ticks after 512 thread-local JVMCI compilation ticks.
+// This mitigates the overhead of the atomic operation used for the global update.
+#define THREAD_TICKS_PER_GLOBAL_TICKS (2 << 9)
+#define THREAD_TICKS_PER_GLOBAL_TICKS_MASK (THREAD_TICKS_PER_GLOBAL_TICKS - 1)
+
+void JVMCICompileState::inc_compilation_ticks() {
+  if ((++_compilation_ticks & THREAD_TICKS_PER_GLOBAL_TICKS_MASK) == 0) {
+    _compiler->inc_global_compilation_ticks();
+  }
 }
 
 bool JVMCICompileState::jvmti_state_changed() const {
@@ -241,9 +257,9 @@ void JVMCIEnv::init(JavaThread* thread, bool is_hotspot, const char* file, int l
 
 // Prints a pending exception (if any) and its stack trace.
 void JVMCIEnv::describe_pending_exception(bool clear) {
-  Thread* THREAD = Thread::current();
+  JavaThread* THREAD = JavaThread::current();
   if (!is_hotspot()) {
-    JNIAccessMark jni(this);
+    JNIAccessMark jni(this, THREAD);
     if (jni()->ExceptionCheck()) {
       jthrowable ex = !clear ? jni()->ExceptionOccurred() : NULL;
       jni()->ExceptionDescribe();
@@ -253,7 +269,7 @@ void JVMCIEnv::describe_pending_exception(bool clear) {
     }
   } else {
     if (HAS_PENDING_EXCEPTION) {
-      JVMCIRuntime::describe_pending_hotspot_exception((JavaThread*) THREAD, clear);
+      JVMCIRuntime::describe_pending_hotspot_exception(THREAD, clear);
     }
   }
 }
@@ -292,8 +308,9 @@ JVMCIEnv::~JVMCIEnv() {
     if (is_hotspot()) {
       // Nothing to do
     } else {
-      if (Thread::current()->is_Java_thread()) {
-        JavaThread* THREAD = JavaThread::current();
+      Thread* thread = Thread::current();
+      if (thread->is_Java_thread()) {
+        JavaThread* THREAD = thread->as_Java_thread();
         if (HAS_PENDING_EXCEPTION) {
           Handle throwable = Handle(THREAD, PENDING_EXCEPTION);
           CLEAR_PENDING_EXCEPTION;
@@ -619,8 +636,8 @@ void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...)
 
 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtime, JVMCIObject method, int entry_bci,
                                                               jlong compile_state, int id) {
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   if (is_hotspot()) {
-    Thread* THREAD = Thread::current();
     JavaCallArguments jargs;
     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(method)));
@@ -634,7 +651,7 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtim
                             vmSymbols::compileMethod_signature(), &jargs, CHECK_(JVMCIObject()));
     return wrap((oop) result.get_jobject());
   } else {
-    JNIAccessMark jni(this);
+    JNIAccessMark jni(this, THREAD);
     jobject result = jni()->CallNonvirtualObjectMethod(runtime.as_jobject(),
                                                      JNIJVMCI::HotSpotJVMCIRuntime::clazz(),
                                                      JNIJVMCI::HotSpotJVMCIRuntime::compileMethod_method(),
@@ -647,14 +664,14 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_compileMethod (JVMCIObject runtim
 }
 
 void JVMCIEnv::call_HotSpotJVMCIRuntime_bootstrapFinished (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   if (is_hotspot()) {
-    Thread* THREAD = Thread::current();
     JavaCallArguments jargs;
     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
     JavaValue result(T_VOID);
     JavaCalls::call_special(&result, HotSpotJVMCI::HotSpotJVMCIRuntime::klass(), vmSymbols::bootstrapFinished_name(), vmSymbols::void_method_signature(), &jargs, CHECK);
   } else {
-    JNIAccessMark jni(this);
+    JNIAccessMark jni(this, THREAD);
     jni()->CallNonvirtualVoidMethod(runtime.as_jobject(), JNIJVMCI::HotSpotJVMCIRuntime::clazz(), JNIJVMCI::HotSpotJVMCIRuntime::bootstrapFinished_method());
 
   }
@@ -680,7 +697,7 @@ void JVMCIEnv::call_HotSpotJVMCIRuntime_shutdown (JVMCIObject runtime) {
 }
 
 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
-  JavaThread* THREAD = JavaThread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   if (is_hotspot()) {
     JavaCallArguments jargs;
     JavaValue result(T_OBJECT);
@@ -697,7 +714,7 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_runtime (JVMCIEnv* JVMCIENV) {
 }
 
 JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
-  JavaThread* THREAD = JavaThread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   if (is_hotspot()) {
     JavaCallArguments jargs;
     JavaValue result(T_OBJECT);
@@ -714,7 +731,7 @@ JVMCIObject JVMCIEnv::call_JVMCI_getRuntime (JVMCIEnv* JVMCIENV) {
 }
 
 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime, JVMCIEnv* JVMCIENV) {
-  JavaThread* THREAD = JavaThread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   if (is_hotspot()) {
     JavaCallArguments jargs;
     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(runtime)));
@@ -733,7 +750,7 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_getCompiler (JVMCIObject runtime,
 
 
 JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object, JVMCIEnv* JVMCIENV) {
-  JavaThread* THREAD = JavaThread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   if (is_hotspot()) {
     JavaCallArguments jargs;
     jargs.push_oop(Handle(THREAD, HotSpotJVMCI::resolve(object)));
@@ -757,7 +774,7 @@ JVMCIObject JVMCIEnv::call_HotSpotJVMCIRuntime_callToString(JVMCIObject object,
 
 
 JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value, JVMCI_TRAPS) {
-  JavaThread* THREAD = JavaThread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   if (is_hotspot()) {
     JavaCallArguments jargs;
     jargs.push_int(kind);
@@ -781,7 +798,7 @@ JVMCIObject JVMCIEnv::call_PrimitiveConstant_forTypeChar(jchar kind, jlong value
 }
 
 JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) {
-  JavaThread* THREAD = JavaThread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   if (is_hotspot()) {
     JavaCallArguments jargs;
     jargs.push_float(value);
@@ -804,7 +821,7 @@ JVMCIObject JVMCIEnv::call_JavaConstant_forFloat(float value, JVMCI_TRAPS) {
 }
 
 JVMCIObject JVMCIEnv::call_JavaConstant_forDouble(double value, JVMCI_TRAPS) {
-  JavaThread* THREAD = JavaThread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   if (is_hotspot()) {
     JavaCallArguments jargs;
     jargs.push_double(value);
@@ -885,7 +902,7 @@ JVMCIObject JVMCIEnv::new_StackTraceElement(const methodHandle& method, int bci,
 }
 
 JVMCIObject JVMCIEnv::new_HotSpotNmethod(const methodHandle& method, const char* name, jboolean isDefault, jlong compileId, JVMCI_TRAPS) {
-  JavaThread* THREAD = JavaThread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
 
   JVMCIObject methodObject = get_jvmci_method(method, JVMCI_CHECK_(JVMCIObject()));
 
@@ -988,7 +1005,7 @@ JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS)
     return method_object;
   }
 
-  Thread* THREAD = Thread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   jmetadata handle = _runtime->allocate_handle(method);
   jboolean exception = false;
   if (is_hotspot()) {
@@ -1004,7 +1021,7 @@ JVMCIObject JVMCIEnv::get_jvmci_method(const methodHandle& method, JVMCI_TRAPS)
       method_object = wrap((oop)result.get_jobject());
     }
   } else {
-    JNIAccessMark jni(this);
+    JNIAccessMark jni(this, THREAD);
     method_object = JNIJVMCI::wrap(jni()->CallStaticObjectMethod(JNIJVMCI::HotSpotResolvedJavaMethodImpl::clazz(),
                                                                   JNIJVMCI::HotSpotResolvedJavaMethodImpl_fromMetaspace_method(),
                                                                   (jlong) handle));
@@ -1031,7 +1048,7 @@ JVMCIObject JVMCIEnv::get_jvmci_type(const JVMCIKlassHandle& klass, JVMCI_TRAPS)
   }
 
   jlong pointer = (jlong) klass();
-  JavaThread* THREAD = JavaThread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   JVMCIObject signature = create_string(klass->signature_name(), JVMCI_CHECK_(JVMCIObject()));
   jboolean exception = false;
   if (is_hotspot()) {
@@ -1070,7 +1087,7 @@ JVMCIObject JVMCIEnv::get_jvmci_constant_pool(const constantPoolHandle& cp, JVMC
   JVMCIObject cp_object;
   jmetadata handle = _runtime->allocate_handle(cp);
   jboolean exception = false;
-  JavaThread* THREAD = JavaThread::current();
+  JavaThread* THREAD = JVMCI::compilation_tick(JavaThread::current());
   if (is_hotspot()) {
     JavaValue result(T_OBJECT);
     JavaCallArguments args;
diff --git a/src/hotspot/share/jvmci/jvmciEnv.hpp b/src/hotspot/share/jvmci/jvmciEnv.hpp
index 333525d5d69..e59a3bde6e0 100644
--- a/src/hotspot/share/jvmci/jvmciEnv.hpp
+++ b/src/hotspot/share/jvmci/jvmciEnv.hpp
@@ -94,6 +94,7 @@ class JVMCICompileState : public ResourceObj {
   friend class JVMCIVMStructs;
  private:
   CompileTask*     _task;
+  JVMCICompiler*   _compiler;
 
   // Cache JVMTI state. Defined as bytes so that reading them from Java
   // via Unsafe is well defined (the C++ type for bool is implementation
@@ -113,8 +114,13 @@ class JVMCICompileState : public ResourceObj {
   // with the mtJVMCI NMT flag.
   bool             _failure_reason_on_C_heap;
 
+  // A value indicating compilation activity during the compilation.
+  // If successive calls to this method return a different value, then
+  // some degree of JVMCI compilation occurred between the calls.
+  jint             _compilation_ticks;
+
  public:
-  JVMCICompileState(CompileTask* task);
+  JVMCICompileState(CompileTask* task, JVMCICompiler* compiler);
 
   CompileTask* task() { return _task; }
 
@@ -135,6 +141,9 @@ class JVMCICompileState : public ResourceObj {
     _failure_reason_on_C_heap = reason_on_C_heap;
     _retryable = retryable;
   }
+
+  jint compilation_ticks() const { return _compilation_ticks; }
+  void inc_compilation_ticks();
 };
 
 
@@ -284,7 +293,7 @@ class JVMCIEnv : public ResourceObj {
   JVMCIPrimitiveArray wrap(typeArrayOop obj) { assert(is_hotspot(), "must be"); return (JVMCIPrimitiveArray) wrap(JNIHandles::make_local(obj)); }
 
  public:
-  // Compiles a method with the JVMIC compiler.
+  // Compiles a method with the JVMCI compiler.
   // Caller must handle pending exception.
   JVMCIObject call_HotSpotJVMCIRuntime_compileMethod(JVMCIObject runtime, JVMCIObject method, int entry_bci,
                                                      jlong compile_state, int id);
diff --git a/src/hotspot/share/jvmci/jvmci_globals.cpp b/src/hotspot/share/jvmci/jvmci_globals.cpp
index 290775278c0..dc6a9000da0 100644
--- a/src/hotspot/share/jvmci/jvmci_globals.cpp
+++ b/src/hotspot/share/jvmci/jvmci_globals.cpp
@@ -38,9 +38,9 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
 
 #ifndef PRODUCT
 #define APPLY_JVMCI_FLAGS(params3, params4) \
-  JVMCI_FLAGS(params4, params3, params4, params3, params4, params3, params4, params4, IGNORE_RANGE, IGNORE_CONSTRAINT)
-#define JVMCI_DECLARE_CHECK4(type, name, value, doc) bool name##checked = false;
-#define JVMCI_DECLARE_CHECK3(type, name, doc)        bool name##checked = false;
+  JVMCI_FLAGS(params4, params3, params4, params3, params4, IGNORE_RANGE, IGNORE_CONSTRAINT)
+#define JVMCI_DECLARE_CHECK4(type, name, value, ...) bool name##checked = false;
+#define JVMCI_DECLARE_CHECK3(type, name, ...)        bool name##checked = false;
 #define JVMCI_FLAG_CHECKED(name)                          name##checked = true;
   APPLY_JVMCI_FLAGS(JVMCI_DECLARE_CHECK3, JVMCI_DECLARE_CHECK4)
 #else
@@ -131,8 +131,8 @@ bool JVMCIGlobals::check_jvmci_flags_are_consistent() {
 #endif // !COMPILER2
 
 #ifndef PRODUCT
-#define JVMCI_CHECK4(type, name, value, doc) assert(name##checked, #name " flag not checked");
-#define JVMCI_CHECK3(type, name, doc)        assert(name##checked, #name " flag not checked");
+#define JVMCI_CHECK4(type, name, value, ...) assert(name##checked, #name " flag not checked");
+#define JVMCI_CHECK3(type, name, ...)        assert(name##checked, #name " flag not checked");
   // Ensures that all JVMCI flags are checked by this method.
   APPLY_JVMCI_FLAGS(JVMCI_CHECK3, JVMCI_CHECK4)
 #undef APPLY_JVMCI_FLAGS
diff --git a/src/hotspot/share/jvmci/jvmci_globals.hpp b/src/hotspot/share/jvmci/jvmci_globals.hpp
index f4ae52b8473..dd1a375c732 100644
--- a/src/hotspot/share/jvmci/jvmci_globals.hpp
+++ b/src/hotspot/share/jvmci/jvmci_globals.hpp
@@ -30,54 +30,51 @@
 class fileStream;
 
 //
-// Defines all global flags used by the JVMCI compiler. Only flags that need
+// Declare all global flags used by the JVMCI compiler. Only flags that need
 // to be accessible to the JVMCI C++ code should be defined here.
 //
-#define JVMCI_FLAGS(develop, \
-                    develop_pd, \
-                    product, \
-                    product_pd, \
-                    diagnostic, \
-                    diagnostic_pd, \
-                    experimental, \
-                    notproduct, \
-                    range, \
-                    constraint) \
-                                                                            \
-  experimental(bool, EnableJVMCI, false,                                    \
+#define JVMCI_FLAGS(develop,                                                \
+                    develop_pd,                                             \
+                    product,                                                \
+                    product_pd,                                             \
+                    notproduct,                                             \
+                    range,                                                  \
+                    constraint)                                             \
+                                                                            \
+  product(bool, EnableJVMCI, false, EXPERIMENTAL,                           \
           "Enable JVMCI")                                                   \
                                                                             \
-  experimental(bool, EnableJVMCIProduct, false,                             \
+  product(bool, EnableJVMCIProduct, false, EXPERIMENTAL,                    \
           "Allow JVMCI to be used in product mode. This alters a subset of "\
           "JVMCI flags to be non-experimental, defaults UseJVMCICompiler "  \
           "and EnableJVMCI to true and defaults UseJVMCINativeLibrary "     \
           "to true if a JVMCI native library is available.")                \
                                                                             \
-  experimental(bool, UseJVMCICompiler, false,                               \
+  product(bool, UseJVMCICompiler, false, EXPERIMENTAL,                      \
           "Use JVMCI as the default compiler. Defaults to true if "         \
           "EnableJVMCIProduct is true.")                                    \
                                                                             \
-  experimental(bool, JVMCIPrintProperties, false,                           \
+  product(bool, JVMCIPrintProperties, false, EXPERIMENTAL,                  \
           "Prints properties used by the JVMCI compiler and exits")         \
                                                                             \
-  experimental(bool, BootstrapJVMCI, false,                                 \
+  product(bool, BootstrapJVMCI, false, EXPERIMENTAL,                        \
           "Bootstrap JVMCI before running Java main method. This "          \
           "initializes the compile queue with a small set of methods "      \
           "and processes the queue until it is empty. Combining this with " \
           "-XX:-TieredCompilation makes JVMCI compile more of itself.")     \
                                                                             \
-  experimental(bool, EagerJVMCI, false,                                     \
+  product(bool, EagerJVMCI, false, EXPERIMENTAL,                            \
           "Force eager JVMCI initialization")                               \
                                                                             \
-  experimental(bool, PrintBootstrap, true,                                  \
+  product(bool, PrintBootstrap, true, EXPERIMENTAL,                         \
           "Print JVMCI bootstrap progress and summary")                     \
                                                                             \
-  experimental(intx, JVMCIThreads, 1,                                       \
+  product(intx, JVMCIThreads, 1, EXPERIMENTAL,                              \
           "Force number of JVMCI compiler threads to use. Ignored if "      \
           "UseJVMCICompiler is false.")                                     \
           range(1, max_jint)                                                \
                                                                             \
-  experimental(intx, JVMCIHostThreads, 1,                                   \
+  product(intx, JVMCIHostThreads, 1, EXPERIMENTAL,                          \
           "Force number of C1 compiler threads. Ignored if "                \
           "UseJVMCICompiler is false.")                                     \
           range(1, max_jint)                                                \
@@ -90,56 +87,58 @@ class fileStream;
   NOT_COMPILER2(product(bool, ReduceInitialCardMarks, true,                 \
           "Defer write barriers of young objects"))                         \
                                                                             \
-  experimental(intx, JVMCIEventLogLevel, 1,                                 \
+  product(intx, JVMCIEventLogLevel, 1, EXPERIMENTAL,                        \
           "Event log level for JVMCI")                                      \
           range(0, 4)                                                       \
                                                                             \
-  experimental(intx, JVMCITraceLevel, 0,                                    \
+  product(intx, JVMCITraceLevel, 0, EXPERIMENTAL,                           \
           "Trace level for JVMCI")                                          \
           range(0, 4)                                                       \
                                                                             \
-  experimental(intx, JVMCICounterSize, 0,                                   \
+  product(intx, JVMCICounterSize, 0, EXPERIMENTAL,                          \
           "Reserved size for benchmark counters")                           \
           range(0, 1000000)                                                 \
                                                                             \
-  experimental(bool, JVMCICountersExcludeCompiler, true,                    \
+  product(bool, JVMCICountersExcludeCompiler, true, EXPERIMENTAL,           \
           "Exclude JVMCI compiler threads from benchmark counters")         \
                                                                             \
   develop(bool, JVMCIUseFastLocking, true,                                  \
           "Use fast inlined locking code")                                  \
                                                                             \
-  experimental(intx, JVMCINMethodSizeLimit, (80*K)*wordSize,                \
+  product(intx, JVMCINMethodSizeLimit, (80*K)*wordSize, EXPERIMENTAL,       \
           "Maximum size of a compiled method.")                             \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(ccstr, JVMCILibPath, NULL,                                   \
+  product(ccstr, JVMCILibPath, NULL, EXPERIMENTAL,                          \
           "LD path for loading the JVMCI shared library")                   \
                                                                             \
-  experimental(ccstr, JVMCILibDumpJNIConfig, NULL,                          \
+  product(ccstr, JVMCILibDumpJNIConfig, NULL, EXPERIMENTAL,                 \
           "Dumps to the given file a description of the classes, fields "   \
           "and methods the JVMCI shared library must provide")              \
                                                                             \
-  experimental(bool, UseJVMCINativeLibrary, false,                          \
+  product(bool, UseJVMCINativeLibrary, false, EXPERIMENTAL,                 \
           "Execute JVMCI Java code from a shared library "                  \
           "instead of loading it from class files and executing it "        \
           "on the HotSpot heap. Defaults to true if EnableJVMCIProduct is " \
           "true and a JVMCI native library is available.")                  \
                                                                             \
-  NOT_COMPILER2(diagnostic(bool, UseMultiplyToLenIntrinsic, false,          \
+  NOT_COMPILER2(product(bool, UseMultiplyToLenIntrinsic, false, DIAGNOSTIC, \
           "Enables intrinsification of BigInteger.multiplyToLen()"))        \
                                                                             \
-  NOT_COMPILER2(diagnostic(bool, UseSquareToLenIntrinsic, false,            \
+  NOT_COMPILER2(product(bool, UseSquareToLenIntrinsic, false, DIAGNOSTIC,   \
           "Enables intrinsification of BigInteger.squareToLen()"))          \
                                                                             \
-  NOT_COMPILER2(diagnostic(bool, UseMulAddIntrinsic, false,                 \
+  NOT_COMPILER2(product(bool, UseMulAddIntrinsic, false, DIAGNOSTIC,        \
           "Enables intrinsification of BigInteger.mulAdd()"))               \
                                                                             \
-  NOT_COMPILER2(diagnostic(bool, UseMontgomeryMultiplyIntrinsic, false,     \
+  NOT_COMPILER2(product(bool, UseMontgomeryMultiplyIntrinsic, false, DIAGNOSTIC, \
           "Enables intrinsification of BigInteger.montgomeryMultiply()"))   \
                                                                             \
-  NOT_COMPILER2(diagnostic(bool, UseMontgomerySquareIntrinsic, false,       \
+  NOT_COMPILER2(product(bool, UseMontgomerySquareIntrinsic, false, DIAGNOSTIC, \
           "Enables intrinsification of BigInteger.montgomerySquare()"))
 
+// end of JVMCI_FLAGS
+
 // The base name for the shared library containing the JVMCI based compiler
 #define JVMCI_SHARED_LIBRARY_NAME "jvmcicompiler"
 
diff --git a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
index 9c6c5279bfa..3a4b776d0a1 100644
--- a/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
+++ b/src/hotspot/share/jvmci/vmStructs_jvmci.cpp
@@ -149,12 +149,6 @@
   nonstatic_field(ExceptionTableElement,       handler_pc,                                    u2)                                    \
   nonstatic_field(ExceptionTableElement,       catch_type_index,                              u2)                                    \
                                                                                                                                      \
-  nonstatic_field(JVMFlag,                     _type,                                         const char*)                           \
-  nonstatic_field(JVMFlag,                     _name,                                         const char*)                           \
-  unchecked_nonstatic_field(JVMFlag,           _addr,                                         sizeof(void*))                         \
-  nonstatic_field(JVMFlag,                     _flags,                                        JVMFlag::Flags)                        \
-  static_field(JVMFlag,                        flags,                                         JVMFlag*)                              \
-                                                                                                                                     \
   nonstatic_field(InstanceKlass,               _fields,                                       Array<u2>*)                            \
   nonstatic_field(InstanceKlass,               _constants,                                    ConstantPool*)                         \
   nonstatic_field(InstanceKlass,               _init_state,                                   u1)                                    \
@@ -169,6 +163,7 @@
   nonstatic_field(JVMCICompileState,           _jvmti_can_access_local_variables,             jbyte)                                 \
   nonstatic_field(JVMCICompileState,           _jvmti_can_post_on_exceptions,                 jbyte)                                 \
   nonstatic_field(JVMCICompileState,           _jvmti_can_pop_frame,                          jbyte)                                 \
+  nonstatic_field(JVMCICompileState,           _compilation_ticks,                            jint)                                  \
                                                                                                                                      \
   nonstatic_field(JavaThread,                  _threadObj,                                    OopHandle)                             \
   nonstatic_field(JavaThread,                  _anchor,                                       JavaFrameAnchor)                       \
diff --git a/src/hotspot/share/memory/archiveBuilder.cpp b/src/hotspot/share/memory/archiveBuilder.cpp
index 5401fd89a34..adf3b63b08c 100644
--- a/src/hotspot/share/memory/archiveBuilder.cpp
+++ b/src/hotspot/share/memory/archiveBuilder.cpp
@@ -23,11 +23,13 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderDataShared.hpp"
 #include "classfile/systemDictionaryShared.hpp"
 #include "logging/log.hpp"
 #include "logging/logMessage.hpp"
 #include "memory/archiveBuilder.hpp"
 #include "memory/archiveUtils.hpp"
+#include "memory/cppVtables.hpp"
 #include "memory/dumpAllocStats.hpp"
 #include "memory/metaspaceShared.hpp"
 #include "memory/resourceArea.hpp"
@@ -218,6 +220,11 @@ void ArchiveBuilder::gather_klasses_and_symbols() {
   log_info(cds)("Gathering classes and symbols ... ");
   GatherKlassesAndSymbols doit(this);
   iterate_roots(&doit, /*is_relocating_pointers=*/false);
+#if INCLUDE_CDS_JAVA_HEAP
+  if (DumpSharedSpaces && MetaspaceShared::use_full_module_graph()) {
+    ClassLoaderDataShared::iterate_symbols(&doit);
+  }
+#endif
   doit.finish();
 
   log_info(cds)("Number of classes %d", _num_instance_klasses + _num_obj_array_klasses + _num_type_array_klasses);
@@ -473,7 +480,7 @@ void ArchiveBuilder::make_shallow_copy(DumpRegion *dump_region, SourceObjInfo* s
 
   memcpy(dest, src, bytes);
 
-  intptr_t* archived_vtable = MetaspaceShared::get_archived_cpp_vtable(ref->msotype(), (address)dest);
+  intptr_t* archived_vtable = CppVtables::get_archived_cpp_vtable(ref->msotype(), (address)dest);
   if (archived_vtable != NULL) {
     *(address*)dest = (address)archived_vtable;
     ArchivePtrMarker::mark_pointer((address*)dest);
diff --git a/src/hotspot/share/memory/cppVtables.cpp b/src/hotspot/share/memory/cppVtables.cpp
new file mode 100644
index 00000000000..914ea209196
--- /dev/null
+++ b/src/hotspot/share/memory/cppVtables.cpp
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 "logging/log.hpp"
+#include "memory/archiveUtils.hpp"
+#include "memory/cppVtables.hpp"
+#include "memory/metaspaceShared.hpp"
+#include "oops/instanceClassLoaderKlass.hpp"
+#include "oops/instanceMirrorKlass.hpp"
+#include "oops/instanceRefKlass.hpp"
+#include "oops/methodData.hpp"
+#include "oops/objArrayKlass.hpp"
+#include "oops/typeArrayKlass.hpp"
+#include "runtime/arguments.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+// Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables.
+// (In GCC this is the field <Type>::_vptr, i.e., first word in the object.)
+//
+// Addresses of the vtables and the methods may be different across JVM runs,
+// if libjvm.so is dynamically loaded at a different base address.
+//
+// To ensure that the Metadata objects in the CDS archive always have the correct vtable:
+//
+// + at dump time:  we redirect the _vptr to point to our own vtables inside
+//                  the CDS image
+// + at run time:   we clone the actual contents of the vtables from libjvm.so
+//                  into our own tables.
+
+// Currently, the archive contain ONLY the following types of objects that have C++ vtables.
+#define CPP_VTABLE_PATCH_TYPES_DO(f) \
+  f(ConstantPool) \
+  f(InstanceKlass) \
+  f(InstanceClassLoaderKlass) \
+  f(InstanceMirrorKlass) \
+  f(InstanceRefKlass) \
+  f(Method) \
+  f(ObjArrayKlass) \
+  f(TypeArrayKlass)
+
+class CppVtableInfo {
+  intptr_t _vtable_size;
+  intptr_t _cloned_vtable[1];
+public:
+  static int num_slots(int vtable_size) {
+    return 1 + vtable_size; // Need to add the space occupied by _vtable_size;
+  }
+  int vtable_size()           { return int(uintx(_vtable_size)); }
+  void set_vtable_size(int n) { _vtable_size = intptr_t(n); }
+  intptr_t* cloned_vtable()   { return &_cloned_vtable[0]; }
+  void zero()                 { memset(_cloned_vtable, 0, sizeof(intptr_t) * vtable_size()); }
+  // Returns the address of the next CppVtableInfo that can be placed immediately after this CppVtableInfo
+  static size_t byte_size(int vtable_size) {
+    CppVtableInfo i;
+    return pointer_delta(&i._cloned_vtable[vtable_size], &i, sizeof(u1));
+  }
+};
+
+static inline intptr_t* vtable_of(Metadata* m) {
+  return *((intptr_t**)m);
+}
+
+static inline DumpRegion* mc_region() {
+  return MetaspaceShared::misc_code_dump_space();
+}
+
+template <class T> class CppVtableCloner : public T {
+  static CppVtableInfo* _info;
+
+  static int get_vtable_length(const char* name);
+
+public:
+  // Allocate and initialize the C++ vtable, starting from top, but do not go past end.
+  static intptr_t* allocate(const char* name);
+
+  // Clone the vtable to ...
+  static intptr_t* clone_vtable(const char* name, CppVtableInfo* info);
+
+  static void zero_vtable_clone() {
+    assert(DumpSharedSpaces, "dump-time only");
+    _info->zero();
+  }
+
+  static bool is_valid_shared_object(const T* obj) {
+    intptr_t* vptr = *(intptr_t**)obj;
+    return vptr == _info->cloned_vtable();
+  }
+
+  static void init_orig_cpp_vtptr(int kind);
+};
+
+template <class T> CppVtableInfo* CppVtableCloner<T>::_info = NULL;
+
+template <class T>
+intptr_t* CppVtableCloner<T>::allocate(const char* name) {
+  assert(is_aligned(mc_region()->top(), sizeof(intptr_t)), "bad alignment");
+  int n = get_vtable_length(name);
+  _info = (CppVtableInfo*)mc_region()->allocate(CppVtableInfo::byte_size(n), sizeof(intptr_t));
+  _info->set_vtable_size(n);
+
+  intptr_t* p = clone_vtable(name, _info);
+  assert((char*)p == mc_region()->top(), "must be");
+
+  return _info->cloned_vtable();
+}
+
+template <class T>
+intptr_t* CppVtableCloner<T>::clone_vtable(const char* name, CppVtableInfo* info) {
+  if (!DumpSharedSpaces) {
+    assert(_info == 0, "_info is initialized only at dump time");
+    _info = info; // Remember it -- it will be used by MetaspaceShared::is_valid_shared_method()
+  }
+  T tmp; // Allocate temporary dummy metadata object to get to the original vtable.
+  int n = info->vtable_size();
+  intptr_t* srcvtable = vtable_of(&tmp);
+  intptr_t* dstvtable = info->cloned_vtable();
+
+  // We already checked (and, if necessary, adjusted n) when the vtables were allocated, so we are
+  // safe to do memcpy.
+  log_debug(cds, vtables)("Copying %3d vtable entries for %s", n, name);
+  memcpy(dstvtable, srcvtable, sizeof(intptr_t) * n);
+  return dstvtable + n;
+}
+
+// To determine the size of the vtable for each type, we use the following
+// trick by declaring 2 subclasses:
+//
+//   class CppVtableTesterA: public InstanceKlass {virtual int   last_virtual_method() {return 1;}    };
+//   class CppVtableTesterB: public InstanceKlass {virtual void* last_virtual_method() {return NULL}; };
+//
+// CppVtableTesterA and CppVtableTesterB's vtables have the following properties:
+// - Their size (N+1) is exactly one more than the size of InstanceKlass's vtable (N)
+// - The first N entries have are exactly the same as in InstanceKlass's vtable.
+// - Their last entry is different.
+//
+// So to determine the value of N, we just walk CppVtableTesterA and CppVtableTesterB's tables
+// and find the first entry that's different.
+//
+// This works on all C++ compilers supported by Oracle, but you may need to tweak it for more
+// esoteric compilers.
+
+template <class T> class CppVtableTesterB: public T {
+public:
+  virtual int last_virtual_method() {return 1;}
+};
+
+template <class T> class CppVtableTesterA : public T {
+public:
+  virtual void* last_virtual_method() {
+    // Make this different than CppVtableTesterB::last_virtual_method so the C++
+    // compiler/linker won't alias the two functions.
+    return NULL;
+  }
+};
+
+template <class T>
+int CppVtableCloner<T>::get_vtable_length(const char* name) {
+  CppVtableTesterA<T> a;
+  CppVtableTesterB<T> b;
+
+  intptr_t* avtable = vtable_of(&a);
+  intptr_t* bvtable = vtable_of(&b);
+
+  // Start at slot 1, because slot 0 may be RTTI (on Solaris/Sparc)
+  int vtable_len = 1;
+  for (; ; vtable_len++) {
+    if (avtable[vtable_len] != bvtable[vtable_len]) {
+      break;
+    }
+  }
+  log_debug(cds, vtables)("Found   %3d vtable entries for %s", vtable_len, name);
+
+  return vtable_len;
+}
+
+#define ALLOC_CPP_VTABLE_CLONE(c) \
+  _cloned_cpp_vtptrs[c##_Kind] = CppVtableCloner<c>::allocate(#c); \
+  ArchivePtrMarker::mark_pointer(&_cloned_cpp_vtptrs[c##_Kind]);
+
+#define CLONE_CPP_VTABLE(c) \
+  p = CppVtableCloner<c>::clone_vtable(#c, (CppVtableInfo*)p);
+
+#define ZERO_CPP_VTABLE(c) \
+ CppVtableCloner<c>::zero_vtable_clone();
+
+#define INIT_ORIG_CPP_VTPTRS(c) \
+  CppVtableCloner<c>::init_orig_cpp_vtptr(c##_Kind);
+
+#define DECLARE_CLONED_VTABLE_KIND(c) c ## _Kind,
+
+enum ClonedVtableKind {
+  // E.g., ConstantPool_Kind == 0, InstanceKlass_Kind == 1, etc.
+  CPP_VTABLE_PATCH_TYPES_DO(DECLARE_CLONED_VTABLE_KIND)
+  _num_cloned_vtable_kinds
+};
+
+// This is a map of all the original vtptrs. E.g., for
+//     ConstantPool *cp = new (...) ConstantPool(...) ; // a dynamically allocated constant pool
+// the following holds true:
+//     _orig_cpp_vtptrs[ConstantPool_Kind] ==  ((intptr_t**)cp)[0]
+static intptr_t* _orig_cpp_vtptrs[_num_cloned_vtable_kinds];
+static bool _orig_cpp_vtptrs_inited = false;
+
+template <class T>
+void CppVtableCloner<T>::init_orig_cpp_vtptr(int kind) {
+  assert(kind < _num_cloned_vtable_kinds, "sanity");
+  T tmp; // Allocate temporary dummy metadata object to get to the original vtable.
+  intptr_t* srcvtable = vtable_of(&tmp);
+  _orig_cpp_vtptrs[kind] = srcvtable;
+}
+
+// This is the index of all the cloned vtables. E.g., for
+//     ConstantPool* cp = ....; // an archived constant pool
+//     InstanceKlass* ik = ....;// an archived class
+// the following holds true:
+//     _cloned_cpp_vtptrs[ConstantPool_Kind]  == ((intptr_t**)cp)[0]
+//     _cloned_cpp_vtptrs[InstanceKlass_Kind] == ((intptr_t**)ik)[0]
+static intptr_t** _cloned_cpp_vtptrs = NULL;
+
+void CppVtables::allocate_cloned_cpp_vtptrs() {
+  assert(DumpSharedSpaces, "must");
+  size_t vtptrs_bytes = _num_cloned_vtable_kinds * sizeof(intptr_t*);
+  _cloned_cpp_vtptrs = (intptr_t**)mc_region()->allocate(vtptrs_bytes, sizeof(intptr_t*));
+}
+
+void CppVtables::serialize_cloned_cpp_vtptrs(SerializeClosure* soc) {
+  soc->do_ptr((void**)&_cloned_cpp_vtptrs);
+}
+
+intptr_t* CppVtables::get_archived_cpp_vtable(MetaspaceObj::Type msotype, address obj) {
+  if (!_orig_cpp_vtptrs_inited) {
+    CPP_VTABLE_PATCH_TYPES_DO(INIT_ORIG_CPP_VTPTRS);
+    _orig_cpp_vtptrs_inited = true;
+  }
+
+  Arguments::assert_is_dumping_archive();
+  int kind = -1;
+  switch (msotype) {
+  case MetaspaceObj::SymbolType:
+  case MetaspaceObj::TypeArrayU1Type:
+  case MetaspaceObj::TypeArrayU2Type:
+  case MetaspaceObj::TypeArrayU4Type:
+  case MetaspaceObj::TypeArrayU8Type:
+  case MetaspaceObj::TypeArrayOtherType:
+  case MetaspaceObj::ConstMethodType:
+  case MetaspaceObj::ConstantPoolCacheType:
+  case MetaspaceObj::AnnotationsType:
+  case MetaspaceObj::MethodCountersType:
+  case MetaspaceObj::RecordComponentType:
+    // These have no vtables.
+    break;
+  case MetaspaceObj::MethodDataType:
+    // We don't archive MethodData <-- should have been removed in removed_unsharable_info
+    ShouldNotReachHere();
+    break;
+  default:
+    for (kind = 0; kind < _num_cloned_vtable_kinds; kind ++) {
+      if (vtable_of((Metadata*)obj) == _orig_cpp_vtptrs[kind]) {
+        break;
+      }
+    }
+    if (kind >= _num_cloned_vtable_kinds) {
+      fatal("Cannot find C++ vtable for " INTPTR_FORMAT " -- you probably added"
+            " a new subtype of Klass or MetaData without updating CPP_VTABLE_PATCH_TYPES_DO",
+            p2i(obj));
+    }
+  }
+
+  if (kind >= 0) {
+    assert(kind < _num_cloned_vtable_kinds, "must be");
+    return _cloned_cpp_vtptrs[kind];
+  } else {
+    return NULL;
+  }
+}
+
+// This can be called at both dump time and run time:
+// - clone the contents of the c++ vtables into the space
+//   allocated by allocate_cpp_vtable_clones()
+void CppVtables::clone_cpp_vtables(intptr_t* p) {
+  assert(DumpSharedSpaces || UseSharedSpaces, "sanity");
+  CPP_VTABLE_PATCH_TYPES_DO(CLONE_CPP_VTABLE);
+}
+
+void CppVtables::zero_cpp_vtable_clones_for_writing() {
+  assert(DumpSharedSpaces, "dump-time only");
+  CPP_VTABLE_PATCH_TYPES_DO(ZERO_CPP_VTABLE);
+}
+
+// Allocate and initialize the C++ vtables, starting from top, but do not go past end.
+char* CppVtables::allocate_cpp_vtable_clones() {
+  char* cloned_vtables = mc_region()->top(); // This is the beginning of all the cloned vtables
+
+  assert(DumpSharedSpaces, "dump-time only");
+  // Layout (each slot is a intptr_t):
+  //   [number of slots in the first vtable = n1]
+  //   [ <n1> slots for the first vtable]
+  //   [number of slots in the first second = n2]
+  //   [ <n2> slots for the second vtable]
+  //   ...
+  // The order of the vtables is the same as the CPP_VTAB_PATCH_TYPES_DO macro.
+  CPP_VTABLE_PATCH_TYPES_DO(ALLOC_CPP_VTABLE_CLONE);
+
+  return cloned_vtables;
+}
+
+bool CppVtables::is_valid_shared_method(const Method* m) {
+  assert(MetaspaceShared::is_in_shared_metaspace(m), "must be");
+  return CppVtableCloner<Method>::is_valid_shared_object(m);
+}
diff --git a/src/hotspot/share/memory/cppVtables.hpp b/src/hotspot/share/memory/cppVtables.hpp
new file mode 100644
index 00000000000..8604424c6fc
--- /dev/null
+++ b/src/hotspot/share/memory/cppVtables.hpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_MEMORY_CPPVTABLES_HPP
+#define SHARE_MEMORY_CPPVTABLES_HPP
+
+#include "memory/allocation.hpp"
+#include "memory/allStatic.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+class Method;
+class SerializeClosure;
+
+// Support for C++ vtables in CDS archive.
+class CppVtables : AllStatic {
+  static void patch_cpp_vtable_pointers();
+public:
+  static char* allocate_cpp_vtable_clones();
+  static void allocate_cloned_cpp_vtptrs();
+  static void clone_cpp_vtables(intptr_t* p);
+  static void zero_cpp_vtable_clones_for_writing();
+  static intptr_t* get_archived_cpp_vtable(MetaspaceObj::Type msotype, address obj);
+  static void serialize_cloned_cpp_vtptrs(SerializeClosure* sc);
+  static bool is_valid_shared_method(const Method* m) NOT_CDS_RETURN_(false);
+};
+
+#endif // SHARE_MEMORY_CPPVTABLES_HPP
diff --git a/src/hotspot/share/memory/dumpAllocStats.hpp b/src/hotspot/share/memory/dumpAllocStats.hpp
index a0d3228de13..bb1e20b1191 100644
--- a/src/hotspot/share/memory/dumpAllocStats.hpp
+++ b/src/hotspot/share/memory/dumpAllocStats.hpp
@@ -39,6 +39,7 @@ class DumpAllocStats : public ResourceObj {
   f(SymbolBucket) \
   f(StringHashentry) \
   f(StringBucket) \
+  f(ModulesNatives) \
   f(Other)
 
   enum Type {
@@ -74,6 +75,11 @@ class DumpAllocStats : public ResourceObj {
     _bytes [which][type] += byte_size;
   }
 
+  void record_modules(int byte_size, bool read_only) {
+    int which = (read_only) ? RO : RW;
+    _bytes [which][ModulesNativesType] += byte_size;
+  }
+
   void record_other_type(int byte_size, bool read_only) {
     int which = (read_only) ? RO : RW;
     _bytes [which][OtherType] += byte_size;
diff --git a/src/hotspot/share/memory/filemap.cpp b/src/hotspot/share/memory/filemap.cpp
index a0ac1871c64..5137b823d6b 100644
--- a/src/hotspot/share/memory/filemap.cpp
+++ b/src/hotspot/share/memory/filemap.cpp
@@ -50,6 +50,7 @@
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiExport.hpp"
 #include "runtime/arguments.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/os.inline.hpp"
@@ -218,6 +219,7 @@ void FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
   _max_heap_size = MaxHeapSize;
   _narrow_klass_shift = CompressedKlassPointers::shift();
   _use_optimized_module_handling = MetaspaceShared::use_optimized_module_handling();
+  _use_full_module_graph = MetaspaceShared::use_full_module_graph();
 
   // The following fields are for sanity checks for whether this archive
   // will function correctly with this JVM and the bootclasspath it's
@@ -1845,6 +1847,7 @@ void FileMapInfo::map_heap_regions() {
 
   if (!HeapShared::open_archive_heap_region_mapped()) {
     assert(open_archive_heap_ranges == NULL && num_open_archive_heap_ranges == 0, "sanity");
+    MetaspaceShared::disable_full_module_graph();
   }
 }
 
@@ -2179,7 +2182,12 @@ bool FileMapHeader::validate() {
 
   if (!_use_optimized_module_handling) {
     MetaspaceShared::disable_optimized_module_handling();
-    log_info(cds)("use_optimized_module_handling disabled: archive was created without optimized module handling");
+    log_info(cds)("optimized module handling: disabled because archive was created without optimized module handling");
+  }
+
+  if (!_use_full_module_graph) {
+    MetaspaceShared::disable_full_module_graph();
+    log_info(cds)("full module graph: disabled because archive was created without full module graph");
   }
 
   return true;
diff --git a/src/hotspot/share/memory/filemap.hpp b/src/hotspot/share/memory/filemap.hpp
index f3d0e2b4744..841cbd11b1b 100644
--- a/src/hotspot/share/memory/filemap.hpp
+++ b/src/hotspot/share/memory/filemap.hpp
@@ -233,6 +233,7 @@ class FileMapHeader: private CDSFileMapHeaderBase {
   bool   _allow_archiving_with_java_agent; // setting of the AllowArchivingWithJavaAgent option
   bool   _use_optimized_module_handling;// No module-relation VM options were specified, so we can skip
                                         // some expensive operations.
+  bool   _use_full_module_graph;        // Can we use the full archived module graph?
   size_t _ptrmap_size_in_bits;          // Size of pointer relocation bitmap
 
   char* from_mapped_offset(size_t offset) const {
diff --git a/src/hotspot/share/memory/heapShared.cpp b/src/hotspot/share/memory/heapShared.cpp
index 6aaae27e184..dfd398db138 100644
--- a/src/hotspot/share/memory/heapShared.cpp
+++ b/src/hotspot/share/memory/heapShared.cpp
@@ -23,9 +23,13 @@
  */
 
 #include "precompiled.hpp"
+#include "classfile/classLoaderData.hpp"
+#include "classfile/classLoaderDataShared.hpp"
 #include "classfile/javaClasses.inline.hpp"
+#include "classfile/moduleEntry.hpp"
 #include "classfile/stringTable.hpp"
 #include "classfile/symbolTable.hpp"
+#include "classfile/systemDictionary.hpp"
 #include "classfile/systemDictionaryShared.hpp"
 #include "classfile/vmSymbols.hpp"
 #include "gc/shared/gcLocker.hpp"
@@ -45,6 +49,7 @@
 #include "oops/fieldStreams.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/fieldDescriptor.inline.hpp"
+#include "runtime/javaCalls.hpp"
 #include "runtime/safepointVerifiers.hpp"
 #include "utilities/bitMap.inline.hpp"
 #if INCLUDE_G1GC
@@ -68,26 +73,35 @@ DumpedInternedStrings *HeapShared::_dumped_interned_strings = NULL;
 // region. Warning: Objects in the subgraphs should not have reference fields
 // assigned at runtime.
 static ArchivableStaticFieldInfo closed_archive_subgraph_entry_fields[] = {
-  {"java/lang/Integer$IntegerCache",           "archivedCache"},
-  {"java/lang/Long$LongCache",                 "archivedCache"},
-  {"java/lang/Byte$ByteCache",                 "archivedCache"},
-  {"java/lang/Short$ShortCache",               "archivedCache"},
-  {"java/lang/Character$CharacterCache",       "archivedCache"},
-  {"java/util/jar/Attributes$Name",            "KNOWN_NAMES"},
-  {"sun/util/locale/BaseLocale",               "constantBaseLocales"},
+  {"java/lang/Integer$IntegerCache",              "archivedCache"},
+  {"java/lang/Long$LongCache",                    "archivedCache"},
+  {"java/lang/Byte$ByteCache",                    "archivedCache"},
+  {"java/lang/Short$ShortCache",                  "archivedCache"},
+  {"java/lang/Character$CharacterCache",          "archivedCache"},
+  {"java/util/jar/Attributes$Name",               "KNOWN_NAMES"},
+  {"sun/util/locale/BaseLocale",                  "constantBaseLocales"},
 };
 // Entry fields for subgraphs archived in the open archive heap region.
 static ArchivableStaticFieldInfo open_archive_subgraph_entry_fields[] = {
-  {"jdk/internal/module/ArchivedModuleGraph",  "archivedModuleGraph"},
-  {"java/util/ImmutableCollections",           "archivedObjects"},
-  {"java/lang/module/Configuration",           "EMPTY_CONFIGURATION"},
-  {"jdk/internal/math/FDBigInteger",           "archivedCaches"},
+  {"jdk/internal/module/ArchivedModuleGraph",     "archivedModuleGraph"},
+  {"java/util/ImmutableCollections",              "archivedObjects"},
+  {"java/lang/module/Configuration",              "EMPTY_CONFIGURATION"},
+  {"jdk/internal/math/FDBigInteger",              "archivedCaches"},
+};
+
+// Entry fields for subgraphs archived in the open archive heap region (full module graph).
+static ArchivableStaticFieldInfo fmg_open_archive_subgraph_entry_fields[] = {
+  {"jdk/internal/loader/ArchivedClassLoaders",    "archivedClassLoaders"},
+  {"jdk/internal/module/ArchivedBootLayer",       "archivedBootLayer"},
+  {"java/lang/Module$ArchivedData",               "archivedData"},
 };
 
 const static int num_closed_archive_subgraph_entry_fields =
   sizeof(closed_archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo);
 const static int num_open_archive_subgraph_entry_fields =
   sizeof(open_archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo);
+const static int num_fmg_open_archive_subgraph_entry_fields =
+  sizeof(fmg_open_archive_subgraph_entry_fields) / sizeof(ArchivableStaticFieldInfo);
 
 ////////////////////////////////////////////////////////////////
 //
@@ -108,6 +122,36 @@ unsigned HeapShared::oop_hash(oop const& p) {
   return hash;
 }
 
+static void reset_states(oop obj, TRAPS) {
+  Handle h_obj(THREAD, obj);
+  InstanceKlass* klass = InstanceKlass::cast(obj->klass());
+  TempNewSymbol method_name = SymbolTable::new_symbol("resetArchivedStates");
+  Symbol* method_sig = vmSymbols::void_method_signature();
+
+  while (klass != NULL) {
+    Method* method = klass->find_method(method_name, method_sig);
+    if (method != NULL) {
+      assert(method->is_private(), "must be");
+      if (log_is_enabled(Debug, cds)) {
+        ResourceMark rm(THREAD);
+        log_debug(cds)("  calling %s", method->name_and_sig_as_C_string());
+      }
+      JavaValue result(T_VOID);
+      JavaCalls::call_special(&result, h_obj, klass,
+                              method_name, method_sig, CHECK);
+    }
+    klass = klass->java_super();
+  }
+}
+
+void HeapShared::reset_archived_object_states(TRAPS) {
+  assert(DumpSharedSpaces, "dump-time only");
+  log_debug(cds)("Resetting platform loader");
+  reset_states(SystemDictionary::java_platform_loader(), THREAD);
+  log_debug(cds)("Resetting system loader");
+  reset_states(SystemDictionary::java_system_loader(), THREAD);
+}
+
 HeapShared::ArchivedObjectCache* HeapShared::_archived_object_cache = NULL;
 oop HeapShared::find_archived_heap_object(oop obj) {
   assert(DumpSharedSpaces, "dump-time only");
@@ -238,6 +282,10 @@ void HeapShared::archive_java_heap_objects(GrowableArray<MemRegion> *closed,
     log_info(cds)("Dumping objects to open archive heap region ...");
     copy_open_archive_heap_objects(open);
 
+    if (MetaspaceShared::use_full_module_graph()) {
+      ClassLoaderDataShared::init_archived_oops();
+    }
+
     destroy_archived_object_cache();
   }
 
@@ -256,7 +304,9 @@ void HeapShared::copy_closed_archive_heap_objects(
 
   archive_object_subgraphs(closed_archive_subgraph_entry_fields,
                            num_closed_archive_subgraph_entry_fields,
-                           true /* is_closed_archive */, THREAD);
+                           true /* is_closed_archive */,
+                           false /* is_full_module_graph */,
+                           THREAD);
 
   G1CollectedHeap::heap()->end_archive_alloc_range(closed_archive,
                                                    os::vm_allocation_granularity());
@@ -276,7 +326,15 @@ void HeapShared::copy_open_archive_heap_objects(
   archive_object_subgraphs(open_archive_subgraph_entry_fields,
                            num_open_archive_subgraph_entry_fields,
                            false /* is_closed_archive */,
+                           false /* is_full_module_graph */,
                            THREAD);
+  if (MetaspaceShared::use_full_module_graph()) {
+    archive_object_subgraphs(fmg_open_archive_subgraph_entry_fields,
+                             num_fmg_open_archive_subgraph_entry_fields,
+                             false /* is_closed_archive */,
+                             true /* is_full_module_graph */,
+                             THREAD);
+  }
 
   G1CollectedHeap::heap()->end_archive_alloc_range(open_archive,
                                                    os::vm_allocation_granularity());
@@ -296,15 +354,22 @@ HeapShared::RunTimeKlassSubGraphInfoTable   HeapShared::_run_time_subgraph_info_
 // Get the subgraph_info for Klass k. A new subgraph_info is created if
 // there is no existing one for k. The subgraph_info records the relocated
 // Klass* of the original k.
+KlassSubGraphInfo* HeapShared::init_subgraph_info(Klass* k, bool is_full_module_graph) {
+  assert(DumpSharedSpaces, "dump time only");
+  bool created;
+  Klass* relocated_k = MetaspaceShared::get_relocated_klass(k);
+  KlassSubGraphInfo* info =
+    _dump_time_subgraph_info_table->put_if_absent(relocated_k, KlassSubGraphInfo(relocated_k, is_full_module_graph),
+                                                  &created);
+  assert(created, "must not initialize twice");
+  return info;
+}
+
 KlassSubGraphInfo* HeapShared::get_subgraph_info(Klass* k) {
   assert(DumpSharedSpaces, "dump time only");
   Klass* relocated_k = MetaspaceShared::get_relocated_klass(k);
   KlassSubGraphInfo* info = _dump_time_subgraph_info_table->get(relocated_k);
-  if (info == NULL) {
-    _dump_time_subgraph_info_table->put(relocated_k, KlassSubGraphInfo(relocated_k));
-    info = _dump_time_subgraph_info_table->get(relocated_k);
-    ++ _dump_time_subgraph_info_table->_count;
-  }
+  assert(info != NULL, "must have been initialized");
   return info;
 }
 
@@ -384,6 +449,7 @@ void ArchivedKlassSubGraphInfoRecord::init(KlassSubGraphInfo* info) {
   _k = info->klass();
   _entry_field_records = NULL;
   _subgraph_object_klasses = NULL;
+  _is_full_module_graph = info->is_full_module_graph();
 
   // populate the entry fields
   GrowableArray<juint>* entry_fields = info->subgraph_entry_fields();
@@ -464,7 +530,7 @@ void HeapShared::serialize_subgraph_info_table_header(SerializeClosure* soc) {
   _run_time_subgraph_info_table.serialize_header(soc);
 }
 
-void HeapShared::initialize_from_archived_subgraph(Klass* k) {
+void HeapShared::initialize_from_archived_subgraph(Klass* k, TRAPS) {
   if (!open_archive_heap_region_mapped()) {
     return; // nothing to do
   }
@@ -476,7 +542,9 @@ void HeapShared::initialize_from_archived_subgraph(Klass* k) {
   // Initialize from archived data. Currently this is done only
   // during VM initialization time. No lock is needed.
   if (record != NULL) {
-    Thread* THREAD = Thread::current();
+    if (record->is_full_module_graph() && !MetaspaceShared::use_full_module_graph()) {
+      return;
+    }
 
     int i;
     // Load/link/initialize the klasses of the objects in the subgraph.
@@ -628,6 +696,25 @@ void HeapShared::check_closed_archive_heap_region_object(InstanceKlass* k,
   }
 }
 
+void HeapShared::check_module_oop(oop orig_module_obj) {
+  assert(DumpSharedSpaces, "must be");
+  assert(java_lang_Module::is_instance(orig_module_obj), "must be");
+  ModuleEntry* orig_module_ent = java_lang_Module::module_entry_raw(orig_module_obj);
+  if (orig_module_ent == NULL) {
+    // These special Module objects are created in Java code. They are not
+    // defined via Modules::define_module(), so they don't have a ModuleEntry:
+    //     java.lang.Module::ALL_UNNAMED_MODULE
+    //     java.lang.Module::EVERYONE_MODULE
+    //     jdk.internal.loader.ClassLoaders$BootClassLoader::unnamedModule
+    assert(java_lang_Module::name(orig_module_obj) == NULL, "must be unnamed");
+    log_info(cds, heap)("Module oop with No ModuleEntry* @[" PTR_FORMAT "]", p2i(orig_module_obj));
+  } else {
+    ClassLoaderData* loader_data = orig_module_ent->loader_data();
+    assert(loader_data->is_builtin_class_loader_data(), "must be");
+  }
+}
+
+
 // (1) If orig_obj has not been archived yet, archive it.
 // (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called),
 //     trace all  objects that are reachable from it, and make sure these objects are archived.
@@ -695,6 +782,18 @@ oop HeapShared::archive_reachable_objects_from(int level,
         vm_exit(1);
       }
     }
+
+    if (java_lang_Module::is_instance(orig_obj)) {
+      check_module_oop(orig_obj);
+      java_lang_Module::set_module_entry(archived_obj, NULL);
+      java_lang_Module::set_loader(archived_obj, NULL);
+    } else if (java_lang_ClassLoader::is_instance(orig_obj)) {
+      // class_data will be restored explicitly at run time.
+      guarantee(orig_obj == SystemDictionary::java_platform_loader() ||
+                orig_obj == SystemDictionary::java_system_loader() ||
+                java_lang_ClassLoader::loader_data_raw(orig_obj) == NULL, "must be");
+      java_lang_ClassLoader::release_set_loader_data(archived_obj, NULL);
+    }
   }
 
   assert(archived_obj != NULL, "must be");
@@ -881,8 +980,9 @@ void HeapShared::set_has_been_seen_during_subgraph_recording(oop obj) {
   ++ _num_new_walked_objs;
 }
 
-void HeapShared::start_recording_subgraph(InstanceKlass *k, const char* class_name) {
+void HeapShared::start_recording_subgraph(InstanceKlass *k, const char* class_name, bool is_full_module_graph) {
   log_info(cds, heap)("Start recording subgraph(s) for archived fields in %s", class_name);
+  init_subgraph_info(k, is_full_module_graph);
   init_seen_objects_table();
   _num_new_walked_objs = 0;
   _num_new_archived_objs = 0;
@@ -959,6 +1059,11 @@ void HeapShared::init_subgraph_entry_fields(Thread* THREAD) {
   init_subgraph_entry_fields(open_archive_subgraph_entry_fields,
                              num_open_archive_subgraph_entry_fields,
                              THREAD);
+  if (MetaspaceShared::use_full_module_graph()) {
+    init_subgraph_entry_fields(fmg_open_archive_subgraph_entry_fields,
+                               num_fmg_open_archive_subgraph_entry_fields,
+                               THREAD);
+  }
 }
 
 void HeapShared::init_for_dumping(Thread* THREAD) {
@@ -968,6 +1073,7 @@ void HeapShared::init_for_dumping(Thread* THREAD) {
 
 void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
                                           int num, bool is_closed_archive,
+                                          bool is_full_module_graph,
                                           Thread* THREAD) {
   _num_total_subgraph_recordings = 0;
   _num_total_walked_objs = 0;
@@ -985,7 +1091,7 @@ void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
   for (i = 0; i < num; ) {
     ArchivableStaticFieldInfo* info = &fields[i];
     const char* klass_name = info->klass_name;
-    start_recording_subgraph(info->klass, klass_name);
+    start_recording_subgraph(info->klass, klass_name, is_full_module_graph);
 
     // If you have specified consecutive fields of the same klass in
     // fields[], these will be archived in the same
@@ -996,6 +1102,7 @@ void HeapShared::archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
       if (f->klass_name != klass_name) {
         break;
       }
+
       archive_reachable_objects_from_static_field(f->klass, f->klass_name,
                                                   f->offset, f->field_name,
                                                   is_closed_archive, CHECK);
diff --git a/src/hotspot/share/memory/heapShared.hpp b/src/hotspot/share/memory/heapShared.hpp
index 40e37865d20..e0a827efe4e 100644
--- a/src/hotspot/share/memory/heapShared.hpp
+++ b/src/hotspot/share/memory/heapShared.hpp
@@ -66,10 +66,12 @@ class KlassSubGraphInfo: public CHeapObj<mtClass> {
   // is_closed_archive flag.
   GrowableArray<juint>*  _subgraph_entry_fields;
 
+  bool _is_full_module_graph;
  public:
-  KlassSubGraphInfo(Klass* k) :
+  KlassSubGraphInfo(Klass* k, bool is_full_module_graph) :
     _k(k),  _subgraph_object_klasses(NULL),
-    _subgraph_entry_fields(NULL) {}
+    _subgraph_entry_fields(NULL),
+    _is_full_module_graph(is_full_module_graph) {}
   ~KlassSubGraphInfo() {
     if (_subgraph_object_klasses != NULL) {
       delete _subgraph_object_klasses;
@@ -93,6 +95,7 @@ class KlassSubGraphInfo: public CHeapObj<mtClass> {
     return _subgraph_object_klasses == NULL ? 0 :
            _subgraph_object_klasses->length();
   }
+  bool is_full_module_graph() const { return _is_full_module_graph; }
 };
 
 // An archived record of object sub-graphs reachable from static
@@ -101,6 +104,7 @@ class KlassSubGraphInfo: public CHeapObj<mtClass> {
 class ArchivedKlassSubGraphInfoRecord {
  private:
   Klass* _k;
+  bool _is_full_module_graph;
 
   // contains pairs of field offset and value for each subgraph entry field
   Array<juint>* _entry_field_records;
@@ -115,6 +119,7 @@ class ArchivedKlassSubGraphInfoRecord {
   Klass* klass() const { return _k; }
   Array<juint>*  entry_field_records() const { return _entry_field_records; }
   Array<Klass*>* subgraph_object_klasses() const { return _subgraph_object_klasses; }
+  bool is_full_module_graph() const { return _is_full_module_graph; }
 };
 #endif // INCLUDE_CDS_JAVA_HEAP
 
@@ -186,6 +191,7 @@ class HeapShared: AllStatic {
   static void archive_object_subgraphs(ArchivableStaticFieldInfo fields[],
                                        int num,
                                        bool is_closed_archive,
+                                       bool is_full_module_graph,
                                        Thread* THREAD);
 
   // Archive object sub-graph starting from the given static field
@@ -200,6 +206,7 @@ class HeapShared: AllStatic {
   static void verify_reachable_objects_from(oop obj, bool is_archived) PRODUCT_RETURN;
   static void verify_subgraph_from(oop orig_obj) PRODUCT_RETURN;
 
+  static KlassSubGraphInfo* init_subgraph_info(Klass *k, bool is_full_module_graph);
   static KlassSubGraphInfo* get_subgraph_info(Klass *k);
 
   static void init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[],
@@ -239,13 +246,17 @@ class HeapShared: AllStatic {
   static int _num_total_recorded_klasses;
   static int _num_total_verifications;
 
-  static void start_recording_subgraph(InstanceKlass *k, const char* klass_name);
+  static void start_recording_subgraph(InstanceKlass *k, const char* klass_name,
+                                       bool is_full_module_graph);
   static void done_recording_subgraph(InstanceKlass *k, const char* klass_name);
 
   static bool has_been_seen_during_subgraph_recording(oop obj);
   static void set_has_been_seen_during_subgraph_recording(oop obj);
 
+  static void check_module_oop(oop orig_module_obj);
+
  public:
+  static void reset_archived_object_states(TRAPS);
   static void create_archived_object_cache() {
     _archived_object_cache =
       new (ResourceObj::C_HEAP, mtClass)ArchivedObjectCache();
@@ -321,7 +332,7 @@ class HeapShared: AllStatic {
 
   inline static bool is_archived_object(oop p) NOT_CDS_JAVA_HEAP_RETURN_(false);
 
-  static void initialize_from_archived_subgraph(Klass* k) NOT_CDS_JAVA_HEAP_RETURN;
+  static void initialize_from_archived_subgraph(Klass* k, TRAPS) NOT_CDS_JAVA_HEAP_RETURN;
 
   // NarrowOops stored in the CDS archive may use a different encoding scheme
   // than CompressedOops::{base,shift} -- see FileMapInfo::map_heap_regions_impl.
diff --git a/src/hotspot/share/memory/metaspace.cpp b/src/hotspot/share/memory/metaspace.cpp
index 9f5a36bbdf9..bf8a21f40ca 100644
--- a/src/hotspot/share/memory/metaspace.cpp
+++ b/src/hotspot/share/memory/metaspace.cpp
@@ -42,6 +42,7 @@
 #include "oops/compressedOops.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/init.hpp"
 #include "services/memTracker.hpp"
 #include "utilities/copy.hpp"
diff --git a/src/hotspot/share/memory/metaspaceShared.cpp b/src/hotspot/share/memory/metaspaceShared.cpp
index d2a20447c3f..c80e1b108b9 100644
--- a/src/hotspot/share/memory/metaspaceShared.cpp
+++ b/src/hotspot/share/memory/metaspaceShared.cpp
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/classLoaderDataGraph.hpp"
+#include "classfile/classLoaderDataShared.hpp"
 #include "classfile/classListParser.hpp"
 #include "classfile/classLoaderExt.hpp"
 #include "classfile/loaderConstraints.hpp"
@@ -40,6 +41,8 @@
 #include "logging/logMessage.hpp"
 #include "memory/archiveBuilder.hpp"
 #include "memory/archiveUtils.inline.hpp"
+#include "memory/cppVtables.hpp"
+#include "memory/dumpAllocStats.hpp"
 #include "memory/dynamicArchive.hpp"
 #include "memory/filemap.hpp"
 #include "memory/heapShared.inline.hpp"
@@ -49,15 +52,10 @@
 #include "memory/resourceArea.hpp"
 #include "memory/universe.hpp"
 #include "oops/compressedOops.inline.hpp"
-#include "oops/instanceClassLoaderKlass.hpp"
 #include "oops/instanceMirrorKlass.hpp"
-#include "oops/instanceRefKlass.hpp"
-#include "oops/methodData.hpp"
-#include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
 #include "oops/oopHandle.hpp"
-#include "oops/typeArrayKlass.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/os.hpp"
 #include "runtime/safepointVerifiers.hpp"
@@ -87,6 +85,7 @@ void* MetaspaceShared::_shared_metaspace_static_top = NULL;
 intx MetaspaceShared::_relocation_delta;
 char* MetaspaceShared::_requested_base_address;
 bool MetaspaceShared::_use_optimized_module_handling = true;
+bool MetaspaceShared::_use_full_module_graph = true;
 
 // The CDS archive is divided into the following regions:
 //     mc  - misc code (the method entry trampolines, c++ vtables)
@@ -151,6 +150,10 @@ char* MetaspaceShared::read_only_space_alloc(size_t num_bytes) {
   return _ro_region.allocate(num_bytes);
 }
 
+char* MetaspaceShared::read_write_space_alloc(size_t num_bytes) {
+  return _rw_region.allocate(num_bytes);
+}
+
 size_t MetaspaceShared::reserved_space_alignment() { return os::vm_allocation_granularity(); }
 
 static bool shared_base_valid(char* shared_base) {
@@ -497,9 +500,11 @@ void MetaspaceShared::serialize(SerializeClosure* soc) {
   SystemDictionaryShared::serialize_well_known_klasses(soc);
   soc->do_tag(--tag);
 
-  serialize_cloned_cpp_vtptrs(soc);
+  CppVtables::serialize_cloned_cpp_vtptrs(soc);
   soc->do_tag(--tag);
 
+  CDS_JAVA_HEAP_ONLY(ClassLoaderDataShared::serialize(soc));
+
   soc->do_tag(666);
 }
 
@@ -607,297 +612,6 @@ void MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread
   }
 }
 
-// Objects of the Metadata types (such as Klass and ConstantPool) have C++ vtables.
-// (In GCC this is the field <Type>::_vptr, i.e., first word in the object.)
-//
-// Addresses of the vtables and the methods may be different across JVM runs,
-// if libjvm.so is dynamically loaded at a different base address.
-//
-// To ensure that the Metadata objects in the CDS archive always have the correct vtable:
-//
-// + at dump time:  we redirect the _vptr to point to our own vtables inside
-//                  the CDS image
-// + at run time:   we clone the actual contents of the vtables from libjvm.so
-//                  into our own tables.
-
-// Currently, the archive contain ONLY the following types of objects that have C++ vtables.
-#define CPP_VTABLE_PATCH_TYPES_DO(f) \
-  f(ConstantPool) \
-  f(InstanceKlass) \
-  f(InstanceClassLoaderKlass) \
-  f(InstanceMirrorKlass) \
-  f(InstanceRefKlass) \
-  f(Method) \
-  f(ObjArrayKlass) \
-  f(TypeArrayKlass)
-
-class CppVtableInfo {
-  intptr_t _vtable_size;
-  intptr_t _cloned_vtable[1];
-public:
-  static int num_slots(int vtable_size) {
-    return 1 + vtable_size; // Need to add the space occupied by _vtable_size;
-  }
-  int vtable_size()           { return int(uintx(_vtable_size)); }
-  void set_vtable_size(int n) { _vtable_size = intptr_t(n); }
-  intptr_t* cloned_vtable()   { return &_cloned_vtable[0]; }
-  void zero()                 { memset(_cloned_vtable, 0, sizeof(intptr_t) * vtable_size()); }
-  // Returns the address of the next CppVtableInfo that can be placed immediately after this CppVtableInfo
-  static size_t byte_size(int vtable_size) {
-    CppVtableInfo i;
-    return pointer_delta(&i._cloned_vtable[vtable_size], &i, sizeof(u1));
-  }
-};
-
-static inline intptr_t* vtable_of(Metadata* m) {
-  return *((intptr_t**)m);
-}
-
-template <class T> class CppVtableCloner : public T {
-  static CppVtableInfo* _info;
-
-  static int get_vtable_length(const char* name);
-
-public:
-  // Allocate and initialize the C++ vtable, starting from top, but do not go past end.
-  static intptr_t* allocate(const char* name);
-
-  // Clone the vtable to ...
-  static intptr_t* clone_vtable(const char* name, CppVtableInfo* info);
-
-  static void zero_vtable_clone() {
-    assert(DumpSharedSpaces, "dump-time only");
-    _info->zero();
-  }
-
-  static bool is_valid_shared_object(const T* obj) {
-    intptr_t* vptr = *(intptr_t**)obj;
-    return vptr == _info->cloned_vtable();
-  }
-
-  static void init_orig_cpp_vtptr(int kind);
-};
-
-template <class T> CppVtableInfo* CppVtableCloner<T>::_info = NULL;
-
-template <class T>
-intptr_t* CppVtableCloner<T>::allocate(const char* name) {
-  assert(is_aligned(_mc_region.top(), sizeof(intptr_t)), "bad alignment");
-  int n = get_vtable_length(name);
-  _info = (CppVtableInfo*)_mc_region.allocate(CppVtableInfo::byte_size(n), sizeof(intptr_t));
-  _info->set_vtable_size(n);
-
-  intptr_t* p = clone_vtable(name, _info);
-  assert((char*)p == _mc_region.top(), "must be");
-
-  return _info->cloned_vtable();
-}
-
-template <class T>
-intptr_t* CppVtableCloner<T>::clone_vtable(const char* name, CppVtableInfo* info) {
-  if (!DumpSharedSpaces) {
-    assert(_info == 0, "_info is initialized only at dump time");
-    _info = info; // Remember it -- it will be used by MetaspaceShared::is_valid_shared_method()
-  }
-  T tmp; // Allocate temporary dummy metadata object to get to the original vtable.
-  int n = info->vtable_size();
-  intptr_t* srcvtable = vtable_of(&tmp);
-  intptr_t* dstvtable = info->cloned_vtable();
-
-  // We already checked (and, if necessary, adjusted n) when the vtables were allocated, so we are
-  // safe to do memcpy.
-  log_debug(cds, vtables)("Copying %3d vtable entries for %s", n, name);
-  memcpy(dstvtable, srcvtable, sizeof(intptr_t) * n);
-  return dstvtable + n;
-}
-
-// To determine the size of the vtable for each type, we use the following
-// trick by declaring 2 subclasses:
-//
-//   class CppVtableTesterA: public InstanceKlass {virtual int   last_virtual_method() {return 1;}    };
-//   class CppVtableTesterB: public InstanceKlass {virtual void* last_virtual_method() {return NULL}; };
-//
-// CppVtableTesterA and CppVtableTesterB's vtables have the following properties:
-// - Their size (N+1) is exactly one more than the size of InstanceKlass's vtable (N)
-// - The first N entries have are exactly the same as in InstanceKlass's vtable.
-// - Their last entry is different.
-//
-// So to determine the value of N, we just walk CppVtableTesterA and CppVtableTesterB's tables
-// and find the first entry that's different.
-//
-// This works on all C++ compilers supported by Oracle, but you may need to tweak it for more
-// esoteric compilers.
-
-template <class T> class CppVtableTesterB: public T {
-public:
-  virtual int last_virtual_method() {return 1;}
-};
-
-template <class T> class CppVtableTesterA : public T {
-public:
-  virtual void* last_virtual_method() {
-    // Make this different than CppVtableTesterB::last_virtual_method so the C++
-    // compiler/linker won't alias the two functions.
-    return NULL;
-  }
-};
-
-template <class T>
-int CppVtableCloner<T>::get_vtable_length(const char* name) {
-  CppVtableTesterA<T> a;
-  CppVtableTesterB<T> b;
-
-  intptr_t* avtable = vtable_of(&a);
-  intptr_t* bvtable = vtable_of(&b);
-
-  // Start at slot 1, because slot 0 may be RTTI (on Solaris/Sparc)
-  int vtable_len = 1;
-  for (; ; vtable_len++) {
-    if (avtable[vtable_len] != bvtable[vtable_len]) {
-      break;
-    }
-  }
-  log_debug(cds, vtables)("Found   %3d vtable entries for %s", vtable_len, name);
-
-  return vtable_len;
-}
-
-#define ALLOC_CPP_VTABLE_CLONE(c) \
-  _cloned_cpp_vtptrs[c##_Kind] = CppVtableCloner<c>::allocate(#c); \
-  ArchivePtrMarker::mark_pointer(&_cloned_cpp_vtptrs[c##_Kind]);
-
-#define CLONE_CPP_VTABLE(c) \
-  p = CppVtableCloner<c>::clone_vtable(#c, (CppVtableInfo*)p);
-
-#define ZERO_CPP_VTABLE(c) \
- CppVtableCloner<c>::zero_vtable_clone();
-
-#define INIT_ORIG_CPP_VTPTRS(c) \
-  CppVtableCloner<c>::init_orig_cpp_vtptr(c##_Kind);
-
-#define DECLARE_CLONED_VTABLE_KIND(c) c ## _Kind,
-
-enum ClonedVtableKind {
-  // E.g., ConstantPool_Kind == 0, InstanceKlass_Kind == 1, etc.
-  CPP_VTABLE_PATCH_TYPES_DO(DECLARE_CLONED_VTABLE_KIND)
-  _num_cloned_vtable_kinds
-};
-
-// This is a map of all the original vtptrs. E.g., for
-//     ConstantPool *cp = new (...) ConstantPool(...) ; // a dynamically allocated constant pool
-// the following holds true:
-//     _orig_cpp_vtptrs[ConstantPool_Kind] ==  ((intptr_t**)cp)[0]
-static intptr_t* _orig_cpp_vtptrs[_num_cloned_vtable_kinds];
-static bool _orig_cpp_vtptrs_inited = false;
-
-template <class T>
-void CppVtableCloner<T>::init_orig_cpp_vtptr(int kind) {
-  assert(kind < _num_cloned_vtable_kinds, "sanity");
-  T tmp; // Allocate temporary dummy metadata object to get to the original vtable.
-  intptr_t* srcvtable = vtable_of(&tmp);
-  _orig_cpp_vtptrs[kind] = srcvtable;
-}
-
-// This is the index of all the cloned vtables. E.g., for
-//     ConstantPool* cp = ....; // an archived constant pool
-//     InstanceKlass* ik = ....;// an archived class
-// the following holds true:
-//     _cloned_cpp_vtptrs[ConstantPool_Kind]  == ((intptr_t**)cp)[0]
-//     _cloned_cpp_vtptrs[InstanceKlass_Kind] == ((intptr_t**)ik)[0]
-static intptr_t** _cloned_cpp_vtptrs = NULL;
-
-void MetaspaceShared::allocate_cloned_cpp_vtptrs() {
-  assert(DumpSharedSpaces, "must");
-  size_t vtptrs_bytes = _num_cloned_vtable_kinds * sizeof(intptr_t*);
-  _cloned_cpp_vtptrs = (intptr_t**)_mc_region.allocate(vtptrs_bytes, sizeof(intptr_t*));
-}
-
-void MetaspaceShared::serialize_cloned_cpp_vtptrs(SerializeClosure* soc) {
-  soc->do_ptr((void**)&_cloned_cpp_vtptrs);
-}
-
-intptr_t* MetaspaceShared::get_archived_cpp_vtable(MetaspaceObj::Type msotype, address obj) {
-  if (!_orig_cpp_vtptrs_inited) {
-    CPP_VTABLE_PATCH_TYPES_DO(INIT_ORIG_CPP_VTPTRS);
-    _orig_cpp_vtptrs_inited = true;
-  }
-
-  Arguments::assert_is_dumping_archive();
-  int kind = -1;
-  switch (msotype) {
-  case MetaspaceObj::SymbolType:
-  case MetaspaceObj::TypeArrayU1Type:
-  case MetaspaceObj::TypeArrayU2Type:
-  case MetaspaceObj::TypeArrayU4Type:
-  case MetaspaceObj::TypeArrayU8Type:
-  case MetaspaceObj::TypeArrayOtherType:
-  case MetaspaceObj::ConstMethodType:
-  case MetaspaceObj::ConstantPoolCacheType:
-  case MetaspaceObj::AnnotationsType:
-  case MetaspaceObj::MethodCountersType:
-  case MetaspaceObj::RecordComponentType:
-    // These have no vtables.
-    break;
-  case MetaspaceObj::MethodDataType:
-    // We don't archive MethodData <-- should have been removed in removed_unsharable_info
-    ShouldNotReachHere();
-    break;
-  default:
-    for (kind = 0; kind < _num_cloned_vtable_kinds; kind ++) {
-      if (vtable_of((Metadata*)obj) == _orig_cpp_vtptrs[kind]) {
-        break;
-      }
-    }
-    if (kind >= _num_cloned_vtable_kinds) {
-      fatal("Cannot find C++ vtable for " INTPTR_FORMAT " -- you probably added"
-            " a new subtype of Klass or MetaData without updating CPP_VTABLE_PATCH_TYPES_DO",
-            p2i(obj));
-    }
-  }
-
-  if (kind >= 0) {
-    assert(kind < _num_cloned_vtable_kinds, "must be");
-    return _cloned_cpp_vtptrs[kind];
-  } else {
-    return NULL;
-  }
-}
-
-// This can be called at both dump time and run time:
-// - clone the contents of the c++ vtables into the space
-//   allocated by allocate_cpp_vtable_clones()
-void MetaspaceShared::clone_cpp_vtables(intptr_t* p) {
-  assert(DumpSharedSpaces || UseSharedSpaces, "sanity");
-  CPP_VTABLE_PATCH_TYPES_DO(CLONE_CPP_VTABLE);
-}
-
-void MetaspaceShared::zero_cpp_vtable_clones_for_writing() {
-  assert(DumpSharedSpaces, "dump-time only");
-  CPP_VTABLE_PATCH_TYPES_DO(ZERO_CPP_VTABLE);
-}
-
-// Allocate and initialize the C++ vtables, starting from top, but do not go past end.
-char* MetaspaceShared::allocate_cpp_vtable_clones() {
-  char* cloned_vtables = _mc_region.top(); // This is the beginning of all the cloned vtables
-
-  assert(DumpSharedSpaces, "dump-time only");
-  // Layout (each slot is a intptr_t):
-  //   [number of slots in the first vtable = n1]
-  //   [ <n1> slots for the first vtable]
-  //   [number of slots in the first second = n2]
-  //   [ <n2> slots for the second vtable]
-  //   ...
-  // The order of the vtables is the same as the CPP_VTAB_PATCH_TYPES_DO macro.
-  CPP_VTABLE_PATCH_TYPES_DO(ALLOC_CPP_VTABLE_CLONE);
-
-  return cloned_vtables;
-}
-
-bool MetaspaceShared::is_valid_shared_method(const Method* m) {
-  assert(is_in_shared_metaspace(m), "must be");
-  return CppVtableCloner<Method>::is_valid_shared_object(m);
-}
-
 class VM_PopulateDumpSharedSpace: public VM_Operation {
 private:
   GrowableArray<MemRegion> *_closed_archive_heap_regions;
@@ -1066,14 +780,33 @@ void VM_PopulateDumpSharedSpace::doit() {
 
   builder.gather_source_objs();
 
-  MetaspaceShared::allocate_cloned_cpp_vtptrs();
+  CppVtables::allocate_cloned_cpp_vtptrs();
   char* cloned_vtables = _mc_region.top();
-  MetaspaceShared::allocate_cpp_vtable_clones();
+  CppVtables::allocate_cpp_vtable_clones();
 
-  _mc_region.pack(&_rw_region);
-  builder.dump_rw_region();
-  _rw_region.pack(&_ro_region);
-  builder.dump_ro_region();
+  {
+    _mc_region.pack(&_rw_region);
+    builder.dump_rw_region();
+#if INCLUDE_CDS_JAVA_HEAP
+    if (MetaspaceShared::use_full_module_graph()) {
+      // Archive the ModuleEntry's and PackageEntry's of the 3 built-in loaders
+      char* start = _rw_region.top();
+      ClassLoaderDataShared::allocate_archived_tables();
+      ArchiveBuilder::alloc_stats()->record_modules(_rw_region.top() - start, /*read_only*/false);
+    }
+#endif
+  }
+  {
+    _rw_region.pack(&_ro_region);
+    builder.dump_ro_region();
+#if INCLUDE_CDS_JAVA_HEAP
+    if (MetaspaceShared::use_full_module_graph()) {
+      char* start = _ro_region.top();
+      ClassLoaderDataShared::init_archived_tables();
+      ArchiveBuilder::alloc_stats()->record_modules(_ro_region.top() - start, /*read_only*/true);
+    }
+#endif
+  }
   builder.relocate_pointers();
 
   dump_shared_symbol_table(builder.symbols());
@@ -1090,7 +823,7 @@ void VM_PopulateDumpSharedSpace::doit() {
 
   // The vtable clones contain addresses of the current process.
   // We don't want to write these addresses into the archive. Same for i2i buffer.
-  MetaspaceShared::zero_cpp_vtable_clones_for_writing();
+  CppVtables::zero_cpp_vtable_clones_for_writing();
   memset(MetaspaceShared::i2i_entry_code_buffers(), 0,
          MetaspaceShared::i2i_entry_code_buffers_size());
 
@@ -1356,6 +1089,8 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
 
     HeapShared::init_for_dumping(THREAD);
 
+    // exercise the manifest processing code to ensure classes used by CDS are always archived
+    SystemDictionaryShared::create_jar_manifest("Manifest-Version: 1.0\n", strlen("Manifest-Version: 1.0\n"), THREAD);
     // Rewrite and link classes
     log_info(cds)("Rewriting and linking classes ...");
 
@@ -1366,6 +1101,12 @@ void MetaspaceShared::preload_and_dump(TRAPS) {
     link_and_cleanup_shared_classes(CATCH);
     log_info(cds)("Rewriting and linking classes: done");
 
+#if INCLUDE_CDS_JAVA_HEAP
+    if (use_full_module_graph()) {
+      HeapShared::reset_archived_object_states(THREAD);
+    }
+#endif
+
     VM_PopulateDumpSharedSpace op;
     MutexLocker ml(THREAD, HeapShared::is_heap_object_archiving_allowed() ?
                    Heap_lock : NULL);     // needed by HeapShared::run_gc()
@@ -1747,9 +1488,12 @@ MapArchiveResult MetaspaceShared::map_archives(FileMapInfo* static_mapinfo, File
           // map_heap_regions() compares the current narrow oop and klass encodings
           // with the archived ones, so it must be done after all encodings are determined.
           static_mapinfo->map_heap_regions();
+
+          disable_full_module_graph(); // Disabled temporarily for JDK-8253081
         }
       });
-    log_info(cds)("Using optimized module handling %s", MetaspaceShared::use_optimized_module_handling() ? "enabled" : "disabled");
+    log_info(cds)("optimized module handling: %s", MetaspaceShared::use_optimized_module_handling() ? "enabled" : "disabled");
+    log_info(cds)("full module graph: %s", MetaspaceShared::use_full_module_graph() ? "enabled" : "disabled");
   } else {
     unmap_archive(static_mapinfo);
     unmap_archive(dynamic_mapinfo);
@@ -1991,7 +1735,7 @@ void MetaspaceShared::initialize_shared_spaces() {
   _i2i_entry_code_buffers = static_mapinfo->i2i_entry_code_buffers();
   _i2i_entry_code_buffers_size = static_mapinfo->i2i_entry_code_buffers_size();
   char* buffer = static_mapinfo->cloned_vtables();
-  clone_cpp_vtables((intptr_t*)buffer);
+  CppVtables::clone_cpp_vtables((intptr_t*)buffer);
 
   // Verify various attributes of the archive, plus initialize the
   // shared string/symbol tables
@@ -2074,6 +1818,17 @@ intx MetaspaceShared::final_delta() {
        - intx(SharedBaseAddress);                         // .. but the base archive is mapped at here at dump time
 }
 
+bool MetaspaceShared::use_full_module_graph() {
+  bool result = _use_optimized_module_handling && _use_full_module_graph &&
+    (UseSharedSpaces || DumpSharedSpaces) && HeapShared::is_heap_object_archiving_allowed();
+  if (result && UseSharedSpaces) {
+    // Classes used by the archived full module graph are loaded in JVMTI early phase.
+    assert(!(JvmtiExport::should_post_class_file_load_hook() && JvmtiExport::has_early_class_hook_env()),
+           "CDS should be disabled if early class hooks are enabled");
+  }
+  return result;
+}
+
 void MetaspaceShared::print_on(outputStream* st) {
   if (UseSharedSpaces || DumpSharedSpaces) {
     st->print("CDS archive(s) mapped at: ");
diff --git a/src/hotspot/share/memory/metaspaceShared.hpp b/src/hotspot/share/memory/metaspaceShared.hpp
index b2b65cd7332..8ffd20f5c45 100644
--- a/src/hotspot/share/memory/metaspaceShared.hpp
+++ b/src/hotspot/share/memory/metaspaceShared.hpp
@@ -78,6 +78,7 @@ class MetaspaceShared : AllStatic {
   static intx _relocation_delta;
   static char* _requested_base_address;
   static bool _use_optimized_module_handling;
+  static bool _use_full_module_graph;
  public:
   enum {
     // core archive spaces
@@ -167,13 +168,6 @@ class MetaspaceShared : AllStatic {
 
   static bool is_shared_dynamic(void* p) NOT_CDS_RETURN_(false);
 
-  static char* allocate_cpp_vtable_clones();
-  static void clone_cpp_vtables(intptr_t* p);
-  static void zero_cpp_vtable_clones_for_writing();
-  static void patch_cpp_vtable_pointers();
-  static void serialize_cloned_cpp_vtptrs(SerializeClosure* sc);
-
-  static bool is_valid_shared_method(const Method* m) NOT_CDS_RETURN_(false);
   static void serialize(SerializeClosure* sc) NOT_CDS_RETURN;
 
   static MetaspaceSharedStats* stats() {
@@ -215,17 +209,22 @@ class MetaspaceShared : AllStatic {
   // Allocate a block of memory from the "mc" or "ro" regions.
   static char* misc_code_space_alloc(size_t num_bytes);
   static char* read_only_space_alloc(size_t num_bytes);
+  static char* read_write_space_alloc(size_t num_bytes);
 
   template <typename T>
   static Array<T>* new_ro_array(int length) {
-#if INCLUDE_CDS
     size_t byte_size = Array<T>::byte_sizeof(length, sizeof(T));
     Array<T>* array = (Array<T>*)read_only_space_alloc(byte_size);
     array->initialize(length);
     return array;
-#else
-    return NULL;
-#endif
+  }
+
+  template <typename T>
+  static Array<T>* new_rw_array(int length) {
+    size_t byte_size = Array<T>::byte_sizeof(length, sizeof(T));
+    Array<T>* array = (Array<T>*)read_write_space_alloc(byte_size);
+    array->initialize(length);
+    return array;
   }
 
   template <typename T>
@@ -246,8 +245,6 @@ class MetaspaceShared : AllStatic {
 
   static Klass* get_relocated_klass(Klass *k, bool is_final=false);
 
-  static void allocate_cloned_cpp_vtptrs();
-  static intptr_t* get_archived_cpp_vtable(MetaspaceObj::Type msotype, address obj);
   static void initialize_ptr_marker(CHeapBitMap* ptrmap);
 
   // This is the base address as specified by -XX:SharedBaseAddress during -Xshare:dump.
@@ -270,9 +267,13 @@ class MetaspaceShared : AllStatic {
                                          GrowableArray<ArchiveHeapOopmapInfo>* open_oopmaps);
 
   // Can we skip some expensive operations related to modules?
-  static bool use_optimized_module_handling()     { return _use_optimized_module_handling;  }
+  static bool use_optimized_module_handling() { return NOT_CDS(false) CDS_ONLY(_use_optimized_module_handling); }
   static void disable_optimized_module_handling() { _use_optimized_module_handling = false; }
 
+  // Can we use the full archived modue graph?
+  static bool use_full_module_graph() NOT_CDS_RETURN_(false);
+  static void disable_full_module_graph() { _use_full_module_graph = false; }
+
 private:
 #if INCLUDE_CDS
   static void write_region(FileMapInfo* mapinfo, int region_idx, DumpRegion* dump_region,
diff --git a/src/hotspot/share/memory/padded.hpp b/src/hotspot/share/memory/padded.hpp
index c51d1e7a63b..08003613609 100644
--- a/src/hotspot/share/memory/padded.hpp
+++ b/src/hotspot/share/memory/padded.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
 // when the start address is not a multiple of alignment; the second maintains
 // alignment of starting addresses that happen to be a multiple.
 #define PADDING_SIZE(type, alignment)                           \
-  ((alignment) + align_up_(sizeof(type), (alignment)))
+  ((alignment) + align_up(sizeof(type), (alignment)))
 
 // Templates to create a subclass padded to avoid cache line sharing.  These are
 // effective only when applied to derived-most (leaf) classes.
@@ -69,7 +69,7 @@ class PaddedEndImpl<T, /*pad_size*/ 0> : public T {
   // No padding.
 };
 
-#define PADDED_END_SIZE(type, alignment) (align_up_(sizeof(type), (alignment)) - sizeof(type))
+#define PADDED_END_SIZE(type, alignment) (align_up(sizeof(type), (alignment)) - sizeof(type))
 
 // More memory conservative implementation of Padded. The subclass adds the
 // minimal amount of padding needed to make the size of the objects be aligned.
diff --git a/src/hotspot/share/memory/padded.inline.hpp b/src/hotspot/share/memory/padded.inline.hpp
index 939bf7b69db..d698f5ee1b3 100644
--- a/src/hotspot/share/memory/padded.inline.hpp
+++ b/src/hotspot/share/memory/padded.inline.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@
 template <class T, MEMFLAGS flags, size_t alignment>
 PaddedEnd<T>* PaddedArray<T, flags, alignment>::create_unfreeable(uint length) {
   // Check that the PaddedEnd class works as intended.
-  STATIC_ASSERT(is_aligned_(sizeof(PaddedEnd<T>), alignment));
+  STATIC_ASSERT(is_aligned(sizeof(PaddedEnd<T>), alignment));
 
   // Allocate a chunk of memory large enough to allow for some alignment.
   void* chunk = AllocateHeap(length * sizeof(PaddedEnd<T, alignment>) + alignment, flags);
diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp
index 0555dfa04d1..ae2ad7d6e1d 100644
--- a/src/hotspot/share/memory/universe.cpp
+++ b/src/hotspot/share/memory/universe.cpp
@@ -1031,26 +1031,6 @@ void Universe::print_heap_at_SIGBREAK() {
   }
 }
 
-void Universe::print_heap_before_gc() {
-  LogTarget(Debug, gc, heap) lt;
-  if (lt.is_enabled()) {
-    LogStream ls(lt);
-    ls.print("Heap before GC invocations=%u (full %u):", heap()->total_collections(), heap()->total_full_collections());
-    ResourceMark rm;
-    heap()->print_on(&ls);
-  }
-}
-
-void Universe::print_heap_after_gc() {
-  LogTarget(Debug, gc, heap) lt;
-  if (lt.is_enabled()) {
-    LogStream ls(lt);
-    ls.print("Heap after GC invocations=%u (full %u):", heap()->total_collections(), heap()->total_full_collections());
-    ResourceMark rm;
-    heap()->print_on(&ls);
-  }
-}
-
 void Universe::initialize_verify_flags() {
   verify_flags = 0;
   const char delimiter[] = " ,";
diff --git a/src/hotspot/share/memory/universe.hpp b/src/hotspot/share/memory/universe.hpp
index 4d80ec4df41..42b3e635ebb 100644
--- a/src/hotspot/share/memory/universe.hpp
+++ b/src/hotspot/share/memory/universe.hpp
@@ -357,8 +357,6 @@ class Universe: AllStatic {
   static int  verify_count()       { return _verify_count; }
   static void print_on(outputStream* st);
   static void print_heap_at_SIGBREAK();
-  static void print_heap_before_gc();
-  static void print_heap_after_gc();
 
   // Change the number of dummy objects kept reachable by the full gc dummy
   // array; this should trigger relocation in a sliding compaction collector.
diff --git a/src/hotspot/share/memory/virtualspace.cpp b/src/hotspot/share/memory/virtualspace.cpp
index 7f88f0dcf50..cbb1a0427c7 100644
--- a/src/hotspot/share/memory/virtualspace.cpp
+++ b/src/hotspot/share/memory/virtualspace.cpp
@@ -29,6 +29,7 @@
 #include "oops/compressedOops.hpp"
 #include "oops/markWord.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.inline.hpp"
 #include "services/memTracker.hpp"
diff --git a/src/hotspot/share/metaprogramming/primitiveConversions.hpp b/src/hotspot/share/metaprogramming/primitiveConversions.hpp
index 2d9fa6e3dbb..08806442bf4 100644
--- a/src/hotspot/share/metaprogramming/primitiveConversions.hpp
+++ b/src/hotspot/share/metaprogramming/primitiveConversions.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,147 +25,102 @@
 #ifndef SHARE_METAPROGRAMMING_PRIMITIVECONVERSIONS_HPP
 #define SHARE_METAPROGRAMMING_PRIMITIVECONVERSIONS_HPP
 
-#include "memory/allocation.hpp"
+#include "memory/allStatic.hpp"
 #include "metaprogramming/enableIf.hpp"
-#include "metaprogramming/integralConstant.hpp"
-#include "metaprogramming/isFloatingPoint.hpp"
-#include "metaprogramming/isIntegral.hpp"
-#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
 #include <type_traits>
 
 class PrimitiveConversions : public AllStatic {
+
+  // True if types are the same size and either is integral.
+  template<typename To, typename From>
+  static constexpr bool check_cast() {
+    return (sizeof(To) == sizeof(From)) &&
+           (std::is_integral<To>::value || std::is_integral<From>::value);
+  }
+
 public:
-  // Return a value of type T with the same representation as x.
+  // template<typename To, typename From> To cast(From x)
+  //
+  // Return a value of type To with the same value representation as x.
   //
-  // T and U must be of the same size.
+  // To and From must be of the same size.
   //
-  // At least one of T or U must be an integral type.  The other must
-  // be an integral, floating point, or pointer type.
-  template<typename T, typename U> static T cast(U x);
+  // At least one of To or From must be an integral type.  The other must
+  // be an integral, enum, floating point, or pointer type.
+
+  // integer -> integer
+  // Use static_cast for conversion.  See C++14 4.7 Integral
+  // conversions. If To is signed and From unsigned, the result is
+  // implementation-defined.  All supported platforms provide two's
+  // complement behavior, and that behavior is required by C++20.
+  // Using an lvalue to reference cast (see C++03 3.10/15) involves a
+  // reinterpret_cast, which prevents constexpr support.
+  template<typename To, typename From,
+           ENABLE_IF(sizeof(To) == sizeof(From)),
+           ENABLE_IF(std::is_integral<To>::value),
+           ENABLE_IF(std::is_integral<From>::value)>
+  static constexpr To cast(From x) {
+    return static_cast<To>(x);
+  }
+
+  // integer -> enum, enum -> integer
+  // Use the enum's underlying type for integer -> integer cast.
+  template<typename To, typename From,
+           ENABLE_IF(check_cast<To, From>()),
+           ENABLE_IF(std::is_enum<To>::value)>
+  static constexpr To cast(From x) {
+    return static_cast<To>(cast<std::underlying_type_t<To>>(x));
+  }
+
+  template<typename To, typename From,
+           ENABLE_IF(check_cast<To, From>()),
+           ENABLE_IF(std::is_enum<From>::value)>
+  static constexpr To cast(From x) {
+    return cast<To>(static_cast<std::underlying_type_t<From>>(x));
+  }
+
+  // integer -> pointer, pointer -> integer
+  // Use reinterpret_cast, so no constexpr support.
+  template<typename To, typename From,
+           ENABLE_IF(check_cast<To, From>()),
+           ENABLE_IF(std::is_pointer<To>::value || std::is_pointer<From>::value)>
+  static To cast(From x) {
+    return reinterpret_cast<To>(x);
+  }
+
+  // integer -> floating point, floating point -> integer
+  // Use the union trick.  The union trick is technically UB, but is
+  // widely and well supported, producing good code.  In some cases,
+  // such as gcc, that support is explicitly documented.  Using memcpy
+  // is the correct method, but some compilers produce wretched code
+  // for that method, even at maximal optimization levels.  Neither
+  // the union trick nor memcpy provides constexpr support.
+  template<typename To, typename From,
+           ENABLE_IF(check_cast<To, From>()),
+           ENABLE_IF(std::is_floating_point<To>::value ||
+                     std::is_floating_point<From>::value)>
+  static To cast(From x) {
+    union { From from; To to; } converter = { x };
+    return converter.to;
+  }
 
   // Support thin wrappers over primitive types.
-  // If derived from TrueType, provides representational conversion
+  // If derived from std::true_type, provides representational conversion
   // from T to some other type.  When true, must provide
   // - Value: typedef for T.
   // - Decayed: typedef for decayed type.
   // - static Decayed decay(T x): return value of type Decayed with
-  //   the same representation as x.
+  //   the same value representation as x.
   // - static T recover(Decayed x): return a value of type T with the
-  //   same representation as x.
-  template<typename T> struct Translate : public FalseType {};
-
-private:
-
-  template<typename T,
-           typename U,
-           bool same_size = sizeof(T) == sizeof(U),
-           typename Enable = void>
-  struct Cast;
-
-  template<typename T, typename U> static T cast_using_union(U x);
-};
-
-// Return an object of type T with the same value representation as x.
-//
-// T and U must be of the same size.  It is expected that one of T and
-// U is an integral type, and the other is an integral type, an enum type,
-// or a floating point type.
-//
-// This implementation uses the "union trick", which seems to be the
-// best of a bad set of options.  Though technically undefined
-// behavior, it is widely and well supported, producing good code.  In
-// some cases, such as gcc, that support is explicitly documented.
-//
-// Using memcpy is the correct method, but some compilers produce
-// wretched code for that method, even at maximal optimization levels.
-//
-// Using static_cast is only possible for integral and enum types, not
-// for floating point types.  And for integral and enum conversions,
-// static_cast has unspecified or implementation-defined behavior for
-// some cases.  C++11 <type_traits> can be used to avoid most or all
-// of those unspecified or implementation-defined issues, though that
-// may require multi-step conversions.
-//
-// Using reinterpret_cast of references has undefined behavior for
-// many cases, and there is much less empirical basis for its use, as
-// compared to the union trick.
-template<typename T, typename U>
-inline T PrimitiveConversions::cast_using_union(U x) {
-  STATIC_ASSERT(sizeof(T) == sizeof(U));
-  union { T t; U u; };
-  u = x;
-  return t;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// cast<T>(x)
-//
-// Cast<T, U, same_size, Enable>
-
-// Give an informative error if the sizes differ.
-template<typename T, typename U>
-struct PrimitiveConversions::Cast<T, U, false> {
-  STATIC_ASSERT(sizeof(T) == sizeof(U));
-};
-
-// Conversion between integral types.
-template<typename T, typename U>
-struct PrimitiveConversions::Cast<
-  T, U, true,
-  typename EnableIf<IsIntegral<T>::value && IsIntegral<U>::value>::type>
-{
-  T operator()(U x) const { return cast_using_union<T>(x); }
+  //   same value representation as x.
+  template<typename T> struct Translate : public std::false_type {};
 };
 
-// Convert an enum or floating point value to an integer value.
-template<typename T, typename U>
-struct PrimitiveConversions::Cast<
-  T, U, true,
-  typename EnableIf<IsIntegral<T>::value &&
-                    (std::is_enum<U>::value ||
-                     IsFloatingPoint<U>::value)>::type>
-{
-  T operator()(U x) const { return cast_using_union<T>(x); }
-};
-
-// Convert an integer to an enum or floating point value.
-template<typename T, typename U>
-struct PrimitiveConversions::Cast<
-  T, U, true,
-  typename EnableIf<IsIntegral<U>::value &&
-                    (std::is_enum<T>::value ||
-                     IsFloatingPoint<T>::value)>::type>
-{
-  T operator()(U x) const { return cast_using_union<T>(x); }
-};
-
-// Convert a pointer to an integral value.
-template<typename T, typename U>
-struct PrimitiveConversions::Cast<
-  T, U*, true,
-  typename EnableIf<IsIntegral<T>::value>::type>
-{
-  T operator()(U* x) const { return reinterpret_cast<T>(x); }
-};
-
-// Convert an integral value to a pointer.
-template<typename T, typename U>
-struct PrimitiveConversions::Cast<
-  T*, U, true,
-  typename EnableIf<IsIntegral<U>::value>::type>
-{
-  T* operator()(U x) const { return reinterpret_cast<T*>(x); }
-};
-
-template<typename T, typename U>
-inline T PrimitiveConversions::cast(U x) {
-  return Cast<T, U>()(x);
-}
-
 // jfloat and jdouble translation to integral types
 
 template<>
-struct PrimitiveConversions::Translate<jdouble> : public TrueType {
+struct PrimitiveConversions::Translate<jdouble> : public std::true_type {
   typedef double Value;
   typedef int64_t Decayed;
 
@@ -174,7 +129,7 @@ struct PrimitiveConversions::Translate<jdouble> : public TrueType {
 };
 
 template<>
-struct PrimitiveConversions::Translate<jfloat> : public TrueType {
+struct PrimitiveConversions::Translate<jfloat> : public std::true_type {
   typedef float Value;
   typedef int32_t Decayed;
 
diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp
index 0f650fdca4f..f76a75fba4e 100644
--- a/src/hotspot/share/oops/constantPool.cpp
+++ b/src/hotspot/share/oops/constantPool.cpp
@@ -492,8 +492,7 @@ void ConstantPool::trace_class_resolution(const constantPoolHandle& this_cp, Kla
 
 Klass* ConstantPool::klass_at_impl(const constantPoolHandle& this_cp, int which,
                                    bool save_resolution_error, TRAPS) {
-  assert(THREAD->is_Java_thread(), "must be a Java thread");
-  JavaThread* javaThread = (JavaThread*)THREAD;
+  JavaThread* javaThread = THREAD->as_Java_thread();
 
   // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
   // It is not safe to rely on the tag bit's here, since we don't have a lock, and
diff --git a/src/hotspot/share/oops/constantPool.hpp b/src/hotspot/share/oops/constantPool.hpp
index 7e5282dfba5..783dff8a539 100644
--- a/src/hotspot/share/oops/constantPool.hpp
+++ b/src/hotspot/share/oops/constantPool.hpp
@@ -495,7 +495,7 @@ class ConstantPool : public Metadata {
   // a String entry.
   // This can happen if the user patches a live
   // object into a CONSTANT_String entry of an unsafe anonymous class.
-  // Method oops internally created for method handles may also
+  // Methods internally created for method handles may also
   // use pseudo-strings to link themselves to related metaobjects.
 
   bool is_pseudo_string_at(int which);
diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp
index cef30558c90..da508131199 100644
--- a/src/hotspot/share/oops/instanceKlass.cpp
+++ b/src/hotspot/share/oops/instanceKlass.cpp
@@ -47,6 +47,7 @@
 #include "logging/logMessage.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/archiveUtils.hpp"
 #include "memory/iterator.inline.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceClosure.hpp"
@@ -898,8 +899,7 @@ bool InstanceKlass::link_class_impl(TRAPS) {
 
   // Timing
   // timer handles recursion
-  assert(THREAD->is_Java_thread(), "non-JavaThread in link_class_impl");
-  JavaThread* jt = (JavaThread*)THREAD;
+  JavaThread* jt = THREAD->as_Java_thread();
 
   // link super class before linking this class
   Klass* super_klass = super();
@@ -1001,9 +1001,7 @@ bool InstanceKlass::link_class_impl(TRAPS) {
 #endif
       set_init_state(linked);
       if (JvmtiExport::should_post_class_prepare()) {
-        Thread *thread = THREAD;
-        assert(thread->is_Java_thread(), "thread->is_Java_thread()");
-        JvmtiExport::post_class_prepare((JavaThread *) thread, this);
+        JvmtiExport::post_class_prepare(THREAD->as_Java_thread(), this);
       }
     }
   }
@@ -1067,8 +1065,7 @@ void InstanceKlass::initialize_impl(TRAPS) {
 
   bool wait = false;
 
-  assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
-  JavaThread* jt = (JavaThread*)THREAD;
+  JavaThread* jt = THREAD->as_Java_thread();
 
   // refer to the JVM book page 47 for description of steps
   // Step 1
@@ -1444,7 +1441,7 @@ Klass* InstanceKlass::array_klass_impl(bool or_null, int n, TRAPS) {
     if (or_null) return NULL;
 
     ResourceMark rm(THREAD);
-    JavaThread *jt = (JavaThread *)THREAD;
+    JavaThread *jt = THREAD->as_Java_thread();
     {
       // Atomic creation of array_klasses
       MutexLocker ma(THREAD, MultiArray_lock);
@@ -3635,7 +3632,7 @@ void InstanceKlass::print_class_load_logging(ClassLoaderData* loader_data,
       Thread* THREAD = Thread::current();
       Klass* caller =
             THREAD->is_Java_thread()
-                ? ((JavaThread*)THREAD)->security_get_caller_class(1)
+                ? THREAD->as_Java_thread()->security_get_caller_class(1)
                 : NULL;
       // caller can be NULL, for example, during a JVMTI VM_Init hook
       if (caller != NULL) {
diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp
index c534995c567..f955edffd69 100644
--- a/src/hotspot/share/oops/instanceKlass.hpp
+++ b/src/hotspot/share/oops/instanceKlass.hpp
@@ -1329,6 +1329,7 @@ class InstanceKlass: public Klass {
   virtual void remove_unshareable_info();
   virtual void remove_java_mirror();
   void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, PackageEntry* pkg_entry, TRAPS);
+  void init_shared_package_entry();
 
   // jvm support
   jint compute_modifier_flags(TRAPS) const;
diff --git a/src/hotspot/share/oops/markWord.cpp b/src/hotspot/share/oops/markWord.cpp
index 4c599f8b6ea..2c8ad2414db 100644
--- a/src/hotspot/share/oops/markWord.cpp
+++ b/src/hotspot/share/oops/markWord.cpp
@@ -26,6 +26,7 @@
 #include "oops/markWord.hpp"
 #include "runtime/thread.inline.hpp"
 #include "runtime/objectMonitor.hpp"
+#include "utilities/ostream.hpp"
 
 void markWord::print_on(outputStream* st) const {
   if (is_marked()) {  // last bits = 11
diff --git a/src/hotspot/share/oops/markWord.hpp b/src/hotspot/share/oops/markWord.hpp
index b3d97417821..2846e1ae112 100644
--- a/src/hotspot/share/oops/markWord.hpp
+++ b/src/hotspot/share/oops/markWord.hpp
@@ -94,6 +94,7 @@
 class BasicLock;
 class ObjectMonitor;
 class JavaThread;
+class outputStream;
 
 class markWord {
  private:
diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp
index 3b65ba17d7c..88a106fbeed 100644
--- a/src/hotspot/share/oops/method.cpp
+++ b/src/hotspot/share/oops/method.cpp
@@ -40,6 +40,7 @@
 #include "logging/logTag.hpp"
 #include "logging/logStream.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/cppVtables.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/metaspaceClosure.hpp"
 #include "memory/metaspaceShared.hpp"
@@ -2303,7 +2304,7 @@ bool Method::is_valid_method(const Method* m) {
     // Quick sanity check on pointer.
     return false;
   } else if (m->is_shared()) {
-    return MetaspaceShared::is_valid_shared_method(m);
+    return CppVtables::is_valid_shared_method(m);
   } else if (Metaspace::contains_non_shared(m)) {
     return has_method_vptr((const void*)m);
   } else {
diff --git a/src/hotspot/share/oops/objArrayKlass.cpp b/src/hotspot/share/oops/objArrayKlass.cpp
index 7c8651439cf..9268cb789f3 100644
--- a/src/hotspot/share/oops/objArrayKlass.cpp
+++ b/src/hotspot/share/oops/objArrayKlass.cpp
@@ -321,7 +321,7 @@ Klass* ObjArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
     if (or_null) return NULL;
 
     ResourceMark rm;
-    JavaThread *jt = (JavaThread *)THREAD;
+    JavaThread *jt = THREAD->as_Java_thread();
     {
       // Ensure atomic creation of higher dimensions
       MutexLocker mu(THREAD, MultiArray_lock);
diff --git a/src/hotspot/share/oops/oop.hpp b/src/hotspot/share/oops/oop.hpp
index db0254ab4a6..7c96f9d3dcf 100644
--- a/src/hotspot/share/oops/oop.hpp
+++ b/src/hotspot/share/oops/oop.hpp
@@ -271,9 +271,6 @@ class oopDesc {
   inline uint age() const;
   inline void incr_age();
 
-  // mark-sweep support
-  void follow_body(int begin, int end);
-
   template <typename OopClosureType>
   inline void oop_iterate(OopClosureType* cl);
 
diff --git a/src/hotspot/share/oops/symbol.cpp b/src/hotspot/share/oops/symbol.cpp
index b84401dbee8..bca078a7644 100644
--- a/src/hotspot/share/oops/symbol.cpp
+++ b/src/hotspot/share/oops/symbol.cpp
@@ -35,6 +35,7 @@
 #include "memory/universe.hpp"
 #include "oops/symbol.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/mutexLocker.hpp"
 #include "runtime/os.hpp"
 #include "runtime/signature.hpp"
 #include "utilities/utf8.hpp"
@@ -63,13 +64,14 @@ Symbol::Symbol(const u1* name, int length, int refcount) {
 void* Symbol::operator new(size_t sz, int len) throw() {
 #if INCLUDE_CDS
  if (DumpSharedSpaces) {
-    // To get deterministic output from -Xshare:dump, we ensure that Symbols are allocated in
-    // increasing addresses. When the symbols are copied into the archive, we preserve their
-    // relative address order (see SortedSymbolClosure in metaspaceShared.cpp)
-    //
-    // We cannot use arena because arena chunks are allocated by the OS. As a result, for example,
-    // the archived symbol of "java/lang/Object" may sometimes be lower than "java/lang/String", and
-    // sometimes be higher. This would cause non-deterministic contents in the archive.
+   MutexLocker ml(DumpRegion_lock, Mutex::_no_safepoint_check_flag);
+   // To get deterministic output from -Xshare:dump, we ensure that Symbols are allocated in
+   // increasing addresses. When the symbols are copied into the archive, we preserve their
+   // relative address order (sorted, see ArchiveBuilder::gather_klasses_and_symbols).
+   //
+   // We cannot use arena because arena chunks are allocated by the OS. As a result, for example,
+   // the archived symbol of "java/lang/Object" may sometimes be lower than "java/lang/String", and
+   // sometimes be higher. This would cause non-deterministic contents in the archive.
    DEBUG_ONLY(static void* last = 0);
    void* p = (void*)MetaspaceShared::symbol_space_alloc(size(len)*wordSize);
    assert(p > last, "must increase monotonically");
diff --git a/src/hotspot/share/oops/typeArrayKlass.cpp b/src/hotspot/share/oops/typeArrayKlass.cpp
index ed95f63bde3..3c3ea730876 100644
--- a/src/hotspot/share/oops/typeArrayKlass.cpp
+++ b/src/hotspot/share/oops/typeArrayKlass.cpp
@@ -183,7 +183,7 @@ Klass* TypeArrayKlass::array_klass_impl(bool or_null, int n, TRAPS) {
     if (or_null)  return NULL;
 
     ResourceMark rm;
-    JavaThread *jt = (JavaThread *)THREAD;
+    JavaThread *jt = THREAD->as_Java_thread();
     {
       // Atomic create higher dimension and link into list
       MutexLocker mu(THREAD, MultiArray_lock);
diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp
index 18174aed8f7..668c04f379a 100644
--- a/src/hotspot/share/opto/c2_globals.hpp
+++ b/src/hotspot/share/opto/c2_globals.hpp
@@ -35,21 +35,18 @@
 // Defines all globals flags used by the server compiler.
 //
 
-#define C2_FLAGS(develop, \
-                 develop_pd, \
-                 product, \
-                 product_pd, \
-                 diagnostic, \
-                 diagnostic_pd, \
-                 experimental, \
-                 notproduct, \
-                 range, \
-                 constraint) \
-                                                                            \
-  diagnostic(bool, StressLCM, false,                                        \
+#define C2_FLAGS(develop,                                                   \
+                 develop_pd,                                                \
+                 product,                                                   \
+                 product_pd,                                                \
+                 notproduct,                                                \
+                 range,                                                     \
+                 constraint)                                                \
+                                                                            \
+  product(bool, StressLCM, false, DIAGNOSTIC,                               \
           "Randomize instruction scheduling in LCM")                        \
                                                                             \
-  diagnostic(bool, StressGCM, false,                                        \
+  product(bool, StressGCM, false, DIAGNOSTIC,                               \
           "Randomize instruction scheduling in GCM")                        \
                                                                             \
   develop(bool, StressMethodHandleLinkerInlining, false,                    \
@@ -116,7 +113,7 @@
           "Check performance difference allowing FP "                       \
           "associativity and commutativity...")                             \
                                                                             \
-  diagnostic_pd(bool, IdealizeClearArrayNode,                               \
+  product_pd(bool, IdealizeClearArrayNode, DIAGNOSTIC,                      \
           "Replace ClearArrayNode by subgraph of basic operations.")        \
                                                                             \
   develop(bool, OptoBreakpoint, false,                                      \
@@ -137,7 +134,7 @@
   notproduct(bool, PrintOptoStatistics, false,                              \
           "Print New compiler statistics")                                  \
                                                                             \
-  diagnostic(bool, PrintOptoAssembly, false,                                \
+  product(bool, PrintOptoAssembly, false, DIAGNOSTIC,                       \
           "Print New compiler assembly output")                             \
                                                                             \
   develop_pd(bool, OptoPeephole,                                            \
@@ -177,13 +174,13 @@
            "Map number of unrolls for main loop via "                       \
            "Superword Level Parallelism analysis")                          \
                                                                             \
-  experimental(bool, PostLoopMultiversioning, false,                        \
+  product(bool, PostLoopMultiversioning, false, EXPERIMENTAL,               \
            "Multi versioned post loops to eliminate range checks")          \
                                                                             \
   notproduct(bool, TraceSuperWordLoopUnrollAnalysis, false,                 \
           "Trace what Superword Level Parallelism analysis applies")        \
                                                                             \
-  diagnostic(bool, UseVectorMacroLogic, true,                               \
+  product(bool, UseVectorMacroLogic, true, DIAGNOSTIC,                      \
           "Use ternary macro logic instructions")                           \
                                                                             \
   product(intx,  LoopUnrollMin, 4,                                          \
@@ -482,11 +479,11 @@
   notproduct(bool, PrintLockStatistics, false,                              \
           "Print precise statistics on the dynamic lock usage")             \
                                                                             \
-  diagnostic(bool, PrintPreciseBiasedLockingStatistics, false,              \
+  product(bool, PrintPreciseBiasedLockingStatistics, false, DIAGNOSTIC,     \
           "(Deprecated) Print per-lock-site statistics of biased locking "  \
           "in JVM")                                                         \
                                                                             \
-  diagnostic(bool, PrintPreciseRTMLockingStatistics, false,                 \
+  product(bool, PrintPreciseRTMLockingStatistics, false, DIAGNOSTIC,        \
           "Print per-lock-site statistics of rtm locking in JVM")           \
                                                                             \
   notproduct(bool, PrintEliminateLocks, false,                              \
@@ -499,7 +496,7 @@
           "Sets max value cached by the java.lang.Integer autobox cache")   \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic(bool, AggressiveUnboxing, true,                                \
+  product(bool, AggressiveUnboxing, true, DIAGNOSTIC,                       \
           "Control optimizations for aggressive boxing elimination")        \
                                                                             \
   develop(bool, TracePostallocExpand, false, "Trace expanding nodes after"  \
@@ -554,7 +551,7 @@
           "Maximum times call Label_Root to prevent stack overflow")        \
           range(100, max_jint)                                              \
                                                                             \
-  diagnostic(intx, DominatorSearchLimit, 1000,                              \
+  product(intx, DominatorSearchLimit, 1000, DIAGNOSTIC,                     \
           "Iterations limit in Node::dominates")                            \
           range(0, max_jint)                                                \
                                                                             \
@@ -569,26 +566,26 @@
   product(bool, BlockLayoutRotateLoops, true,                               \
           "Allow back branches to be fall throughs in the block layout")    \
                                                                             \
-  diagnostic(bool, InlineReflectionGetCallerClass, true,                    \
+  product(bool, InlineReflectionGetCallerClass, true, DIAGNOSTIC,           \
           "inline sun.reflect.Reflection.getCallerClass(), known to be "    \
           "part of base library DLL")                                       \
                                                                             \
-  diagnostic(bool, InlineObjectCopy, true,                                  \
+  product(bool, InlineObjectCopy, true, DIAGNOSTIC,                         \
           "inline Object.clone and Arrays.copyOf[Range] intrinsics")        \
                                                                             \
-  diagnostic(bool, SpecialStringCompareTo, true,                            \
+  product(bool, SpecialStringCompareTo, true, DIAGNOSTIC,                   \
           "special version of string compareTo")                            \
                                                                             \
-  diagnostic(bool, SpecialStringIndexOf, true,                              \
+  product(bool, SpecialStringIndexOf, true, DIAGNOSTIC,                     \
           "special version of string indexOf")                              \
                                                                             \
-  diagnostic(bool, SpecialStringEquals, true,                               \
+  product(bool, SpecialStringEquals, true, DIAGNOSTIC,                      \
           "special version of string equals")                               \
                                                                             \
-  diagnostic(bool, SpecialArraysEquals, true,                               \
+  product(bool, SpecialArraysEquals, true, DIAGNOSTIC,                      \
           "special version of Arrays.equals(char[],char[])")                \
                                                                             \
-  diagnostic(bool, SpecialEncodeISOArray, true,                             \
+  product(bool, SpecialEncodeISOArray, true, DIAGNOSTIC,                    \
           "special version of ISO_8859_1$Encoder.encodeISOArray")           \
                                                                             \
   develop(bool, BailoutToInterpreterForThrows, false,                       \
@@ -610,10 +607,10 @@
   develop(bool, PrintDominators, false,                                     \
           "Print out dominator trees for GVN")                              \
                                                                             \
-  diagnostic(bool, TraceSpilling, false,                                    \
+  product(bool, TraceSpilling, false, DIAGNOSTIC,                           \
           "Trace spilling")                                                 \
                                                                             \
-  diagnostic(bool, TraceTypeProfile, false,                                 \
+  product(bool, TraceTypeProfile, false, DIAGNOSTIC,                        \
           "Trace type profile")                                             \
                                                                             \
   develop(bool, PoisonOSREntry, true,                                       \
@@ -629,19 +626,19 @@
           "% of major receiver type to all profiled receivers")             \
           range(0, 100)                                                     \
                                                                             \
-  diagnostic(bool, PrintIntrinsics, false,                                  \
+  product(bool, PrintIntrinsics, false, DIAGNOSTIC,                         \
           "prints attempted and successful inlining of intrinsics")         \
                                                                             \
   develop(bool, StressReflectiveCode, false,                                \
           "Use inexact types at allocations, etc., to test reflection")     \
                                                                             \
-  diagnostic(bool, DebugInlinedCalls, true,                                 \
+  product(bool, DebugInlinedCalls, true, DIAGNOSTIC,                        \
          "If false, restricts profiled locations to the root method only")  \
                                                                             \
   notproduct(bool, VerifyLoopOptimizations, false,                          \
           "verify major loop optimizations")                                \
                                                                             \
-  diagnostic(bool, ProfileDynamicTypes, true,                               \
+  product(bool, ProfileDynamicTypes, true, DIAGNOSTIC,                      \
           "do extra type profiling and use it more aggressively")           \
                                                                             \
   develop(bool, TraceIterativeGVN, false,                                   \
@@ -710,34 +707,34 @@
           "max number of live nodes in a method")                           \
           range(0, max_juint / 8)                                           \
                                                                             \
-  diagnostic(bool, OptimizeExpensiveOps, true,                              \
+  product(bool, OptimizeExpensiveOps, true, DIAGNOSTIC,                     \
           "Find best control for expensive operations")                     \
                                                                             \
-  diagnostic(bool, UseMathExactIntrinsics, true,                            \
+  product(bool, UseMathExactIntrinsics, true, DIAGNOSTIC,                   \
           "Enables intrinsification of various java.lang.Math functions")   \
                                                                             \
-  diagnostic(bool, UseCharacterCompareIntrinsics, false,                    \
+  product(bool, UseCharacterCompareIntrinsics, false, DIAGNOSTIC,           \
           "Enables intrinsification of java.lang.Character functions")      \
                                                                             \
-  diagnostic(bool, UseMultiplyToLenIntrinsic, false,                        \
+  product(bool, UseMultiplyToLenIntrinsic, false, DIAGNOSTIC,               \
           "Enables intrinsification of BigInteger.multiplyToLen()")         \
                                                                             \
-  diagnostic(bool, UseSquareToLenIntrinsic, false,                          \
+  product(bool, UseSquareToLenIntrinsic, false, DIAGNOSTIC,                 \
           "Enables intrinsification of BigInteger.squareToLen()")           \
                                                                             \
-  diagnostic(bool, UseMulAddIntrinsic, false,                               \
+  product(bool, UseMulAddIntrinsic, false, DIAGNOSTIC,                      \
           "Enables intrinsification of BigInteger.mulAdd()")                \
                                                                             \
-  diagnostic(bool, UseMontgomeryMultiplyIntrinsic, false,                   \
+  product(bool, UseMontgomeryMultiplyIntrinsic, false, DIAGNOSTIC,          \
           "Enables intrinsification of BigInteger.montgomeryMultiply()")    \
                                                                             \
-  diagnostic(bool, UseMontgomerySquareIntrinsic, false,                     \
+  product(bool, UseMontgomerySquareIntrinsic, false, DIAGNOSTIC,            \
           "Enables intrinsification of BigInteger.montgomerySquare()")      \
                                                                             \
   product(bool, UseTypeSpeculation, true,                                   \
           "Speculatively propagate types from profiles")                    \
                                                                             \
-  diagnostic(bool, UseInlineDepthForSpeculativeTypes, true,                 \
+  product(bool, UseInlineDepthForSpeculativeTypes, true, DIAGNOSTIC,        \
           "Carry inline depth of profile point with speculative type "      \
           "and give priority to profiling from lower inline depth")         \
                                                                             \
@@ -768,7 +765,9 @@
   product(bool, UseProfiledLoopPredicate, true,                             \
           "Move predicates out of loops based on profiling data")           \
                                                                             \
-  diagnostic(bool, ExpandSubTypeCheckAtParseTime, false,                    \
-          "Do not use subtype check macro node")                            \
+  product(bool, ExpandSubTypeCheckAtParseTime, false, DIAGNOSTIC,           \
+          "Do not use subtype check macro node")
+
+// end of C2_FLAGS
 
 #endif // SHARE_OPTO_C2_GLOBALS_HPP
diff --git a/src/hotspot/share/opto/callnode.hpp b/src/hotspot/share/opto/callnode.hpp
index bfaada851ce..16f5a0baae5 100644
--- a/src/hotspot/share/opto/callnode.hpp
+++ b/src/hotspot/share/opto/callnode.hpp
@@ -54,7 +54,6 @@ class     BoxLockNode;
 class     LockNode;
 class     UnlockNode;
 class JVMState;
-class OopMap;
 class State;
 class StartNode;
 class MachCallNode;
@@ -329,14 +328,12 @@ class SafePointNode : public MultiNode {
                 // A plain safepoint advertises no memory effects (NULL):
                 const TypePtr* adr_type = NULL)
     : MultiNode( edges ),
-      _oop_map(NULL),
       _jvms(jvms),
       _adr_type(adr_type)
   {
     init_class_id(Class_SafePoint);
   }
 
-  OopMap*         _oop_map;   // Array of OopMap info (8-bit char) for GC
   JVMState* const _jvms;      // Pointer to list of JVM State objects
   const TypePtr*  _adr_type;  // What type of memory does this node produce?
   ReplacedNodes   _replaced_nodes; // During parsing: list of pair of nodes from calls to GraphKit::replace_in_map()
@@ -349,8 +346,6 @@ class SafePointNode : public MultiNode {
   void set_jvms(JVMState* s) {
     *(JVMState**)&_jvms = s;  // override const attribute in the accessor
   }
-  OopMap *oop_map() const { return _oop_map; }
-  void set_oop_map(OopMap *om) { _oop_map = om; }
 
  private:
   void verify_input(JVMState* jvms, uint idx) const {
diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp
index ec7ecc7bdfc..ff266916b4b 100644
--- a/src/hotspot/share/opto/loopTransform.cpp
+++ b/src/hotspot/share/opto/loopTransform.cpp
@@ -40,6 +40,7 @@
 #include "opto/subnode.hpp"
 #include "opto/superword.hpp"
 #include "opto/vectornode.hpp"
+#include "runtime/globals_extension.hpp"
 
 //------------------------------is_loop_exit-----------------------------------
 // Given an IfNode, return the loop-exiting projection or NULL if both
diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp
index f901206f16a..cb1d6d69372 100644
--- a/src/hotspot/share/opto/machnode.hpp
+++ b/src/hotspot/share/opto/machnode.hpp
@@ -880,17 +880,14 @@ class MachCallNode : public MachSafePointNode {
   const TypeFunc *_tf;        // Function type
   address      _entry_point;  // Address of the method being called
   float        _cnt;          // Estimate of number of times called
-  uint         _argsize;      // Size of argument block on stack
 
   const TypeFunc* tf()        const { return _tf; }
   const address entry_point() const { return _entry_point; }
   const float   cnt()         const { return _cnt; }
-  uint argsize()              const { return _argsize; }
 
   void set_tf(const TypeFunc* tf) { _tf = tf; }
   void set_entry_point(address p) { _entry_point = p; }
   void set_cnt(float c)           { _cnt = c; }
-  void set_argsize(int s)         { _argsize = s; }
 
   MachCallNode() : MachSafePointNode() {
     init_class_id(Class_MachCall);
diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp
index 2bbd5a28c8e..b07b4e03be9 100644
--- a/src/hotspot/share/opto/matcher.cpp
+++ b/src/hotspot/share/opto/matcher.cpp
@@ -1305,10 +1305,6 @@ MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) {
       if (OptoReg::is_valid(reg2))
         rm->Insert( reg2 );
     } // End of for all arguments
-
-    // Compute number of stack slots needed to restore stack in case of
-    // Pascal-style argument popping.
-    mcall->_argsize = out_arg_limit_per_call - begin_out_arg_area;
   }
 
   // Compute the max stack slot killed by any call.  These will not be
@@ -1346,9 +1342,6 @@ MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) {
   assert((mcall == NULL) || (mcall->jvms() == NULL) ||
          (mcall->jvms()->debug_start() + mcall->_jvmadj == mcall->tf()->domain()->cnt()), "");
 
-  // Move the OopMap
-  msfpt->_oop_map = sfpt->_oop_map;
-
   // Add additional edges.
   if (msfpt->mach_constant_base_node_input() != (uint)-1 && !msfpt->is_MachCallLeaf()) {
     // For these calls we can not add MachConstantBase in expand(), as the
diff --git a/src/hotspot/share/opto/matcher.hpp b/src/hotspot/share/opto/matcher.hpp
index c55b6d2b8da..c211557eacb 100644
--- a/src/hotspot/share/opto/matcher.hpp
+++ b/src/hotspot/share/opto/matcher.hpp
@@ -358,9 +358,6 @@ class Matcher : public PhaseTransform {
 
   // These calls are all generated by the ADLC
 
-  // TRUE - grows up, FALSE - grows down (Intel)
-  virtual bool stack_direction() const;
-
   // Java-Java calling convention
   // (what you use when Java calls Java)
 
@@ -418,12 +415,12 @@ class Matcher : public PhaseTransform {
   // The Method-klass-holder may be passed in the inline_cache_reg
   // and then expanded into the inline_cache_reg and a method_ptr register
 
-  static OptoReg::Name  interpreter_method_oop_reg();
-  static int            interpreter_method_oop_reg_encode();
+  static OptoReg::Name  interpreter_method_reg();
+  static int            interpreter_method_reg_encode();
 
-  static OptoReg::Name  compiler_method_oop_reg();
-  static const RegMask &compiler_method_oop_reg_mask();
-  static int            compiler_method_oop_reg_encode();
+  static OptoReg::Name  compiler_method_reg();
+  static const RegMask &compiler_method_reg_mask();
+  static int            compiler_method_reg_encode();
 
   // Interpreter's Frame Pointer Register
   static OptoReg::Name  interpreter_frame_pointer_reg();
@@ -440,9 +437,6 @@ class Matcher : public PhaseTransform {
   OptoReg::Name  c_frame_pointer() const;
   static RegMask c_frame_ptr_mask;
 
-  // !!!!! Special stuff for building ScopeDescs
-  virtual int      regnum_to_fpu_offset(int regnum);
-
   // Is this branch offset small enough to be addressed by a short branch?
   bool is_short_branch_offset(int rule, int br_size, int offset);
 
diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp
index 3f41a2ff7fa..dc7af3d4b29 100644
--- a/src/hotspot/share/opto/type.cpp
+++ b/src/hotspot/share/opto/type.cpp
@@ -250,7 +250,7 @@ const Type* Type::make_from_constant(ciConstant constant, bool require_constant,
           guarantee(require_constant || oop_constant->should_be_constant(), "con_type must get computed");
           con_type = TypeOopPtr::make_from_constant(oop_constant, require_constant);
           if (Compile::current()->eliminate_boxing() && is_autobox_cache) {
-            con_type = con_type->is_aryptr()->cast_to_autobox_cache(true);
+            con_type = con_type->is_aryptr()->cast_to_autobox_cache();
           }
           if (stable_dimension > 0) {
             assert(FoldStableValues, "sanity");
@@ -4203,15 +4203,14 @@ int TypeAryPtr::stable_dimension() const {
 }
 
 //----------------------cast_to_autobox_cache-----------------------------------
-const TypeAryPtr* TypeAryPtr::cast_to_autobox_cache(bool cache) const {
-  if (is_autobox_cache() == cache)  return this;
+const TypeAryPtr* TypeAryPtr::cast_to_autobox_cache() const {
+  if (is_autobox_cache())  return this;
   const TypeOopPtr* etype = elem()->make_oopptr();
   if (etype == NULL)  return this;
   // The pointers in the autobox arrays are always non-null.
-  TypePtr::PTR ptr_type = cache ? TypePtr::NotNull : TypePtr::AnyNull;
   etype = etype->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr();
   const TypeAry* new_ary = TypeAry::make(etype, size(), is_stable());
-  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth, cache);
+  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth, /*is_autobox_cache=*/true);
 }
 
 //------------------------------eq---------------------------------------------
diff --git a/src/hotspot/share/opto/type.hpp b/src/hotspot/share/opto/type.hpp
index 08053369b09..989630b17a8 100644
--- a/src/hotspot/share/opto/type.hpp
+++ b/src/hotspot/share/opto/type.hpp
@@ -1226,7 +1226,7 @@ class TypeAryPtr : public TypeOopPtr {
   const TypeAryPtr* cast_to_stable(bool stable, int stable_dimension = 1) const;
   int stable_dimension() const;
 
-  const TypeAryPtr* cast_to_autobox_cache(bool cache) const;
+  const TypeAryPtr* cast_to_autobox_cache() const;
 
   static jint max_array_length(BasicType etype) ;
 
diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp
index aabed4ecb3a..f0f779e3a87 100644
--- a/src/hotspot/share/prims/jni.cpp
+++ b/src/hotspot/share/prims/jni.cpp
@@ -329,7 +329,7 @@ JNI_ENTRY(jclass, jni_DefineClass(JNIEnv *env, const char *name, jobject loaderR
     // check whether the current caller thread holds the lock or not.
     // If not, increment the corresponding counter
     if (ObjectSynchronizer::
-        query_lock_ownership((JavaThread*)THREAD, class_loader) !=
+        query_lock_ownership(thread, class_loader) !=
         ObjectSynchronizer::owner_self) {
       ClassLoader::sync_JNIDefineClassLockFreeCounter()->inc();
     }
@@ -3940,7 +3940,7 @@ static jint attach_current_thread(JavaVM *vm, void **penv, void *_args, bool dae
     // If executing from an atexit hook we may be in the VMThread.
     if (t->is_Java_thread()) {
       // If the thread has been attached this operation is a no-op
-      *(JNIEnv**)penv = ((JavaThread*) t)->jni_environment();
+      *(JNIEnv**)penv = t->as_Java_thread()->jni_environment();
       return JNI_OK;
     } else {
       return JNI_ERR;
@@ -4078,7 +4078,7 @@ jint JNICALL jni_DetachCurrentThread(JavaVM *vm)  {
 
   VM_Exit::block_if_vm_exited();
 
-  JavaThread* thread = (JavaThread*) current;
+  JavaThread* thread = current->as_Java_thread();
   if (thread->has_last_Java_frame()) {
     HOTSPOT_JNI_DETACHCURRENTTHREAD_RETURN((uint32_t) JNI_ERR);
     // Can't detach a thread that's running java, that can't work.
@@ -4133,7 +4133,7 @@ jint JNICALL jni_GetEnv(JavaVM *vm, void **penv, jint version) {
   Thread* thread = Thread::current_or_null();
   if (thread != NULL && thread->is_Java_thread()) {
     if (Threads::is_supported_jni_version_including_1_1(version)) {
-      *(JNIEnv**)penv = ((JavaThread*) thread)->jni_environment();
+      *(JNIEnv**)penv = thread->as_Java_thread()->jni_environment();
       ret = JNI_OK;
       return ret;
 
diff --git a/src/hotspot/share/prims/jniCheck.cpp b/src/hotspot/share/prims/jniCheck.cpp
index 47da2257a83..fd9e2e3bab7 100644
--- a/src/hotspot/share/prims/jniCheck.cpp
+++ b/src/hotspot/share/prims/jniCheck.cpp
@@ -93,11 +93,12 @@ static struct JNINativeInterface_ * unchecked_jni_NativeInterface;
 #define JNI_ENTRY_CHECKED(result_type, header)                           \
 extern "C" {                                                             \
   result_type JNICALL header {                                           \
-    JavaThread* thr = (JavaThread*) Thread::current_or_null();           \
-    if (thr == NULL || !thr->is_Java_thread()) {                         \
+    Thread* cur = Thread::current_or_null();                             \
+    if (cur == NULL || !cur->is_Java_thread()) {                         \
       tty->print_cr("%s", fatal_using_jnienv_in_nonjava);                \
       os::abort(true);                                                   \
     }                                                                    \
+    JavaThread* thr = cur->as_Java_thread();                             \
     JNIEnv* xenv = thr->jni_environment();                               \
     if (env != xenv) {                                                   \
       NativeReportJNIFatalError(thr, warn_wrong_jnienv);                 \
diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp
index 0b415808715..e6313ba37f2 100644
--- a/src/hotspot/share/prims/jvm.cpp
+++ b/src/hotspot/share/prims/jvm.cpp
@@ -65,6 +65,7 @@
 #include "prims/stackwalk.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
@@ -142,7 +143,7 @@ static void trace_class_resolution_impl(Klass* to_class, TRAPS) {
   const char * source_file = NULL;
   const char * trace = "explicit";
   InstanceKlass* caller = NULL;
-  JavaThread* jthread = (JavaThread*) THREAD;
+  JavaThread* jthread = THREAD->as_Java_thread();
   if (jthread->has_last_Java_frame()) {
     vframeStream vfst(jthread);
 
@@ -611,8 +612,7 @@ JVM_ENTRY(jobject, JVM_CallStackWalk(JNIEnv *env, jobject stackStream, jlong mod
                                      jint skip_frames, jint frame_count, jint start_index,
                                      jobjectArray frames))
   JVMWrapper("JVM_CallStackWalk");
-  JavaThread* jt = (JavaThread*) THREAD;
-  if (!jt->is_Java_thread() || !jt->has_last_Java_frame()) {
+  if (!thread->has_last_Java_frame()) {
     THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: no stack trace", NULL);
   }
 
@@ -671,7 +671,7 @@ JVM_ENTRY(void, JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms))
   Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
   JavaThreadInObjectWaitState jtiows(thread, ms != 0);
   if (JvmtiExport::should_post_monitor_wait()) {
-    JvmtiExport::post_monitor_wait((JavaThread *)THREAD, (oop)obj(), ms);
+    JvmtiExport::post_monitor_wait(thread, (oop)obj(), ms);
 
     // The current thread already owns the monitor and it has not yet
     // been added to the wait queue so the current thread cannot be
@@ -921,7 +921,7 @@ static void is_lock_held_by_thread(Handle loader, PerfCounter* counter, TRAPS) {
 
   // check whether the current caller thread holds the lock or not.
   // If not, increment the corresponding counter
-  if (ObjectSynchronizer::query_lock_ownership((JavaThread*)THREAD, loader) !=
+  if (ObjectSynchronizer::query_lock_ownership(THREAD->as_Java_thread(), loader) !=
       ObjectSynchronizer::owner_self) {
     counter->inc();
   }
@@ -934,8 +934,7 @@ static jclass jvm_define_class_common(const char *name,
                                       TRAPS) {
   if (source == NULL)  source = "__JVM_DefineClass__";
 
-  assert(THREAD->is_Java_thread(), "must be a JavaThread");
-  JavaThread* jt = (JavaThread*) THREAD;
+  JavaThread* jt = THREAD->as_Java_thread();
 
   PerfClassTraceTime vmtimer(ClassLoader::perf_define_appclass_time(),
                              ClassLoader::perf_define_appclass_selftime(),
@@ -989,7 +988,6 @@ enum {
 static jclass jvm_lookup_define_class(jclass lookup, const char *name,
                                       const jbyte *buf, jsize len, jobject pd,
                                       jboolean init, int flags, jobject classData, TRAPS) {
-  assert(THREAD->is_Java_thread(), "must be a JavaThread");
   ResourceMark rm(THREAD);
 
   Klass* lookup_k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(lookup));
@@ -1230,6 +1228,11 @@ JVM_ENTRY (void, JVM_AddReadsModule(JNIEnv *env, jobject from_module, jobject so
   Modules::add_reads_module(from_module, source_module, CHECK);
 JVM_END
 
+JVM_ENTRY(void, JVM_DefineArchivedModules(JNIEnv *env, jobject platform_loader, jobject system_loader))
+  JVMWrapper("JVM_DefineArchivedModules");
+  Modules::define_archived_modules(platform_loader, system_loader, CHECK);
+JVM_END
+
 // Reflection support //////////////////////////////////////////////////////////////////////////////
 
 JVM_ENTRY(jstring, JVM_InitClassName(JNIEnv *env, jclass cls))
@@ -3310,12 +3313,11 @@ JVM_END
 
 JVM_ENTRY(jboolean, JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj))
   JVMWrapper("JVM_HoldsLock");
-  assert(THREAD->is_Java_thread(), "sanity check");
   if (obj == NULL) {
     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
   }
   Handle h_obj(THREAD, JNIHandles::resolve(obj));
-  return ObjectSynchronizer::current_thread_holds_lock((JavaThread*)THREAD, h_obj);
+  return ObjectSynchronizer::current_thread_holds_lock(thread, h_obj);
 JVM_END
 
 
@@ -3726,7 +3728,7 @@ JVM_ENTRY(void, JVM_InitializeFromArchive(JNIEnv* env, jclass cls))
   JVMWrapper("JVM_InitializeFromArchive");
   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
   assert(k->is_klass(), "just checking");
-  HeapShared::initialize_from_archived_subgraph(k);
+  HeapShared::initialize_from_archived_subgraph(k, THREAD);
 JVM_END
 
 JVM_ENTRY(void, JVM_RegisterLambdaProxyClassForArchiving(JNIEnv* env,
diff --git a/src/hotspot/share/prims/jvmtiEnter.xsl b/src/hotspot/share/prims/jvmtiEnter.xsl
index 023b759c850..2ed29d5cb6f 100644
--- a/src/hotspot/share/prims/jvmtiEnter.xsl
+++ b/src/hotspot/share/prims/jvmtiEnter.xsl
@@ -1,4 +1,4 @@
-<?xml version="1.0"?> 
+<?xml version="1.0"?>
 <!--
  Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -20,7 +20,7 @@
  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.
-  
+
 -->
 
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
@@ -63,7 +63,7 @@
 // Error names
 const char* JvmtiUtil::_error_names[] = {
 </xsl:text>
-    <xsl:call-template name="fillEntityName"> 
+    <xsl:call-template name="fillEntityName">
       <xsl:with-param name="entities" select="errorsection/errorcategory/errorid"/>
     </xsl:call-template>
     <xsl:text>
@@ -73,7 +73,7 @@ const char* JvmtiUtil::_error_names[] = {
 // Event threaded
 const bool JvmtiUtil::_event_threaded[] = {
 </xsl:text>
-    <xsl:call-template name="fillEventThreaded"> 
+    <xsl:call-template name="fillEventThreaded">
       <xsl:with-param name="entities" select="eventsection/event"/>
     </xsl:call-template>
     <xsl:text>
@@ -92,7 +92,7 @@ const bool JvmtiUtil::_event_threaded[] = {
       <xsl:if test="count(../../eventsection/event[@num &gt; $mynum]) = 0">
         <xsl:value-of select="@num"/>
       </xsl:if>
-    </xsl:for-each>    
+    </xsl:for-each>
   </xsl:variable>
 
   <xsl:text>jbyte JvmtiTrace::_event_trace_flags[</xsl:text>
@@ -106,7 +106,7 @@ jint JvmtiTrace::_max_event_index = </xsl:text>
 // Event names
 const char* JvmtiTrace::_event_names[] = {
 </xsl:text>
-    <xsl:call-template name="fillEntityName"> 
+    <xsl:call-template name="fillEntityName">
       <xsl:with-param name="entities" select="eventsection/event"/>
     </xsl:call-template>
     <xsl:text>
@@ -203,7 +203,7 @@ const bool JvmtiUtil::has_event_capability(jvmtiEvent event_type, const jvmtiCap
       <xsl:if test="count(../../category/function[@num &gt; $mynum]) = 0">
         <xsl:value-of select="@num"/>
       </xsl:if>
-    </xsl:for-each>    
+    </xsl:for-each>
   </xsl:variable>
 
   <xsl:text>jbyte JvmtiTrace::_trace_flags[</xsl:text>
@@ -248,7 +248,7 @@ struct jvmtiInterface_1_ jvmti</xsl:text>
   <xsl:value-of select="$trace"/>
   <xsl:text>_Interface = {
 </xsl:text>
- 
+
   <xsl:call-template name="fillFuncStruct">
     <xsl:with-param name="funcs" select="category/function[count(@hide)=0]"/>
   </xsl:call-template>
@@ -281,7 +281,7 @@ struct jvmtiInterface_1_ jvmti</xsl:text>
     </xsl:when>
     <xsl:otherwise>
       <xsl:text> RESERVED */
-      NULL</xsl:text>        
+      NULL</xsl:text>
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
@@ -314,7 +314,7 @@ struct jvmtiInterface_1_ jvmti</xsl:text>
       <xsl:text>"</xsl:text>
     </xsl:when>
     <xsl:otherwise>
-      <xsl:text>  NULL</xsl:text>        
+      <xsl:text>  NULL</xsl:text>
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
@@ -347,12 +347,12 @@ struct jvmtiInterface_1_ jvmti</xsl:text>
           <xsl:text>  false</xsl:text>
         </xsl:when>
         <xsl:otherwise>
-          <xsl:text>  true</xsl:text>        
+          <xsl:text>  true</xsl:text>
         </xsl:otherwise>
       </xsl:choose>
     </xsl:when>
     <xsl:otherwise>
-      <xsl:text>  false</xsl:text>        
+      <xsl:text>  false</xsl:text>
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
@@ -387,7 +387,7 @@ struct jvmtiInterface_1_ jvmti</xsl:text>
   <xsl:text>
   //
   // </xsl:text><xsl:value-of select="@label"/><xsl:text> functions
-  // 
+  //
 </xsl:text>
   <xsl:apply-templates select="function[count(@hide)=0]"/>
 </xsl:template>
@@ -398,23 +398,23 @@ struct jvmtiInterface_1_ jvmti</xsl:text>
   </xsl:text>
   </xsl:param>
   <xsl:value-of select="$space"/>
-  
-  <xsl:choose> 
+
+  <xsl:choose>
     <xsl:when test="count(@callbacksafe)=0 or not(contains(@callbacksafe,'safe'))">
-      <xsl:text>if (this_thread == NULL || !this_thread->is_Java_thread()) {</xsl:text> 
-    </xsl:when> 
-    <xsl:otherwise> 
+      <xsl:text>if (this_thread == NULL || !this_thread->is_Java_thread()) {</xsl:text>
+    </xsl:when>
+    <xsl:otherwise>
       <xsl:choose>
         <xsl:when test="count(@phase)=0 or contains(@phase,'live') or contains(@phase,'start')">
 	  <xsl:text>if (this_thread == NULL || (!this_thread->is_Java_thread() &amp;&amp; !this_thread->is_Named_thread())) {</xsl:text>
         </xsl:when>
         <xsl:otherwise>
-          <xsl:text>if (!this_thread->is_Java_thread()) {</xsl:text> 
+          <xsl:text>if (!this_thread->is_Java_thread()) {</xsl:text>
         </xsl:otherwise>
       </xsl:choose>
-     </xsl:otherwise> 
-  </xsl:choose> 
-  
+     </xsl:otherwise>
+  </xsl:choose>
+
   <xsl:if test="$trace='Trace'">
     <xsl:value-of select="$space"/>
     <xsl:text>  if (trace_flags) {</xsl:text>
@@ -428,10 +428,10 @@ struct jvmtiInterface_1_ jvmti</xsl:text>
   <xsl:value-of select="$space"/>
   <xsl:text>  return JVMTI_ERROR_UNATTACHED_THREAD;</xsl:text>
   <xsl:value-of select="$space"/>
-  <xsl:text>}</xsl:text>  
-  <xsl:value-of select="$space"/>  
+  <xsl:text>}</xsl:text>
+  <xsl:value-of select="$space"/>
   <xsl:if test="count(@impl)=0 or not(contains(@impl,'innative'))">
-    <xsl:text>JavaThread* current_thread = (JavaThread*)this_thread;</xsl:text>   
+    <xsl:text>JavaThread* current_thread = this_thread->as_Java_thread();</xsl:text>
     <xsl:value-of select="$space"/>
     <xsl:text>ThreadInVMfromNative __tiv(current_thread);</xsl:text>
     <xsl:value-of select="$space"/>
@@ -456,7 +456,7 @@ struct jvmtiInterface_1_ jvmti</xsl:text>
 </xsl:text>
     <xsl:if test="$trace='Trace'">
       <xsl:text>    if (trace_flags) {
-          log_trace(jvmti)("[%s] %s %s",  curr_thread_name, func_name, 
+          log_trace(jvmti)("[%s] %s %s",  curr_thread_name, func_name,
                     JvmtiUtil::error_name(JVMTI_ERROR_MUST_POSSESS_CAPABILITY));
     }
 </xsl:text>
@@ -496,9 +496,9 @@ static jvmtiError JNICALL
 </xsl:text>
     </xsl:if>
     <xsl:text>    return JVMTI_ERROR_WRONG_PHASE;
-  }</xsl:text>  
+  }</xsl:text>
 
-      <xsl:text>  
+      <xsl:text>
   Thread* this_thread = Thread::current_or_null(); </xsl:text>
 
       <xsl:apply-templates select="." mode="transition"/>
@@ -513,7 +513,7 @@ static jvmtiError JNICALL
 </xsl:text>
     <xsl:if test="$trace='Trace'">
       <xsl:text>    if (trace_flags) {
-          log_trace(jvmti)("[-] %s %s",  func_name, 
+          log_trace(jvmti)("[-] %s %s",  func_name,
                     JvmtiUtil::error_name(JVMTI_ERROR_WRONG_PHASE));
     }
 </xsl:text>
@@ -526,7 +526,7 @@ static jvmtiError JNICALL
 </xsl:text>
     <xsl:if test="$trace='Trace'">
       <xsl:text>    if (trace_flags) {
-          log_trace(jvmti)("[-] %s %s",  func_name, 
+          log_trace(jvmti)("[-] %s %s",  func_name,
                     JvmtiUtil::error_name(JVMTI_ERROR_WRONG_PHASE));
     }
 </xsl:text>
@@ -545,7 +545,7 @@ static jvmtiError JNICALL
 </xsl:text>
     <xsl:if test="$trace='Trace'">
       <xsl:text>    if (trace_flags) {
-          log_trace(jvmti)("[%s] %s %s  env=" PTR_FORMAT,  curr_thread_name, func_name, 
+          log_trace(jvmti)("[%s] %s %s  env=" PTR_FORMAT,  curr_thread_name, func_name,
                     JvmtiUtil::error_name(JVMTI_ERROR_INVALID_ENVIRONMENT), p2i(env));
     }
 </xsl:text>
@@ -555,11 +555,11 @@ static jvmtiError JNICALL
 </xsl:text>
 
   <xsl:apply-templates select="capabilities/required"/>
-  
+
   <xsl:text>  jvmtiError err;
 </xsl:text>
   <xsl:choose>
-    <xsl:when test="count(@phase)=1 and not(contains(@phase,'live')) and not(contains(@phase,'start'))">    
+    <xsl:when test="count(@phase)=1 and not(contains(@phase,'live')) and not(contains(@phase,'start'))">
       <xsl:choose>
         <xsl:when test="count(@callbacksafe)=0 or not(contains(@callbacksafe,'safe'))">
           <xsl:text>  if (Threads::number_of_threads() != 0) {
@@ -589,16 +589,16 @@ static jvmtiError JNICALL
       </xsl:apply-templates>
       <xsl:text>
   </xsl:text>
-      <xsl:apply-templates select="." mode="doCall"/>     
+      <xsl:apply-templates select="." mode="doCall"/>
       <xsl:text>  } else {
   </xsl:text>
       <!-- we are pre-thread - no thread transition code -->
-      <xsl:apply-templates select="." mode="doCall"/>     
+      <xsl:apply-templates select="." mode="doCall"/>
       <xsl:text>  }
 </xsl:text>
     </xsl:when>
     <xsl:otherwise>
-      <xsl:apply-templates select="." mode="doCall"/>      
+      <xsl:apply-templates select="." mode="doCall"/>
     </xsl:otherwise>
   </xsl:choose>
   <xsl:text>  return err;
@@ -613,7 +613,7 @@ static jvmtiError JNICALL
 
 <xsl:template match="function" mode="doCall">
   <xsl:apply-templates select="parameters" mode="dochecks"/>
-  <xsl:apply-templates select="." mode="traceBefore"/>  
+  <xsl:apply-templates select="." mode="traceBefore"/>
   <xsl:apply-templates select="." mode="genCall"/>
   <xsl:apply-templates select="." mode="traceAfter"/>
 </xsl:template>
@@ -674,7 +674,7 @@ static jvmtiError JNICALL
         log_error(jvmti)("[%s] %s } %s - erroneous arg is </xsl:text>
     <xsl:value-of select="@id"/>
     <xsl:value-of select="$comment"/>
-    <xsl:text>",  curr_thread_name, func_name, 
+    <xsl:text>",  curr_thread_name, func_name,
                   JvmtiUtil::error_name(</xsl:text>
     <xsl:value-of select="$err"/>
     <xsl:text>)</xsl:text>
@@ -696,7 +696,7 @@ static jvmtiError JNICALL
 </xsl:text>
     <xsl:apply-templates select="." mode="traceIn"/>
     <xsl:text>    }
-    log_error(jvmti)("[%s] %s } %s",  curr_thread_name, func_name, 
+    log_error(jvmti)("[%s] %s } %s",  curr_thread_name, func_name,
                   JvmtiUtil::error_name(err));
   } else if ((trace_flags &amp; JvmtiTrace::SHOW_OUT) != 0) {
     log_trace(jvmti)("[%s] %s }",  curr_thread_name, func_name);
@@ -709,11 +709,11 @@ static jvmtiError JNICALL
   <xsl:param name="endParam"></xsl:param>
   <xsl:text>          log_trace(jvmti)("[%s] %s { </xsl:text>
   <xsl:apply-templates select="parameters" mode="traceInFormat">
-    <xsl:with-param name="endParam" select="$endParam"/>    
+    <xsl:with-param name="endParam" select="$endParam"/>
   </xsl:apply-templates>
   <xsl:text>", curr_thread_name, func_name</xsl:text>
   <xsl:apply-templates select="parameters" mode="traceInValue">
-    <xsl:with-param name="endParam" select="$endParam"/>    
+    <xsl:with-param name="endParam" select="$endParam"/>
   </xsl:apply-templates>
   <xsl:text>);
 </xsl:text>
@@ -736,7 +736,7 @@ static jvmtiError JNICALL
     <xsl:value-of select="$name"/>
     <xsl:text> == NULL) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
+    <xsl:apply-templates select=".." mode="traceError">
       <xsl:with-param name="err">JVMTI_ERROR_NULL_POINTER</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
@@ -752,7 +752,7 @@ static jvmtiError JNICALL
   <xsl:text>;
   if (rmonitor == NULL) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
+    <xsl:apply-templates select=".." mode="traceError">
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_MONITOR</xsl:with-param>
       <xsl:with-param name="comment"> - raw monitor is NULL</xsl:with-param>
     </xsl:apply-templates>
@@ -760,7 +760,7 @@ static jvmtiError JNICALL
   }
   if (!rmonitor->is_valid()) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
+    <xsl:apply-templates select=".." mode="traceError">
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_MONITOR</xsl:with-param>
       <xsl:with-param name="comment"> - not a raw monitor " PTR_FORMAT "</xsl:with-param>
       <xsl:with-param name="extraValue">, p2i(rmonitor)</xsl:with-param>
@@ -777,7 +777,7 @@ static jvmtiError JNICALL
     <xsl:text>, &amp;java_thread, NULL);
     if (err != JVMTI_ERROR_NONE) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
+    <xsl:apply-templates select=".." mode="traceError">
       <xsl:with-param name="err">err</xsl:with-param>
       <xsl:with-param name="comment"> - jthread did not convert to a JavaThread - jthread = " PTR_FORMAT "</xsl:with-param>
       <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
@@ -822,7 +822,7 @@ static jvmtiError JNICALL
   <xsl:text>
   if (depth &lt; 0) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
+    <xsl:apply-templates select=".." mode="traceError">
       <xsl:with-param name="err">JVMTI_ERROR_ILLEGAL_ARGUMENT</xsl:with-param>
       <xsl:with-param name="comment"> - negative depth - jthread = " INT32_FORMAT "</xsl:with-param>
       <xsl:with-param name="extraValue">, <xsl:value-of select="$name"/></xsl:with-param>
@@ -836,12 +836,12 @@ static jvmtiError JNICALL
  <xsl:param name="name"/>
  <!-- for JVMTI a jclass/jmethodID becomes just jmethodID -->
  <xsl:if test="count(@method)=0">
-  <xsl:text>  oop k_mirror = JNIHandles::resolve_external_guard(</xsl:text>  
+  <xsl:text>  oop k_mirror = JNIHandles::resolve_external_guard(</xsl:text>
   <xsl:value-of select="$name"/>
   <xsl:text>);
   if (k_mirror == NULL) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
+    <xsl:apply-templates select=".." mode="traceError">
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_CLASS</xsl:with-param>
       <xsl:with-param name="comment"> - resolved to NULL - jclass = " PTR_FORMAT "</xsl:with-param>
       <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
@@ -850,7 +850,7 @@ static jvmtiError JNICALL
   }
   if (!k_mirror->is_a(SystemDictionary::Class_klass())) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
+    <xsl:apply-templates select=".." mode="traceError">
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_CLASS</xsl:with-param>
       <xsl:with-param name="comment"> - not a class - jclass = " PTR_FORMAT "</xsl:with-param>
       <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
@@ -862,7 +862,7 @@ static jvmtiError JNICALL
     <xsl:text>
   if (java_lang_Class::is_primitive(k_mirror)) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
+    <xsl:apply-templates select=".." mode="traceError">
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_CLASS</xsl:with-param>
       <xsl:with-param name="comment"> - is a primitive class - jclass = " PTR_FORMAT "</xsl:with-param>
       <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
@@ -872,7 +872,7 @@ static jvmtiError JNICALL
   Klass* k_oop = java_lang_Class::as_Klass(k_mirror);
   if (k_oop == NULL) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
+    <xsl:apply-templates select=".." mode="traceError">
       <xsl:with-param name="err">JVMTI_ERROR_INVALID_CLASS</xsl:with-param>
       <xsl:with-param name="comment"> - no Klass* - jclass = " PTR_FORMAT "</xsl:with-param>
       <xsl:with-param name="extraValue">, p2i(<xsl:value-of select="$name"/>)</xsl:with-param>
@@ -891,7 +891,7 @@ static jvmtiError JNICALL
   <xsl:value-of select="$name"/>
   <xsl:text>);&#xA;</xsl:text>
   <xsl:text>  if (checked_method == NULL) {&#xA;</xsl:text>
-  <xsl:apply-templates select=".." mode="traceError">     
+  <xsl:apply-templates select=".." mode="traceError">
     <xsl:with-param name="err">JVMTI_ERROR_INVALID_METHODID</xsl:with-param>
     <xsl:with-param name="comment"></xsl:with-param>
     <xsl:with-param name="extraValue"></xsl:with-param>
@@ -899,9 +899,9 @@ static jvmtiError JNICALL
   <xsl:text>&#xA;</xsl:text>
   <xsl:text>  }&#xA;</xsl:text>
   <xsl:if test="count(@native)=1 and contains(@native,'error')">
-    <xsl:text>  if (checked_method->is_native()) {&#xA;</xsl:text>   
-    <xsl:text>    return JVMTI_ERROR_NATIVE_METHOD;&#xA;</xsl:text>   
-    <xsl:text>  }&#xA;</xsl:text>   
+    <xsl:text>  if (checked_method->is_native()) {&#xA;</xsl:text>
+    <xsl:text>    return JVMTI_ERROR_NATIVE_METHOD;&#xA;</xsl:text>
+    <xsl:text>  }&#xA;</xsl:text>
   </xsl:if>
 </xsl:template>
 
@@ -913,7 +913,7 @@ static jvmtiError JNICALL
   <xsl:text>  if (!JvmtiEnv::get_field_descriptor(k_oop, </xsl:text>
   <xsl:value-of select="$name"/>
   <xsl:text>, &amp;fdesc)) {&#xA;</xsl:text>
-  <xsl:apply-templates select=".." mode="traceError">     
+  <xsl:apply-templates select=".." mode="traceError">
     <xsl:with-param name="err">JVMTI_ERROR_INVALID_FIELDID</xsl:with-param>
   </xsl:apply-templates>
   <xsl:text>&#xA;</xsl:text>
@@ -930,7 +930,7 @@ static jvmtiError JNICALL
     <xsl:value-of select="@min"/>
     <xsl:text>) {
 </xsl:text>
-    <xsl:apply-templates select=".." mode="traceError">     
+    <xsl:apply-templates select=".." mode="traceError">
       <xsl:with-param name="err">JVMTI_ERROR_ILLEGAL_ARGUMENT</xsl:with-param>
     </xsl:apply-templates>
     <xsl:text>
@@ -1050,7 +1050,7 @@ static jvmtiError JNICALL
       <xsl:text>=" PTR_FORMAT "</xsl:text>
     </xsl:when>
     <xsl:otherwise>
-      <xsl:apply-templates select="$child" mode="traceInFormat"/> 
+      <xsl:apply-templates select="$child" mode="traceInFormat"/>
     </xsl:otherwise>
   </xsl:choose>
 </xsl:template>
@@ -1066,7 +1066,7 @@ static jvmtiError JNICALL
     <xsl:otherwise>
       <xsl:apply-templates select="$child" mode="traceInValue"/>
     </xsl:otherwise>
-  </xsl:choose> 
+  </xsl:choose>
 </xsl:template>
 
 <xsl:template match="inptr" mode="traceInFormat">
@@ -1118,8 +1118,8 @@ static jvmtiError JNICALL
   <xsl:param name="name"/>
   <!-- If we convert and test threads -->
   <xsl:if test="count(@impl)=0 or not(contains(@impl,'noconvert'))">
-    <xsl:text>, 
-                    JvmtiTrace::safe_get_thread_name(java_thread)</xsl:text>  
+    <xsl:text>,
+                    JvmtiTrace::safe_get_thread_name(java_thread)</xsl:text>
   </xsl:if>
 </xsl:template>
 
@@ -1137,7 +1137,7 @@ static jvmtiError JNICALL
 <xsl:template match="jclass" mode="traceInValue">
   <!-- for JVMTI a jclass/jmethodID becomes just jmethodID -->
   <xsl:if test="count(@method)=0">
-    <xsl:text>, 
+    <xsl:text>,
                     JvmtiTrace::get_class_name(k_mirror)</xsl:text>
   </xsl:if>
 </xsl:template>
@@ -1151,7 +1151,7 @@ static jvmtiError JNICALL
 
 <xsl:template match="jmethodID" mode="traceInValue">
   <xsl:param name="name"/>
-  <xsl:text>, 
+  <xsl:text>,
                     checked_method == NULL? "NULL" : checked_method->klass_name()->as_C_string(),
                     checked_method == NULL? "NULL" : checked_method->name()->as_C_string()
              </xsl:text>
@@ -1173,7 +1173,7 @@ static jvmtiError JNICALL
   <xsl:param name="name"/>
   <xsl:text>, </xsl:text>
   <xsl:value-of select="$name"/>
-  <xsl:text>, 
+  <xsl:text>,
                     </xsl:text>
   <xsl:choose>
     <xsl:when test=".='jvmtiError'">
diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp
index a2b90d1c271..d50f903c7df 100644
--- a/src/hotspot/share/prims/jvmtiEnv.cpp
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp
@@ -3308,7 +3308,7 @@ JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {
   } else {
     Thread* thread = Thread::current();
     if (thread->is_Java_thread()) {
-      JavaThread* current_thread = (JavaThread*)thread;
+      JavaThread* current_thread = thread->as_Java_thread();
 
       /* Transition to thread_blocked without entering vm state          */
       /* This is really evil. Normally you can't undo _thread_blocked    */
diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp
index 513acfe68bf..21acadd8a71 100644
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp
@@ -663,13 +663,13 @@ JvmtiEnvBase::get_current_contended_monitor(JavaThread *calling_thread, JavaThre
     mon = java_thread->current_pending_monitor();
     if (mon != NULL) {
       // The thread is trying to enter() an ObjectMonitor.
-      obj = (oop)mon->object();
+      obj = mon->object();
       assert(obj != NULL, "ObjectMonitor should have a valid object!");
     }
     // implied else: no contended ObjectMonitor
   } else {
     // thread is doing an Object.wait() call
-    obj = (oop)mon->object();
+    obj = mon->object();
     assert(obj != NULL, "Object.wait() should have an object");
   }
 
@@ -741,7 +741,7 @@ JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread
     // Save object of current wait() call (if any) for later comparison.
     ObjectMonitor *mon = java_thread->current_waiting_monitor();
     if (mon != NULL) {
-      wait_obj = (oop)mon->object();
+      wait_obj = mon->object();
     }
   }
   oop pending_obj = NULL;
@@ -752,7 +752,7 @@ JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread
     // Save object of current enter() call (if any) for later comparison.
     ObjectMonitor *mon = java_thread->current_pending_monitor();
     if (mon != NULL) {
-      pending_obj = (oop)mon->object();
+      pending_obj = mon->object();
     }
   }
 
@@ -1077,7 +1077,7 @@ JvmtiEnvBase::get_object_monitor_usage(JavaThread* calling_thread, jobject objec
           }
           Thread *t = mon->thread_of_waiter(waiter);
           if (t != NULL && t->is_Java_thread()) {
-            JavaThread *wjava_thread = (JavaThread *)t;
+            JavaThread *wjava_thread = t->as_Java_thread();
             // If the thread was found on the ObjectWaiter list, then
             // it has not been notified. This thread can't change the
             // state of the monitor so it doesn't need to be suspended.
@@ -1268,8 +1268,7 @@ VM_GetThreadListStackTraces::doit() {
 
 void
 GetSingleStackTraceClosure::do_thread(Thread *target) {
-  assert(target->is_Java_thread(), "just checking");
-  JavaThread *jt = (JavaThread *)target;
+  JavaThread *jt = target->as_Java_thread();
   oop thread_oop = jt->threadObj();
 
   if (!jt->is_exiting() && thread_oop != NULL) {
@@ -1435,7 +1434,7 @@ JvmtiMonitorClosure::do_monitor(ObjectMonitor* mon) {
   }
   if (mon->owner() == _java_thread ) {
     // Filter out on stack monitors collected during stack walk.
-    oop obj = (oop)mon->object();
+    oop obj = mon->object();
     bool found = false;
     for (int j = 0; j < _owned_monitors_list->length(); j++) {
       jobject jobj = ((jvmtiMonitorStackDepthInfo*)_owned_monitors_list->at(j))->monitor;
@@ -1526,8 +1525,7 @@ SetFramePopClosure::do_thread(Thread *target) {
 
 void
 GetOwnedMonitorInfoClosure::do_thread(Thread *target) {
-  assert(target->is_Java_thread(), "just checking");
-  JavaThread *jt = (JavaThread *)target;
+  JavaThread *jt = target->as_Java_thread();
   if (!jt->is_exiting() && (jt->threadObj() != NULL)) {
     _result = ((JvmtiEnvBase *)_env)->get_owned_monitors(_calling_thread,
                                                          jt,
@@ -1537,8 +1535,7 @@ GetOwnedMonitorInfoClosure::do_thread(Thread *target) {
 
 void
 GetCurrentContendedMonitorClosure::do_thread(Thread *target) {
-  assert(target->is_Java_thread(), "just checking");
-  JavaThread *jt = (JavaThread *)target;
+  JavaThread *jt = target->as_Java_thread();
   if (!jt->is_exiting() && (jt->threadObj() != NULL)) {
     _result = ((JvmtiEnvBase *)_env)->get_current_contended_monitor(_calling_thread,
                                                                     jt,
@@ -1548,8 +1545,7 @@ GetCurrentContendedMonitorClosure::do_thread(Thread *target) {
 
 void
 GetStackTraceClosure::do_thread(Thread *target) {
-  assert(target->is_Java_thread(), "just checking");
-  JavaThread *jt = (JavaThread *)target;
+  JavaThread *jt = target->as_Java_thread();
   if (!jt->is_exiting() && jt->threadObj() != NULL) {
     _result = ((JvmtiEnvBase *)_env)->get_stack_trace(jt,
                                                       _start_depth, _max_count,
@@ -1568,8 +1564,7 @@ GetFrameCountClosure::do_thread(Thread *target) {
 
 void
 GetFrameLocationClosure::do_thread(Thread *target) {
-  assert(target->is_Java_thread(), "just checking");
-  JavaThread *jt = (JavaThread *)target;
+  JavaThread *jt = target->as_Java_thread();
   if (!jt->is_exiting() && jt->threadObj() != NULL) {
     _result = ((JvmtiEnvBase*)_env)->get_frame_location(jt, _depth,
                                                         _method_ptr, _location_ptr);
diff --git a/src/hotspot/share/prims/jvmtiEnvThreadState.cpp b/src/hotspot/share/prims/jvmtiEnvThreadState.cpp
index e58f2031dab..c6ed99e4a67 100644
--- a/src/hotspot/share/prims/jvmtiEnvThreadState.cpp
+++ b/src/hotspot/share/prims/jvmtiEnvThreadState.cpp
@@ -255,7 +255,7 @@ class GetCurrentLocationClosure : public HandshakeClosure {
       _method_id(NULL),
       _bci(0) {}
   void do_thread(Thread *target) {
-    JavaThread *jt = (JavaThread *)target;
+    JavaThread *jt = target->as_Java_thread();
     ResourceMark rmark; // jt != Thread::current()
     RegisterMap rm(jt, false);
     // There can be a race condition between a VM_Operation reaching a safepoint
diff --git a/src/hotspot/share/prims/jvmtiEventController.cpp b/src/hotspot/share/prims/jvmtiEventController.cpp
index 586f0f277fe..5d6b49b22aa 100644
--- a/src/hotspot/share/prims/jvmtiEventController.cpp
+++ b/src/hotspot/share/prims/jvmtiEventController.cpp
@@ -198,7 +198,7 @@ class EnterInterpOnlyModeClosure : public HandshakeClosure {
 public:
   EnterInterpOnlyModeClosure() : HandshakeClosure("EnterInterpOnlyMode") { }
   void do_thread(Thread* th) {
-    JavaThread* jt = (JavaThread*) th;
+    JavaThread* jt = th->as_Java_thread();
     JvmtiThreadState* state = jt->jvmti_thread_state();
 
     // Set up the current stack depth for later tracking
@@ -331,8 +331,7 @@ void JvmtiEventControllerPrivate::enter_interp_only_mode(JvmtiThreadState *state
   EC_TRACE(("[%s] # Entering interpreter only mode",
             JvmtiTrace::safe_get_thread_name(state->get_thread())));
   EnterInterpOnlyModeClosure hs;
-  assert(state->get_thread()->is_Java_thread(), "just checking");
-  JavaThread *target = (JavaThread *)state->get_thread();
+  JavaThread *target = state->get_thread();
   Thread *current = Thread::current();
   if (target == current || target->active_handshaker() == current) {
     hs.do_thread(target);
@@ -645,7 +644,6 @@ JvmtiEventControllerPrivate::recompute_enabled() {
 
 void
 JvmtiEventControllerPrivate::thread_started(JavaThread *thread) {
-  assert(thread->is_Java_thread(), "Must be JavaThread");
   assert(thread == Thread::current(), "must be current thread");
   assert(JvmtiEnvBase::environments_might_exist(), "to enter event controller, JVM TI environments must exist");
 
diff --git a/src/hotspot/share/prims/jvmtiExport.cpp b/src/hotspot/share/prims/jvmtiExport.cpp
index d97ade70d2d..bfe5d574a7c 100644
--- a/src/hotspot/share/prims/jvmtiExport.cpp
+++ b/src/hotspot/share/prims/jvmtiExport.cpp
@@ -108,7 +108,7 @@ class JvmtiThreadEventTransition : StackObj {
 public:
   JvmtiThreadEventTransition(Thread *thread) : _rm(), _hm(thread) {
     if (thread->is_Java_thread()) {
-       _jthread = (JavaThread *)thread;
+       _jthread = thread->as_Java_thread();
        _saved_state = _jthread->thread_state();
        if (_saved_state == _thread_in_Java) {
          ThreadStateTransition::transition_from_java(_jthread, _thread_in_native);
@@ -2306,7 +2306,7 @@ void JvmtiExport::record_vm_internal_object_allocation(oop obj) {
     NoSafepointVerifier no_sfpt;
     // Cannot take safepoint here so do not use state_for to get
     // jvmti thread state.
-    JvmtiThreadState *state = ((JavaThread*)thread)->jvmti_thread_state();
+    JvmtiThreadState *state = thread->as_Java_thread()->jvmti_thread_state();
     if (state != NULL) {
       // state is non NULL when VMObjectAllocEventCollector is enabled.
       JvmtiVMObjectAllocEventCollector *collector;
@@ -2330,7 +2330,7 @@ void JvmtiExport::record_sampled_internal_object_allocation(oop obj) {
     NoSafepointVerifier no_sfpt;
     // Cannot take safepoint here so do not use state_for to get
     // jvmti thread state.
-    JvmtiThreadState *state = ((JavaThread*)thread)->jvmti_thread_state();
+    JvmtiThreadState *state = thread->as_Java_thread()->jvmti_thread_state();
     if (state != NULL) {
       // state is non NULL when SampledObjectAllocEventCollector is enabled.
       JvmtiSampledObjectAllocEventCollector *collector;
@@ -2407,7 +2407,7 @@ void JvmtiExport::post_data_dump() {
 }
 
 void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor *obj_mntr) {
-  oop object = (oop)obj_mntr->object();
+  oop object = obj_mntr->object();
   JvmtiThreadState *state = thread->jvmti_thread_state();
   if (state == NULL) {
     return;
@@ -2438,7 +2438,7 @@ void JvmtiExport::post_monitor_contended_enter(JavaThread *thread, ObjectMonitor
 }
 
 void JvmtiExport::post_monitor_contended_entered(JavaThread *thread, ObjectMonitor *obj_mntr) {
-  oop object = (oop)obj_mntr->object();
+  oop object = obj_mntr->object();
   JvmtiThreadState *state = thread->jvmti_thread_state();
   if (state == NULL) {
     return;
@@ -2501,7 +2501,7 @@ void JvmtiExport::post_monitor_wait(JavaThread *thread, oop object,
 }
 
 void JvmtiExport::post_monitor_waited(JavaThread *thread, ObjectMonitor *obj_mntr, jboolean timed_out) {
-  oop object = (oop)obj_mntr->object();
+  oop object = obj_mntr->object();
   JvmtiThreadState *state = thread->jvmti_thread_state();
   if (state == NULL) {
     return;
@@ -2867,7 +2867,7 @@ NoJvmtiVMObjectAllocMark::NoJvmtiVMObjectAllocMark() : _collector(NULL) {
   }
   Thread* thread = Thread::current_or_null();
   if (thread != NULL && thread->is_Java_thread())  {
-    JavaThread* current_thread = (JavaThread*)thread;
+    JavaThread* current_thread = thread->as_Java_thread();
     JvmtiThreadState *state = current_thread->jvmti_thread_state();
     if (state != NULL) {
       JvmtiVMObjectAllocEventCollector *collector;
diff --git a/src/hotspot/share/prims/jvmtiImpl.cpp b/src/hotspot/share/prims/jvmtiImpl.cpp
index 7d64a88efff..68f589ac3d2 100644
--- a/src/hotspot/share/prims/jvmtiImpl.cpp
+++ b/src/hotspot/share/prims/jvmtiImpl.cpp
@@ -73,7 +73,6 @@ JvmtiAgentThread::start_function_wrapper(JavaThread *thread, TRAPS) {
     // It is expected that any Agent threads will be created as
     // Java Threads.  If this is the case, notification of the creation
     // of the thread is given in JavaThread::thread_main().
-    assert(thread->is_Java_thread(), "debugger thread should be a Java Thread");
     assert(thread == JavaThread::current(), "sanity check");
 
     JvmtiAgentThread *dthread = (JvmtiAgentThread *)thread;
diff --git a/src/hotspot/share/prims/jvmtiRawMonitor.cpp b/src/hotspot/share/prims/jvmtiRawMonitor.cpp
index 0e8d38498fc..06efea26c5f 100644
--- a/src/hotspot/share/prims/jvmtiRawMonitor.cpp
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -234,7 +234,7 @@ int JvmtiRawMonitor::simple_wait(Thread* self, jlong millis) {
 
   int ret = M_OK;
   if (self->is_Java_thread()) {
-    JavaThread* jt = (JavaThread*) self;
+    JavaThread* jt = self->as_Java_thread();
     // Transition to VM so we can check interrupt state
     ThreadInVMfromNative tivm(jt);
     if (jt->is_interrupted(true)) {
@@ -314,7 +314,7 @@ void JvmtiRawMonitor::raw_enter(Thread* self) {
   // don't enter raw monitor if thread is being externally suspended, it will
   // surprise the suspender if a "suspended" thread can still enter monitor
   if (self->is_Java_thread()) {
-    jt = (JavaThread*)self;
+    jt = self->as_Java_thread();
     jt->SR_lock()->lock_without_safepoint_check();
     while (jt->is_external_suspend()) {
       jt->SR_lock()->unlock();
@@ -410,7 +410,7 @@ int JvmtiRawMonitor::raw_wait(jlong millis, Thread* self) {
   guarantee(self == _owner, "invariant");
 
   if (self->is_Java_thread()) {
-    JavaThread* jt = (JavaThread*)self;
+    JavaThread* jt = self->as_Java_thread();
     for (;;) {
       jt->set_suspend_equivalent();
       if (!jt->handle_special_suspend_equivalent_condition()) {
diff --git a/src/hotspot/share/prims/jvmtiThreadState.cpp b/src/hotspot/share/prims/jvmtiThreadState.cpp
index 5c80a2c6b68..2bcf10689e1 100644
--- a/src/hotspot/share/prims/jvmtiThreadState.cpp
+++ b/src/hotspot/share/prims/jvmtiThreadState.cpp
@@ -241,7 +241,7 @@ int JvmtiThreadState::count_frames() {
 
 void JvmtiThreadState::invalidate_cur_stack_depth() {
   assert(SafepointSynchronize::is_at_safepoint() ||
-         (JavaThread *)Thread::current() == get_thread() ||
+         JavaThread::current() == get_thread() ||
          Thread::current() == get_thread()->active_handshaker(),
          "bad synchronization with owner thread");
 
@@ -272,7 +272,7 @@ void JvmtiThreadState::decr_cur_stack_depth() {
 }
 
 int JvmtiThreadState::cur_stack_depth() {
-  Thread *current = Thread::current();
+  JavaThread *current = JavaThread::current();
   guarantee(current == get_thread() || current == get_thread()->active_handshaker(),
             "must be current thread or direct handshake");
 
diff --git a/src/hotspot/share/prims/jvmtiTrace.cpp b/src/hotspot/share/prims/jvmtiTrace.cpp
index fd8c85cae36..e620c996c93 100644
--- a/src/hotspot/share/prims/jvmtiTrace.cpp
+++ b/src/hotspot/share/prims/jvmtiTrace.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -276,8 +276,7 @@ const char *JvmtiTrace::safe_get_thread_name(Thread *thread) {
   if (!thread->is_Java_thread()) {
     return thread->name();
   }
-  JavaThread *java_thread = (JavaThread *)thread;
-  oop threadObj = java_thread->threadObj();
+  oop threadObj = thread->as_Java_thread()->threadObj();
   if (threadObj == NULL) {
     return "NULL";
   }
diff --git a/src/hotspot/share/prims/stackwalk.cpp b/src/hotspot/share/prims/stackwalk.cpp
index f7f4f0d4ca4..6c0b973058a 100644
--- a/src/hotspot/share/prims/stackwalk.cpp
+++ b/src/hotspot/share/prims/stackwalk.cpp
@@ -79,7 +79,6 @@ void JavaFrameStream::next() { _vfst.next();}
 BaseFrameStream* BaseFrameStream::from_current(JavaThread* thread, jlong magic,
                                                objArrayHandle frames_array)
 {
-  assert(thread != NULL && thread->is_Java_thread(), "");
   oop m1 = frames_array->obj_at(magic_pos);
   if (m1 != thread->threadObj()) return NULL;
   if (magic == 0L)                    return NULL;
@@ -338,7 +337,7 @@ oop StackWalk::walk(Handle stackStream, jlong mode,
                     objArrayHandle frames_array,
                     TRAPS) {
   ResourceMark rm(THREAD);
-  JavaThread* jt = (JavaThread*)THREAD;
+  JavaThread* jt = THREAD->as_Java_thread();
   log_debug(stackwalk)("Start walking: mode " JLONG_FORMAT " skip %d frames batch size %d",
                        mode, skip_frames, frame_count);
 
@@ -458,7 +457,7 @@ jint StackWalk::fetchNextBatch(Handle stackStream, jlong mode, jlong magic,
                                objArrayHandle frames_array,
                                TRAPS)
 {
-  JavaThread* jt = (JavaThread*)THREAD;
+  JavaThread* jt = THREAD->as_Java_thread();
   BaseFrameStream* existing_stream = BaseFrameStream::from_current(jt, magic, frames_array);
   if (existing_stream == NULL) {
     THROW_MSG_(vmSymbols::java_lang_InternalError(), "doStackWalk: corrupted buffers", 0L);
diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp
index 6440de7f829..586c2b7d9cc 100644
--- a/src/hotspot/share/prims/whitebox.cpp
+++ b/src/hotspot/share/prims/whitebox.cpp
@@ -1997,8 +1997,7 @@ WB_ENTRY(jint, WB_HandshakeWalkStack(JNIEnv* env, jobject wb, jobject thread_han
     jint _num_threads_completed;
 
     void do_thread(Thread* th) {
-      assert(th->is_Java_thread(), "sanity");
-      JavaThread* jt = (JavaThread*)th;
+      JavaThread* jt = th->as_Java_thread();
       ResourceMark rm;
 
       jt->print_on(tty);
diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp
index 9b6a60db41c..adf05cc4231 100644
--- a/src/hotspot/share/runtime/arguments.cpp
+++ b/src/hotspot/share/runtime/arguments.cpp
@@ -1459,7 +1459,14 @@ bool Arguments::add_property(const char* prop, PropertyWriteable writeable, Prop
   if (is_internal_module_property(key) ||
       strcmp(key, "jdk.module.main") == 0) {
     MetaspaceShared::disable_optimized_module_handling();
-    log_info(cds)("Using optimized module handling disabled due to incompatible property: %s=%s", key, value);
+    log_info(cds)("optimized module handling: disabled due to incompatible property: %s=%s", key, value);
+  }
+  if (strcmp(key, "jdk.module.showModuleResolution") == 0 ||
+      strcmp(key, "jdk.module.illegalAccess") == 0 ||
+      strcmp(key, "jdk.module.validation") == 0 ||
+      strcmp(key, "java.system.class.loader") == 0) {
+    MetaspaceShared::disable_full_module_graph();
+    log_info(cds)("full module graph: disabled due to incompatible property: %s=%s", key, value);
   }
 #endif
 
@@ -2508,7 +2515,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
       Arguments::append_sysclasspath(tail);
 #if INCLUDE_CDS
       MetaspaceShared::disable_optimized_module_handling();
-      log_info(cds)("Using optimized module handling disabled due to bootclasspath was appended");
+      log_info(cds)("optimized module handling: disabled because bootclasspath was appended");
 #endif
     // -bootclasspath/p:
     } else if (match_option(option, "-Xbootclasspath/p:", &tail)) {
@@ -3898,10 +3905,7 @@ bool Arguments::handle_deprecated_print_gc_flags() {
 
 jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) {
   assert(verify_special_jvm_flags(false), "deprecated and obsolete flag table inconsistent");
-
-  // Initialize ranges and constraints
-  JVMFlagRangeList::init();
-  JVMFlagConstraintList::init();
+  JVMFlag::check_all_flag_declarations();
 
   // If flag "-XX:Flags=flags-file" is used it will be the first option to be processed.
   const char* hotspotrc = ".hotspotrc";
diff --git a/src/hotspot/share/runtime/biasedLocking.cpp b/src/hotspot/share/runtime/biasedLocking.cpp
index fa39d0b91a2..9d4a03834b8 100644
--- a/src/hotspot/share/runtime/biasedLocking.cpp
+++ b/src/hotspot/share/runtime/biasedLocking.cpp
@@ -725,8 +725,7 @@ void BiasedLocking::walk_stack_and_revoke(oop obj, JavaThread* biased_locker) {
 }
 
 void BiasedLocking::revoke_own_lock(Handle obj, TRAPS) {
-  assert(THREAD->is_Java_thread(), "must be called by a JavaThread");
-  JavaThread* thread = (JavaThread*)THREAD;
+  JavaThread* thread = THREAD->as_Java_thread();
 
   markWord mark = obj->mark();
 
@@ -740,7 +739,7 @@ void BiasedLocking::revoke_own_lock(Handle obj, TRAPS) {
   ResourceMark rm;
   log_info(biasedlocking)("Revoking bias by walking my own stack:");
   EventBiasedLockSelfRevocation event;
-  BiasedLocking::walk_stack_and_revoke(obj(), (JavaThread*) thread);
+  BiasedLocking::walk_stack_and_revoke(obj(), thread);
   thread->set_cached_monitor_info(NULL);
   assert(!obj->mark().has_bias_pattern(), "invariant");
   if (event.should_commit()) {
@@ -830,7 +829,7 @@ void BiasedLocking::revoke(Handle obj, TRAPS) {
         }
         return;
       } else {
-        BiasedLocking::Condition cond = single_revoke_with_handshake(obj, (JavaThread*)THREAD, blt);
+        BiasedLocking::Condition cond = single_revoke_with_handshake(obj, THREAD->as_Java_thread(), blt);
         if (cond != NOT_REVOKED) {
           return;
         }
@@ -839,7 +838,7 @@ void BiasedLocking::revoke(Handle obj, TRAPS) {
       assert((heuristics == HR_BULK_REVOKE) ||
          (heuristics == HR_BULK_REBIAS), "?");
       EventBiasedLockClassRevocation event;
-      VM_BulkRevokeBias bulk_revoke(&obj, (JavaThread*)THREAD,
+      VM_BulkRevokeBias bulk_revoke(&obj, THREAD->as_Java_thread(),
                                     (heuristics == HR_BULK_REBIAS));
       VMThread::execute(&bulk_revoke);
       if (event.should_commit()) {
diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp
index 8e88fda441b..7e9d23e9c6a 100644
--- a/src/hotspot/share/runtime/deoptimization.cpp
+++ b/src/hotspot/share/runtime/deoptimization.cpp
@@ -810,7 +810,7 @@ class DeoptimizeMarkedClosure : public HandshakeClosure {
  public:
   DeoptimizeMarkedClosure() : HandshakeClosure("Deoptimize") {}
   void do_thread(Thread* thread) {
-    JavaThread* jt = (JavaThread*)thread;
+    JavaThread* jt = thread->as_Java_thread();
     jt->deoptimize_marked_methods();
   }
 };
@@ -1697,8 +1697,7 @@ void Deoptimization::load_class_by_index(const constantPoolHandle& constant_pool
     // to the runtime the stack is no longer guarded. Reguard the
     // stack otherwise if we return to the uncommon trap blob and the
     // stack bang causes a stack overflow we crash.
-    assert(THREAD->is_Java_thread(), "only a java thread can be here");
-    JavaThread* thread = (JavaThread*)THREAD;
+    JavaThread* thread = THREAD->as_Java_thread();
     bool guard_pages_enabled = thread->stack_guards_enabled();
     if (!guard_pages_enabled) guard_pages_enabled = thread->reguard_stack();
     assert(guard_pages_enabled, "stack banging in uncommon trap blob may cause crash");
diff --git a/src/hotspot/share/runtime/flags/jvmFlag.cpp b/src/hotspot/share/runtime/flags/jvmFlag.cpp
index 4611155d7ee..4d44a58a34c 100644
--- a/src/hotspot/share/runtime/flags/jvmFlag.cpp
+++ b/src/hotspot/share/runtime/flags/jvmFlag.cpp
@@ -28,6 +28,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/flags/jvmFlag.hpp"
 #include "runtime/flags/jvmFlagConstraintList.hpp"
+#include "runtime/flags/jvmFlagLookup.hpp"
 #include "runtime/flags/jvmFlagRangeList.hpp"
 #include "runtime/globals_extension.hpp"
 #include "utilities/defaultStream.hpp"
@@ -131,7 +132,7 @@ bool JVMFlag::ccstr_accumulates() const {
   return strcmp(_type, "ccstrlist") == 0;
 }
 
-JVMFlag::Flags JVMFlag::get_origin() {
+JVMFlag::Flags JVMFlag::get_origin() const {
   return Flags(_flags & VALUE_ORIGIN_MASK);
 }
 
@@ -141,19 +142,19 @@ void JVMFlag::set_origin(Flags origin) {
   _flags = Flags((_flags & ~VALUE_ORIGIN_MASK) | new_origin);
 }
 
-bool JVMFlag::is_default() {
+bool JVMFlag::is_default() const {
   return (get_origin() == DEFAULT);
 }
 
-bool JVMFlag::is_ergonomic() {
+bool JVMFlag::is_ergonomic() const {
   return (get_origin() == ERGONOMIC);
 }
 
-bool JVMFlag::is_command_line() {
+bool JVMFlag::is_command_line() const {
   return (_flags & ORIG_COMMAND_LINE) != 0;
 }
 
-bool JVMFlag::is_jimage_resource() {
+bool JVMFlag::is_jimage_resource() const {
   return (get_origin() == JIMAGE_RESOURCE);
 }
 
@@ -185,10 +186,6 @@ bool JVMFlag::is_develop() const {
   return (_flags & KIND_DEVELOP) != 0;
 }
 
-bool JVMFlag::is_read_write() const {
-  return (_flags & KIND_READ_WRITE) != 0;
-}
-
 /**
  * Returns if this flag is a constant in the binary.  Right now this is
  * true for notproduct and develop flags in product builds.
@@ -224,13 +221,13 @@ void JVMFlag::clear_diagnostic() {
 
 void JVMFlag::clear_experimental() {
   assert(is_experimental(), "sanity");
- _flags = Flags(_flags & ~KIND_EXPERIMENTAL);
+  _flags = Flags(_flags & ~KIND_EXPERIMENTAL);
   assert(!is_experimental(), "sanity");
 }
 
 void JVMFlag::set_product() {
   assert(!is_product(), "sanity");
- _flags = Flags(_flags | KIND_PRODUCT);
+  _flags = Flags(_flags | KIND_PRODUCT);
   assert(is_product(), "sanity");
 }
 
@@ -266,7 +263,7 @@ JVMFlag::MsgType JVMFlag::get_locked_message(char* buf, int buflen) const {
 }
 
 bool JVMFlag::is_writeable() const {
-  return is_manageable() || (is_product() && is_read_write());
+  return is_manageable();
 }
 
 // All flags except "manageable" are assumed to be internal flags.
@@ -288,7 +285,7 @@ void fill_to_pos(outputStream* st, unsigned int req_pos) {
   }
 }
 
-void JVMFlag::print_on(outputStream* st, bool withComments, bool printRanges) {
+void JVMFlag::print_on(outputStream* st, bool withComments, bool printRanges) const {
   // Don't print notproduct and develop flags in a product build.
   if (is_constant_in_binary()) {
     return;
@@ -496,7 +493,7 @@ void JVMFlag::print_on(outputStream* st, bool withComments, bool printRanges) {
   }
 }
 
-void JVMFlag::print_kind(outputStream* st, unsigned int width) {
+void JVMFlag::print_kind(outputStream* st, unsigned int width) const {
   struct Data {
     int flag;
     const char* name;
@@ -515,7 +512,6 @@ void JVMFlag::print_kind(outputStream* st, unsigned int width) {
     { KIND_NOT_PRODUCT, "notproduct" },
     { KIND_DEVELOP, "develop" },
     { KIND_LP64_PRODUCT, "lp64_product" },
-    { KIND_READ_WRITE, "rw" },
     { -1, "" }
   };
 
@@ -549,7 +545,7 @@ void JVMFlag::print_kind(outputStream* st, unsigned int width) {
   }
 }
 
-void JVMFlag::print_origin(outputStream* st, unsigned int width) {
+void JVMFlag::print_origin(outputStream* st, unsigned int width) const {
   int origin = _flags & VALUE_ORIGIN_MASK;
   st->print("{");
   switch(origin) {
@@ -578,7 +574,7 @@ void JVMFlag::print_origin(outputStream* st, unsigned int width) {
   st->print("}");
 }
 
-void JVMFlag::print_as_flag(outputStream* st) {
+void JVMFlag::print_as_flag(outputStream* st) const {
   if (is_bool()) {
     st->print("-XX:%s%s", get_bool() ? "+" : "-", _name);
   } else if (is_int()) {
@@ -633,167 +629,125 @@ const char* JVMFlag::flag_error_str(JVMFlag::Error error) {
   }
 }
 
-// 4991491 do not "optimize out" the was_set false values: omitting them
-// tickles a Microsoft compiler bug causing flagTable to be malformed
-
-#define RUNTIME_PRODUCT_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_PRODUCT) },
-#define RUNTIME_PD_PRODUCT_FLAG_STRUCT(  type, name,        doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_PRODUCT | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define RUNTIME_DIAGNOSTIC_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_DIAGNOSTIC) },
-#define RUNTIME_PD_DIAGNOSTIC_FLAG_STRUCT(type, name,       doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_DIAGNOSTIC | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define RUNTIME_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_EXPERIMENTAL) },
-#define RUNTIME_MANAGEABLE_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_MANAGEABLE) },
-#define RUNTIME_PRODUCT_RW_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_PRODUCT | JVMFlag::KIND_READ_WRITE) },
-#define RUNTIME_DEVELOP_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_DEVELOP) },
-#define RUNTIME_PD_DEVELOP_FLAG_STRUCT(  type, name,        doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_DEVELOP | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define RUNTIME_NOTPRODUCT_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_NOT_PRODUCT) },
-
-#define JVMCI_PRODUCT_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_JVMCI | JVMFlag::KIND_PRODUCT) },
-#define JVMCI_PD_PRODUCT_FLAG_STRUCT(    type, name,        doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_JVMCI | JVMFlag::KIND_PRODUCT | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define JVMCI_DIAGNOSTIC_FLAG_STRUCT(    type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_JVMCI | JVMFlag::KIND_DIAGNOSTIC) },
-#define JVMCI_PD_DIAGNOSTIC_FLAG_STRUCT( type, name,        doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_JVMCI | JVMFlag::KIND_DIAGNOSTIC | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define JVMCI_EXPERIMENTAL_FLAG_STRUCT(  type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_JVMCI | JVMFlag::KIND_EXPERIMENTAL) },
-#define JVMCI_DEVELOP_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_JVMCI | JVMFlag::KIND_DEVELOP) },
-#define JVMCI_PD_DEVELOP_FLAG_STRUCT(    type, name,        doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_JVMCI | JVMFlag::KIND_DEVELOP | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define JVMCI_NOTPRODUCT_FLAG_STRUCT(    type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_JVMCI | JVMFlag::KIND_NOT_PRODUCT) },
-
-#ifdef _LP64
-#define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_LP64_PRODUCT) },
-#else
-#define RUNTIME_LP64_PRODUCT_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
-#endif // _LP64
-
-#define C1_PRODUCT_FLAG_STRUCT(          type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C1 | JVMFlag::KIND_PRODUCT) },
-#define C1_PD_PRODUCT_FLAG_STRUCT(       type, name,        doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C1 | JVMFlag::KIND_PRODUCT | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define C1_DIAGNOSTIC_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C1 | JVMFlag::KIND_DIAGNOSTIC) },
-#define C1_PD_DIAGNOSTIC_FLAG_STRUCT(    type, name,        doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C1 | JVMFlag::KIND_DIAGNOSTIC | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define C1_DEVELOP_FLAG_STRUCT(          type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C1 | JVMFlag::KIND_DEVELOP) },
-#define C1_PD_DEVELOP_FLAG_STRUCT(       type, name,        doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C1 | JVMFlag::KIND_DEVELOP | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define C1_NOTPRODUCT_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C1 | JVMFlag::KIND_NOT_PRODUCT) },
-
-#define C2_PRODUCT_FLAG_STRUCT(          type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C2 | JVMFlag::KIND_PRODUCT) },
-#define C2_PD_PRODUCT_FLAG_STRUCT(       type, name,        doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C2 | JVMFlag::KIND_PRODUCT | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define C2_DIAGNOSTIC_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C2 | JVMFlag::KIND_DIAGNOSTIC) },
-#define C2_PD_DIAGNOSTIC_FLAG_STRUCT(    type, name,        doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C2 | JVMFlag::KIND_DIAGNOSTIC | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define C2_EXPERIMENTAL_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C2 | JVMFlag::KIND_EXPERIMENTAL) },
-#define C2_DEVELOP_FLAG_STRUCT(          type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C2 | JVMFlag::KIND_DEVELOP) },
-#define C2_PD_DEVELOP_FLAG_STRUCT(       type, name,        doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C2 | JVMFlag::KIND_DEVELOP | JVMFlag::KIND_PLATFORM_DEPENDENT) },
-#define C2_NOTPRODUCT_FLAG_STRUCT(       type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_C2 | JVMFlag::KIND_NOT_PRODUCT) },
-
-#define ARCH_PRODUCT_FLAG_STRUCT(        type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_ARCH | JVMFlag::KIND_PRODUCT) },
-#define ARCH_DIAGNOSTIC_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_ARCH | JVMFlag::KIND_DIAGNOSTIC) },
-#define ARCH_EXPERIMENTAL_FLAG_STRUCT(   type, name, value, doc) { #type, XSTR(name), &name,         NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_ARCH | JVMFlag::KIND_EXPERIMENTAL) },
-#define ARCH_DEVELOP_FLAG_STRUCT(        type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_ARCH | JVMFlag::KIND_DEVELOP) },
-#define ARCH_NOTPRODUCT_FLAG_STRUCT(     type, name, value, doc) { #type, XSTR(name), (void*) &name, NOT_PRODUCT_ARG(doc) JVMFlag::Flags(JVMFlag::DEFAULT | JVMFlag::KIND_ARCH | JVMFlag::KIND_NOT_PRODUCT) },
-
-static JVMFlag flagTable[] = {
-  VM_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
-           RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
-           RUNTIME_PRODUCT_FLAG_STRUCT, \
-           RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
-           RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
-           RUNTIME_PD_DIAGNOSTIC_FLAG_STRUCT, \
-           RUNTIME_EXPERIMENTAL_FLAG_STRUCT, \
-           RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
-           RUNTIME_MANAGEABLE_FLAG_STRUCT, \
-           RUNTIME_PRODUCT_RW_FLAG_STRUCT, \
-           RUNTIME_LP64_PRODUCT_FLAG_STRUCT, \
-           IGNORE_RANGE, \
-           IGNORE_CONSTRAINT)
-
-  RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_STRUCT, \
-                   RUNTIME_PD_DEVELOP_FLAG_STRUCT, \
-                   RUNTIME_PRODUCT_FLAG_STRUCT, \
-                   RUNTIME_PD_PRODUCT_FLAG_STRUCT, \
-                   RUNTIME_DIAGNOSTIC_FLAG_STRUCT, \
-                   RUNTIME_PD_DIAGNOSTIC_FLAG_STRUCT, \
-                   RUNTIME_NOTPRODUCT_FLAG_STRUCT, \
-                   IGNORE_RANGE, \
-                   IGNORE_CONSTRAINT)
-#if INCLUDE_JVMCI
-  JVMCI_FLAGS(JVMCI_DEVELOP_FLAG_STRUCT, \
-              JVMCI_PD_DEVELOP_FLAG_STRUCT, \
-              JVMCI_PRODUCT_FLAG_STRUCT, \
-              JVMCI_PD_PRODUCT_FLAG_STRUCT, \
-              JVMCI_DIAGNOSTIC_FLAG_STRUCT, \
-              JVMCI_PD_DIAGNOSTIC_FLAG_STRUCT, \
-              JVMCI_EXPERIMENTAL_FLAG_STRUCT, \
-              JVMCI_NOTPRODUCT_FLAG_STRUCT, \
-              IGNORE_RANGE, \
-              IGNORE_CONSTRAINT)
-#endif // INCLUDE_JVMCI
-#ifdef COMPILER1
-  C1_FLAGS(C1_DEVELOP_FLAG_STRUCT, \
-           C1_PD_DEVELOP_FLAG_STRUCT, \
-           C1_PRODUCT_FLAG_STRUCT, \
-           C1_PD_PRODUCT_FLAG_STRUCT, \
-           C1_DIAGNOSTIC_FLAG_STRUCT, \
-           C1_PD_DIAGNOSTIC_FLAG_STRUCT, \
-           C1_NOTPRODUCT_FLAG_STRUCT, \
-           IGNORE_RANGE, \
-           IGNORE_CONSTRAINT)
-#endif // COMPILER1
-#ifdef COMPILER2
-  C2_FLAGS(C2_DEVELOP_FLAG_STRUCT, \
-           C2_PD_DEVELOP_FLAG_STRUCT, \
-           C2_PRODUCT_FLAG_STRUCT, \
-           C2_PD_PRODUCT_FLAG_STRUCT, \
-           C2_DIAGNOSTIC_FLAG_STRUCT, \
-           C2_PD_DIAGNOSTIC_FLAG_STRUCT, \
-           C2_EXPERIMENTAL_FLAG_STRUCT, \
-           C2_NOTPRODUCT_FLAG_STRUCT, \
-           IGNORE_RANGE, \
-           IGNORE_CONSTRAINT)
-#endif // COMPILER2
-  ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, \
-             ARCH_PRODUCT_FLAG_STRUCT, \
-             ARCH_DIAGNOSTIC_FLAG_STRUCT, \
-             ARCH_EXPERIMENTAL_FLAG_STRUCT, \
-             ARCH_NOTPRODUCT_FLAG_STRUCT, \
-             IGNORE_RANGE, \
-             IGNORE_CONSTRAINT)
-  {0, NULL, NULL}
+//----------------------------------------------------------------------
+// Build flagTable[]
+
+// Find out the number of LP64/JVMCI/COMPILER1/COMPILER1/ARCH flags,
+// for JVMFlag::flag_group()
+
+#define ENUM_F(type, name, ...)  enum_##name,
+#define IGNORE_F(...)
+
+//                                                  dev     dev-pd  pro     pro-pd  notpro  range     constraint
+enum FlagCounter_LP64  { LP64_RUNTIME_FLAGS(        ENUM_F, ENUM_F, ENUM_F, ENUM_F, ENUM_F, IGNORE_F, IGNORE_F)  num_flags_LP64   };
+enum FlagCounter_JVMCI { JVMCI_ONLY(JVMCI_FLAGS(    ENUM_F, ENUM_F, ENUM_F, ENUM_F, ENUM_F, IGNORE_F, IGNORE_F)) num_flags_JVMCI  };
+enum FlagCounter_C1    { COMPILER1_PRESENT(C1_FLAGS(ENUM_F, ENUM_F, ENUM_F, ENUM_F, ENUM_F, IGNORE_F, IGNORE_F)) num_flags_C1     };
+enum FlagCounter_C2    { COMPILER2_PRESENT(C2_FLAGS(ENUM_F, ENUM_F, ENUM_F, ENUM_F, ENUM_F, IGNORE_F, IGNORE_F)) num_flags_C2     };
+enum FlagCounter_ARCH  { ARCH_FLAGS(                ENUM_F,         ENUM_F,         ENUM_F, IGNORE_F, IGNORE_F)  num_flags_ARCH   };
+
+const int first_flag_enum_LP64   = 0;
+const int first_flag_enum_JVMCI  = first_flag_enum_LP64  + num_flags_LP64;
+const int first_flag_enum_C1     = first_flag_enum_JVMCI + num_flags_JVMCI;
+const int first_flag_enum_C2     = first_flag_enum_C1    + num_flags_C1;
+const int first_flag_enum_ARCH   = first_flag_enum_C2    + num_flags_C2;
+const int first_flag_enum_other  = first_flag_enum_ARCH  + num_flags_ARCH;
+
+static constexpr int flag_group(int flag_enum) {
+  if (flag_enum < first_flag_enum_JVMCI) return JVMFlag::KIND_LP64_PRODUCT;
+  if (flag_enum < first_flag_enum_C1)    return JVMFlag::KIND_JVMCI;
+  if (flag_enum < first_flag_enum_C2)    return JVMFlag::KIND_C1;
+  if (flag_enum < first_flag_enum_ARCH)  return JVMFlag::KIND_C2;
+  if (flag_enum < first_flag_enum_other) return JVMFlag::KIND_ARCH;
+
+  return 0;
+}
+
+constexpr JVMFlag::JVMFlag(int flag_enum, const char* type, const char* name,
+                           void* addr, int flags, int extra_flags, const char* doc) :
+  _type(type), _name(name), _addr(addr), _flags() NOT_PRODUCT(COMMA _doc(doc)) {
+  flags = flags | extra_flags | JVMFlag::DEFAULT | flag_group(flag_enum);
+  if ((flags & JVMFlag::KIND_PRODUCT) != 0) {
+    if (flags & (JVMFlag::KIND_DIAGNOSTIC | JVMFlag::KIND_MANAGEABLE | JVMFlag::KIND_EXPERIMENTAL)) {
+      // Backwards compatibility. This will be relaxed in JDK-7123237.
+      flags &= ~(JVMFlag::KIND_PRODUCT);
+    }
+  }
+  _flags = static_cast<Flags>(flags);
+}
+
+constexpr JVMFlag::JVMFlag(int flag_enum,  const char* type, const char* name,
+                           void* addr, int flags, const char* doc) :
+  JVMFlag(flag_enum, type, name, addr, flags, /*extra_flags*/0, doc) {}
+
+const int PRODUCT_KIND     = JVMFlag::KIND_PRODUCT;
+const int PRODUCT_KIND_PD  = JVMFlag::KIND_PRODUCT | JVMFlag::KIND_PLATFORM_DEPENDENT;
+const int DEVELOP_KIND     = JVMFlag::KIND_DEVELOP;
+const int DEVELOP_KIND_PD  = JVMFlag::KIND_DEVELOP | JVMFlag::KIND_PLATFORM_DEPENDENT;
+const int NOTPROD_KIND     = JVMFlag::KIND_NOT_PRODUCT;
+
+#define DEVELOP_FLAG_INIT(   type, name, value, ...) JVMFlag(FLAG_MEMBER_ENUM(name), #type, XSTR(name), (void*)&name, DEVELOP_KIND,    __VA_ARGS__),
+#define DEVELOP_FLAG_INIT_PD(type, name,        ...) JVMFlag(FLAG_MEMBER_ENUM(name), #type, XSTR(name), (void*)&name, DEVELOP_KIND_PD, __VA_ARGS__),
+#define PRODUCT_FLAG_INIT(   type, name, value, ...) JVMFlag(FLAG_MEMBER_ENUM(name), #type, XSTR(name), (void*)&name, PRODUCT_KIND,    __VA_ARGS__),
+#define PRODUCT_FLAG_INIT_PD(type, name,        ...) JVMFlag(FLAG_MEMBER_ENUM(name), #type, XSTR(name), (void*)&name, PRODUCT_KIND_PD, __VA_ARGS__),
+#define NOTPROD_FLAG_INIT(   type, name, value, ...) JVMFlag(FLAG_MEMBER_ENUM(name), #type, XSTR(name), (void*)&name, NOTPROD_KIND,    __VA_ARGS__),
+
+// Handy aliases to match the symbols used in the flag specification macros.
+const int DIAGNOSTIC   = JVMFlag::KIND_DIAGNOSTIC;
+const int MANAGEABLE   = JVMFlag::KIND_MANAGEABLE;
+const int EXPERIMENTAL = JVMFlag::KIND_EXPERIMENTAL;
+
+#define MATERIALIZE_ALL_FLAGS      \
+  ALL_FLAGS(DEVELOP_FLAG_INIT,     \
+            DEVELOP_FLAG_INIT_PD,  \
+            PRODUCT_FLAG_INIT,     \
+            PRODUCT_FLAG_INIT_PD,  \
+            NOTPROD_FLAG_INIT,     \
+            IGNORE_RANGE,          \
+            IGNORE_CONSTRAINT)
+
+static JVMFlag flagTable[NUM_JVMFlagsEnum + 1] = {
+  MATERIALIZE_ALL_FLAGS
+  JVMFlag() // The iteration code wants a flag with a NULL name at the end of the table.
 };
 
+// We want flagTable[] to be completely initialized at C++ compilation time, which requires
+// that all arguments passed to JVMFlag() constructors be constexpr. The following line
+// checks for this -- if any non-constexpr arguments are passed, the C++ compiler will
+// generate an error.
+//
+// constexpr implies internal linkage. This means the flagTable_verify_constexpr[] variable
+// will not be included in jvmFlag.o, so there's no footprint cost for having this variable.
+//
+// Note that we cannot declare flagTable[] as constexpr because JVMFlag::_flags is modified
+// at runtime.
+constexpr JVMFlag flagTable_verify_constexpr[] = { MATERIALIZE_ALL_FLAGS };
+
 JVMFlag* JVMFlag::flags = flagTable;
 size_t JVMFlag::numFlags = (sizeof(flagTable) / sizeof(JVMFlag));
 
-inline bool str_equal(const char* s, size_t s_len, const char* q, size_t q_len) {
-  if (s_len != q_len) return false;
-  return memcmp(s, q, q_len) == 0;
-}
-
 // Search the flag table for a named flag
 JVMFlag* JVMFlag::find_flag(const char* name, size_t length, bool allow_locked, bool return_flag) {
-  for (JVMFlag* current = &flagTable[0]; current->_name != NULL; current++) {
-    if (str_equal(current->_name, current->get_name_length(), name, length)) {
-      // Found a matching entry.
-      // Don't report notproduct and develop flags in product builds.
-      if (current->is_constant_in_binary()) {
-        return (return_flag ? current : NULL);
-      }
-      // Report locked flags only if allowed.
-      if (!(current->is_unlocked() || current->is_unlocker())) {
-        if (!allow_locked) {
-          // disable use of locked flags, e.g. diagnostic, experimental,
-          // etc. until they are explicitly unlocked
-          return NULL;
-        }
+  JVMFlag* flag = JVMFlagLookup::find(name, length);
+  if (flag != NULL) {
+    // Found a matching entry.
+    // Don't report notproduct and develop flags in product builds.
+    if (flag->is_constant_in_binary()) {
+      return (return_flag ? flag : NULL);
+    }
+    // Report locked flags only if allowed.
+    if (!(flag->is_unlocked() || flag->is_unlocker())) {
+      if (!allow_locked) {
+        // disable use of locked flags, e.g. diagnostic, experimental,
+        // etc. until they are explicitly unlocked
+        return NULL;
       }
-      return current;
     }
+    return flag;
   }
   // JVMFlag name is not in the flag table
   return NULL;
 }
 
-// Get or compute the flag name length
-size_t JVMFlag::get_name_length() {
-  if (_name_len == 0) {
-    _name_len = strlen(_name);
-  }
-  return _name_len;
-}
-
 JVMFlag* JVMFlag::fuzzy_match(const char* name, size_t length, bool allow_locked) {
   float VMOptionsFuzzyMatchSimilarity = 0.7f;
   JVMFlag* match = NULL;
@@ -856,7 +810,7 @@ void JVMFlagEx::setOnCmdLine(JVMFlagsEnum flag) {
 }
 
 template<class E, class T>
-static void trace_flag_changed(const JVMFlag* flag, const T old_value, const T new_value, const JVMFlag::Flags origin) {
+static void trace_flag_changed(JVMFlag* flag, const T old_value, const T new_value, const JVMFlag::Flags origin) {
   E e;
   e.set_name(flag->_name);
   e.set_oldValue(old_value);
@@ -865,11 +819,11 @@ static void trace_flag_changed(const JVMFlag* flag, const T old_value, const T n
   e.commit();
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_bool(const JVMFlag* flag, bool new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_bool(JVMFlag* flag, bool new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
-  if (constraint != NULL) {
-    status = constraint->apply_bool(new_value, verbose);
+  JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
+  if (constraint.exists()) {
+    status = constraint.apply_bool(new_value, verbose);
   }
   return status;
 }
@@ -900,16 +854,16 @@ JVMFlag::Error JVMFlagEx::boolAtPut(JVMFlagsEnum flag, bool value, JVMFlag::Flag
   return JVMFlag::boolAtPut(faddr, &value, origin);
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_int(const JVMFlag* flag, int new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_int(JVMFlag* flag, int new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(flag);
-  if (range != NULL) {
-    status = range->check_int(new_value, verbose);
+  JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
+  if (range.exists()) {
+    status = range.check_int(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
-    if (constraint != NULL) {
-      status = constraint->apply_int(new_value, verbose);
+    JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
+    if (constraint.exists()) {
+      status = constraint.apply_int(new_value, verbose);
     }
   }
   return status;
@@ -941,16 +895,16 @@ JVMFlag::Error JVMFlagEx::intAtPut(JVMFlagsEnum flag, int value, JVMFlag::Flags
   return JVMFlag::intAtPut(faddr, &value, origin);
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_uint(const JVMFlag* flag, uint new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_uint(JVMFlag* flag, uint new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(flag);
-  if (range != NULL) {
-    status = range->check_uint(new_value, verbose);
+  JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
+  if (range.exists()) {
+    status = range.check_uint(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
-    if (constraint != NULL) {
-      status = constraint->apply_uint(new_value, verbose);
+    JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
+    if (constraint.exists()) {
+      status = constraint.apply_uint(new_value, verbose);
     }
   }
   return status;
@@ -989,16 +943,16 @@ JVMFlag::Error JVMFlag::intxAt(const JVMFlag* flag, intx* value) {
   return JVMFlag::SUCCESS;
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_intx(const JVMFlag* flag, intx new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_intx(JVMFlag* flag, intx new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(flag);
-  if (range != NULL) {
-    status = range->check_intx(new_value, verbose);
+  JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
+  if (range.exists()) {
+    status = range.check_intx(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
-    if (constraint != NULL) {
-      status = constraint->apply_intx(new_value, verbose);
+    JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
+    if (constraint.exists()) {
+      status = constraint.apply_intx(new_value, verbose);
     }
   }
   return status;
@@ -1030,16 +984,16 @@ JVMFlag::Error JVMFlag::uintxAt(const JVMFlag* flag, uintx* value) {
   return JVMFlag::SUCCESS;
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_uintx(const JVMFlag* flag, uintx new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_uintx(JVMFlag* flag, uintx new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(flag);
-  if (range != NULL) {
-    status = range->check_uintx(new_value, verbose);
+  JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
+  if (range.exists()) {
+    status = range.check_uintx(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
-    if (constraint != NULL) {
-      status = constraint->apply_uintx(new_value, verbose);
+    JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
+    if (constraint.exists()) {
+      status = constraint.apply_uintx(new_value, verbose);
     }
   }
   return status;
@@ -1071,16 +1025,16 @@ JVMFlag::Error JVMFlag::uint64_tAt(const JVMFlag* flag, uint64_t* value) {
   return JVMFlag::SUCCESS;
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_uint64_t(const JVMFlag* flag, uint64_t new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_uint64_t(JVMFlag* flag, uint64_t new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(flag);
-  if (range != NULL) {
-    status = range->check_uint64_t(new_value, verbose);
+  JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
+  if (range.exists()) {
+    status = range.check_uint64_t(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
-    if (constraint != NULL) {
-      status = constraint->apply_uint64_t(new_value, verbose);
+    JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
+    if (constraint.exists()) {
+      status = constraint.apply_uint64_t(new_value, verbose);
     }
   }
   return status;
@@ -1112,16 +1066,16 @@ JVMFlag::Error JVMFlag::size_tAt(const JVMFlag* flag, size_t* value) {
   return JVMFlag::SUCCESS;
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_size_t(const JVMFlag* flag, size_t new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_size_t(JVMFlag* flag, size_t new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(flag);
-  if (range != NULL) {
-    status = range->check_size_t(new_value, verbose);
+  JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
+  if (range.exists()) {
+    status = range.check_size_t(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
-    if (constraint != NULL) {
-      status = constraint->apply_size_t(new_value, verbose);
+    JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
+    if (constraint.exists()) {
+      status = constraint.apply_size_t(new_value, verbose);
     }
   }
   return status;
@@ -1154,16 +1108,16 @@ JVMFlag::Error JVMFlag::doubleAt(const JVMFlag* flag, double* value) {
   return JVMFlag::SUCCESS;
 }
 
-static JVMFlag::Error apply_constraint_and_check_range_double(const JVMFlag* flag, double new_value, bool verbose) {
+static JVMFlag::Error apply_constraint_and_check_range_double(JVMFlag* flag, double new_value, bool verbose) {
   JVMFlag::Error status = JVMFlag::SUCCESS;
-  JVMFlagRange* range = JVMFlagRangeList::find(flag);
-  if (range != NULL) {
-    status = range->check_double(new_value, verbose);
+  JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
+  if (range.exists()) {
+    status = range.check_double(new_value, verbose);
   }
   if (status == JVMFlag::SUCCESS) {
-    JVMFlagConstraint* constraint = JVMFlagConstraintList::find_if_needs_check(flag);
-    if (constraint != NULL) {
-      status = constraint->apply_double(new_value, verbose);
+    JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find_if_needs_check(flag);
+    if (constraint.exists()) {
+      status = constraint.apply_double(new_value, verbose);
     }
   }
   return status;
@@ -1269,6 +1223,33 @@ void JVMFlag::verify() {
 
 #endif // PRODUCT
 
+#ifdef ASSERT
+
+void JVMFlag::assert_valid_flag_enum(int i) {
+  assert(0 <= i && i < NUM_JVMFlagsEnum, "must be");
+}
+
+void JVMFlag::check_all_flag_declarations() {
+  for (JVMFlag* current = &flagTable[0]; current->_name != NULL; current++) {
+    int flags = static_cast<int>(current->_flags);
+    // Backwards compatibility. This will be relaxed/removed in JDK-7123237.
+    int mask = JVMFlag::KIND_DIAGNOSTIC | JVMFlag::KIND_MANAGEABLE | JVMFlag::KIND_EXPERIMENTAL;
+    if ((flags & mask) != 0) {
+      assert((flags & mask) == JVMFlag::KIND_DIAGNOSTIC ||
+             (flags & mask) == JVMFlag::KIND_MANAGEABLE ||
+             (flags & mask) == JVMFlag::KIND_EXPERIMENTAL,
+             "%s can be declared with at most one of "
+             "DIAGNOSTIC, MANAGEABLE or EXPERIMENTAL", current->_name);
+      assert((flags & KIND_NOT_PRODUCT) == 0 &&
+             (flags & KIND_DEVELOP) == 0,
+             "%s has an optional DIAGNOSTIC, MANAGEABLE or EXPERIMENTAL "
+             "attribute; it must be declared as a product flag", current->_name);
+    }
+  }
+}
+
+#endif // ASSERT
+
 void JVMFlag::printFlags(outputStream* out, bool withComments, bool printRanges, bool skipDefaults) {
   // Print the flags sorted by name
   // Note: This method may be called before the thread structure is in place
diff --git a/src/hotspot/share/runtime/flags/jvmFlag.hpp b/src/hotspot/share/runtime/flags/jvmFlag.hpp
index 1c84920896d..7e8731e49de 100644
--- a/src/hotspot/share/runtime/flags/jvmFlag.hpp
+++ b/src/hotspot/share/runtime/flags/jvmFlag.hpp
@@ -34,7 +34,7 @@ class outputStream;
 typedef const char* (*RangeStrFunc)(void);
 
 struct JVMFlag {
-  enum Flags {
+  enum Flags : int {
     // latest value origin
     DEFAULT          = 0,
     COMMAND_LINE     = 1,
@@ -58,12 +58,11 @@ struct JVMFlag {
     KIND_NOT_PRODUCT        = 1 << 8,
     KIND_DEVELOP            = 1 << 9,
     KIND_PLATFORM_DEPENDENT = 1 << 10,
-    KIND_READ_WRITE         = 1 << 11,
-    KIND_C1                 = 1 << 12,
-    KIND_C2                 = 1 << 13,
-    KIND_ARCH               = 1 << 14,
-    KIND_LP64_PRODUCT       = 1 << 15,
-    KIND_JVMCI              = 1 << 16,
+    KIND_C1                 = 1 << 11,
+    KIND_C2                 = 1 << 12,
+    KIND_ARCH               = 1 << 13,
+    KIND_LP64_PRODUCT       = 1 << 14,
+    KIND_JVMCI              = 1 << 15,
 
     // set this bit if the flag was set on the command line
     ORIG_COMMAND_LINE       = 1 << 17,
@@ -109,9 +108,8 @@ struct JVMFlag {
   const char* _type;
   const char* _name;
   void* _addr;
-  NOT_PRODUCT(const char* _doc;)
   Flags _flags;
-  size_t _name_len;
+  NOT_PRODUCT(const char* _doc;)
 
   // points to all Flags static array
   static JVMFlag* flags;
@@ -123,13 +121,21 @@ struct JVMFlag {
   static JVMFlag* find_flag(const char* name, size_t length, bool allow_locked, bool return_flag);
 
 public:
+  constexpr JVMFlag() : _type(), _name(), _addr(), _flags() NOT_PRODUCT(COMMA _doc()) {}
+
+  constexpr JVMFlag(int flag_enum, const char* type, const char* name,
+                    void* addr, int flags, int extra_flags, const char* doc);
+
+  constexpr JVMFlag(int flag_enum,  const char* type, const char* name,
+                    void* addr, int flags, const char* doc);
+
   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) {
+  static 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) {
+  static JVMFlag* find_declared_flag(const char* name) {
     return find_declared_flag(name, strlen(name));
   }
 
@@ -143,52 +149,64 @@ struct JVMFlag {
   static const char* get_size_t_default_range_str();
   static const char* get_double_default_range_str();
 
+  static void assert_valid_flag_enum(int i) NOT_DEBUG_RETURN;
+  static void check_all_flag_declarations() NOT_DEBUG_RETURN;
+
+  inline int flag_enum() const {
+    int i = this - JVMFlag::flags;
+    assert_valid_flag_enum(i);
+    return i;
+  }
+
+  static JVMFlag* flag_from_enum(int flag_enum) {
+    assert_valid_flag_enum(flag_enum);
+    return &JVMFlag::flags[flag_enum];
+  }
+
   bool is_bool() const;
   bool get_bool() const                       { return *((bool*) _addr); }
-  void set_bool(bool value)                   { *((bool*) _addr) = value; }
+  void set_bool(bool value) const             { *((bool*) _addr) = value; }
 
   bool is_int() const;
   int get_int() const                         { return *((int*) _addr); }
-  void set_int(int value)                     { *((int*) _addr) = value; }
+  void set_int(int value) const               { *((int*) _addr) = value; }
 
   bool is_uint() const;
   uint get_uint() const                       { return *((uint*) _addr); }
-  void set_uint(uint value)                   { *((uint*) _addr) = value; }
+  void set_uint(uint value) const             { *((uint*) _addr) = value; }
 
   bool is_intx() const;
   intx get_intx() const                       { return *((intx*) _addr); }
-  void set_intx(intx value)                   { *((intx*) _addr) = value; }
+  void set_intx(intx value) const             { *((intx*) _addr) = value; }
 
   bool is_uintx() const;
   uintx get_uintx() const                     { return *((uintx*) _addr); }
-  void set_uintx(uintx value)                 { *((uintx*) _addr) = value; }
+  void set_uintx(uintx value) const           { *((uintx*) _addr) = value; }
 
   bool is_uint64_t() const;
   uint64_t get_uint64_t() const               { return *((uint64_t*) _addr); }
-  void set_uint64_t(uint64_t value)           { *((uint64_t*) _addr) = value; }
+  void set_uint64_t(uint64_t value) const     { *((uint64_t*) _addr) = value; }
 
   bool is_size_t() const;
   size_t get_size_t() const                   { return *((size_t*) _addr); }
-  void set_size_t(size_t value)               { *((size_t*) _addr) = value; }
+  void set_size_t(size_t value) const         { *((size_t*) _addr) = value; }
 
   bool is_double() const;
   double get_double() const                   { return *((double*) _addr); }
-  void set_double(double value)               { *((double*) _addr) = value; }
+  void set_double(double value) const         { *((double*) _addr) = value; }
 
   bool is_ccstr() const;
   bool ccstr_accumulates() const;
   ccstr get_ccstr() const                     { return *((ccstr*) _addr); }
-  void set_ccstr(ccstr value)                 { *((ccstr*) _addr) = value; }
+  void set_ccstr(ccstr value) const           { *((ccstr*) _addr) = value; }
 
-  Flags get_origin();
+  Flags get_origin() const;
   void set_origin(Flags origin);
 
-  size_t get_name_length();
-
-  bool is_default();
-  bool is_ergonomic();
-  bool is_jimage_resource();
-  bool is_command_line();
+  bool is_default() const;
+  bool is_ergonomic() const;
+  bool is_jimage_resource() const;
+  bool is_command_line() const;
   void set_command_line();
 
   bool is_product() const;
@@ -197,7 +215,6 @@ struct JVMFlag {
   bool is_experimental() const;
   bool is_notproduct() const;
   bool is_develop() const;
-  bool is_read_write() const;
 
   bool is_constant_in_binary() const;
 
@@ -214,10 +231,10 @@ struct JVMFlag {
   JVMFlag::MsgType get_locked_message_ext(char*, int) const;
 
   // printRanges will print out flags type, name and range values as expected by -XX:+PrintFlagsRanges
-  void print_on(outputStream* st, bool withComments = false, bool printRanges = false);
-  void print_kind(outputStream* st, unsigned int width);
-  void print_origin(outputStream* st, unsigned int width);
-  void print_as_flag(outputStream* st);
+  void print_on(outputStream* st, bool withComments = false, bool printRanges = false) const;
+  void print_kind(outputStream* st, unsigned int width) const;
+  void print_origin(outputStream* st, unsigned int width) const;
+  void print_as_flag(outputStream* st) const;
 
   static const char* flag_error_str(JVMFlag::Error error);
 
@@ -260,4 +277,6 @@ struct JVMFlag {
   static void verify() PRODUCT_RETURN;
 };
 
+#define DECLARE_CONSTRAINT(type, func) JVMFlag::Error func(type value, bool verbose);
+
 #endif // SHARE_RUNTIME_FLAGS_JVMFLAG_HPP
diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp
index 3d21cfdf060..9248eb87521 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.cpp
@@ -172,125 +172,43 @@ class JVMFlagConstraint_double : public JVMFlagConstraint {
   }
 };
 
-// No constraint emitting
-void emit_constraint_no(...)                            { /* NOP */ }
-
-// No constraint emitting if function argument is NOT provided
-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 JVMFlag* flag, JVMFlagConstraintFunc_bool func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_bool(flag, 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 JVMFlag* flag, JVMFlagConstraintFunc_intx func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_intx(flag, 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 JVMFlag* flag, JVMFlagConstraintFunc_uintx func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_uintx(flag, 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 JVMFlag* flag, JVMFlagConstraintFunc_size_t func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_size_t(flag, func, type));
-}
-void emit_constraint_double(const JVMFlag* flag, JVMFlagConstraintFunc_double func, JVMFlagConstraint::ConstraintType type) {
-  JVMFlagConstraintList::add(new JVMFlagConstraint_double(flag, func, type));
+#define DEFINE_CONSTRAINT_APPLY(T) \
+JVMFlag::Error JVMFlagConstraintChecker::apply_ ## T(T value, bool verbose) const {           \
+  assert(exists(), "must be");                                                                \
+  JVMFlagConstraint_ ## T constraint(_flag,                                                   \
+                                     (JVMFlagConstraintFunc_ ## T)_limit->constraint_func(),  \
+                                     (JVMFlagConstraint::ConstraintType)_limit->phase());     \
+  return constraint.apply_ ## T(value, verbose);                                              \
 }
 
-// Generate code to call emit_constraint_xxx function
-#define EMIT_CONSTRAINT_START       (void)(0
-#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)
-#define EMIT_CONSTRAINT_EXPERIMENTAL_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
-#define EMIT_CONSTRAINT_MANAGEABLE_FLAG(type, name, value, doc)   EMIT_CONSTRAINT(type, name)
-#define EMIT_CONSTRAINT_PRODUCT_RW_FLAG(type, name, value, doc)   EMIT_CONSTRAINT(type, name)
-#define EMIT_CONSTRAINT_PD_PRODUCT_FLAG(type, name, doc)          EMIT_CONSTRAINT(type, name)
-#define EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG(type, name, doc)       EMIT_CONSTRAINT(type, name)
-#ifndef PRODUCT
-#define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc)    EMIT_CONSTRAINT(type, name)
-#define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc)        EMIT_CONSTRAINT(type, name)
-#define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc)   EMIT_CONSTRAINT(type, name)
-#else
-#define EMIT_CONSTRAINT_DEVELOPER_FLAG(type, name, value, doc)    EMIT_CONSTRAINT_NO
-#define EMIT_CONSTRAINT_PD_DEVELOPER_FLAG(type, name, doc)        EMIT_CONSTRAINT_NO
-#define EMIT_CONSTRAINT_NOTPRODUCT_FLAG(type, name, value, doc)   EMIT_CONSTRAINT_NO
-#endif
-#ifdef _LP64
-#define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT(type, name)
-#else
-#define EMIT_CONSTRAINT_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_CONSTRAINT_NO
-#endif
-#define EMIT_CONSTRAINT_END         );
-
-// Generate func argument to pass into emit_constraint_xxx functions
-#define EMIT_CONSTRAINT_CHECK(func, type)                         , func, JVMFlagConstraint::type
-
-// the "name" argument must be a string literal
-#define INITIAL_CONSTRAINTS_SIZE 72
-GrowableArray<JVMFlagConstraint*>* JVMFlagConstraintList::_constraints = NULL;
-JVMFlagConstraint::ConstraintType JVMFlagConstraintList::_validating_type = JVMFlagConstraint::AtParse;
+ALL_CONSTRAINT_TYPES(DEFINE_CONSTRAINT_APPLY)
 
-// Check the ranges of all flags that have them or print them out and exit if requested
-void JVMFlagConstraintList::init(void) {
-  _constraints = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JVMFlagConstraint*>(INITIAL_CONSTRAINTS_SIZE, mtArguments);
-
-  EMIT_CONSTRAINT_START
-
-  ALL_FLAGS(EMIT_CONSTRAINT_DEVELOPER_FLAG,
-            EMIT_CONSTRAINT_PD_DEVELOPER_FLAG,
-            EMIT_CONSTRAINT_PRODUCT_FLAG,
-            EMIT_CONSTRAINT_PD_PRODUCT_FLAG,
-            EMIT_CONSTRAINT_DIAGNOSTIC_FLAG,
-            EMIT_CONSTRAINT_PD_DIAGNOSTIC_FLAG,
-            EMIT_CONSTRAINT_EXPERIMENTAL_FLAG,
-            EMIT_CONSTRAINT_NOTPRODUCT_FLAG,
-            EMIT_CONSTRAINT_MANAGEABLE_FLAG,
-            EMIT_CONSTRAINT_PRODUCT_RW_FLAG,
-            EMIT_CONSTRAINT_LP64_PRODUCT_FLAG,
-            IGNORE_RANGE,
-            EMIT_CONSTRAINT_CHECK)
-
-  EMIT_CONSTRAINT_END
-}
 
-JVMFlagConstraint* JVMFlagConstraintList::find(const JVMFlag* flag) {
-  JVMFlagConstraint* found = NULL;
-  for (int i=0; i<length(); i++) {
-    JVMFlagConstraint* constraint = at(i);
-    if (constraint->flag() == flag) {
-      found = constraint;
-      break;
-    }
+JVMFlag::Error JVMFlagConstraintChecker::apply(bool verbose) const {
+#define APPLY_CONSTRAINT(T)                                                                     \
+  if (_flag->is_ ## T()) {                                                                      \
+    JVMFlagConstraint_ ## T constraint(_flag,                                                   \
+                                       (JVMFlagConstraintFunc_ ## T)_limit->constraint_func(),  \
+                                       (JVMFlagConstraint::ConstraintType)_limit->phase());     \
+    return constraint.apply(verbose);                                                           \
   }
-  return found;
+
+  ALL_CONSTRAINT_TYPES(APPLY_CONSTRAINT);
+
+  ShouldNotReachHere();
+  return JVMFlag::INVALID_FLAG;
 }
 
+
+JVMFlagConstraint::ConstraintType JVMFlagConstraintList::_validating_type = JVMFlagConstraint::AtParse;
+
 // 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(flag);
-  if (constraint != NULL && (constraint->type() <= _validating_type)) {
-    found = constraint;
+JVMFlagConstraintChecker JVMFlagConstraintList::find_if_needs_check(const JVMFlag* flag) {
+  JVMFlagConstraintChecker constraint = JVMFlagConstraintList::find(flag);
+  if (constraint.exists() && (constraint.type() <= _validating_type)) {
+    return constraint;
   }
-  return found;
+  return JVMFlagConstraintChecker(flag, NULL);
 }
 
 // Check constraints for specific constraint type.
@@ -299,10 +217,11 @@ bool JVMFlagConstraintList::check_constraints(JVMFlagConstraint::ConstraintType
   _validating_type = type;
 
   bool status = true;
-  for (int i=0; i<length(); i++) {
-    JVMFlagConstraint* constraint = at(i);
-    if (type != constraint->type()) continue;
-    if (constraint->apply(true) != JVMFlag::SUCCESS) status = false;
+  for (int i = 0; i < NUM_JVMFlagsEnum; i++) {
+    JVMFlagConstraintChecker constraint(&JVMFlag::flags[i], JVMFlagLimit::get_constraint_at(i));
+    if (!constraint.exists()) continue;
+    if (type != constraint.type()) continue;
+    if (constraint.apply(true) != JVMFlag::SUCCESS) status = false;
   }
   return status;
 }
diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp
index 91a785b9434..d6119f986a2 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintList.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 #define SHARE_RUNTIME_FLAGS_JVMFLAGCONSTRAINTLIST_HPP
 
 #include "runtime/flags/jvmFlag.hpp"
-#include "utilities/growableArray.hpp"
+#include "runtime/flags/jvmFlagLimit.hpp"
 
 /*
  * Here we have a mechanism for extracting constraints (as custom functions) for flags,
@@ -83,18 +83,28 @@ class JVMFlagConstraint : public CHeapObj<mtArguments> {
   virtual JVMFlag::Error apply_double(double value, bool verbose = true) { ShouldNotReachHere(); return JVMFlag::ERR_OTHER; };
 };
 
+class JVMFlagConstraintChecker {
+  const JVMFlag* _flag;
+  const JVMFlagLimit* _limit;
+
+public:
+  JVMFlagConstraintChecker(const JVMFlag* flag, const JVMFlagLimit* limit) : _flag(flag), _limit(limit) {}
+  bool exists() const { return _limit != NULL; }
+  JVMFlag::Error apply(bool verbose = true) const;
+
+  JVMFlagConstraint::ConstraintType type() const { return (JVMFlagConstraint::ConstraintType)_limit->phase(); }
+#define DECLARE_CONSTRAINT_APPLY(T) JVMFlag::Error apply_ ## T(T new_value, bool verbose = true) const;
+  ALL_CONSTRAINT_TYPES(DECLARE_CONSTRAINT_APPLY)
+};
+
 class JVMFlagConstraintList : public AllStatic {
 private:
-  static GrowableArray<JVMFlagConstraint*>* _constraints;
   // Latest constraint validation type.
   static JVMFlagConstraint::ConstraintType _validating_type;
 public:
   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 JVMFlag* flag);
-  static JVMFlagConstraint* find_if_needs_check(const JVMFlag* flag);
-  static void add(JVMFlagConstraint* constraint) { _constraints->append(constraint); }
+  static JVMFlagConstraintChecker find(const JVMFlag* flag) { return JVMFlagConstraintChecker(flag, JVMFlagLimit::get_constraint(flag)); }
+  static JVMFlagConstraintChecker find_if_needs_check(const JVMFlag* flag);
   // True if 'AfterErgo' or later constraint functions are validated.
   static bool validated_after_ergo() { return _validating_type >= JVMFlagConstraint::AfterErgo; };
   static bool check_constraints(JVMFlagConstraint::ConstraintType type);
diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.hpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.hpp
index b63eebd410a..6b4abf8a501 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.hpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 #define SHARE_RUNTIME_FLAGS_JVMFLAGCONSTRAINTSCOMPILER_HPP
 
 #include "runtime/flags/jvmFlag.hpp"
+#include "utilities/macros.hpp"
 
 /*
  * Here we have compiler arguments constraints functions, which are called automatically
@@ -33,46 +34,28 @@
  * an appropriate error value.
  */
 
-JVMFlag::Error AliasLevelConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error CICompilerCountConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error AllocatePrefetchDistanceConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error AllocatePrefetchInstrConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error AllocatePrefetchStepSizeConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error CompileThresholdConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error OnStackReplacePercentageConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error CodeCacheSegmentSizeConstraintFunc(uintx value, bool verbose);
-
-JVMFlag::Error CompilerThreadPriorityConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error CodeEntryAlignmentConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error OptoLoopAlignmentConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error ArraycopyDstPrefetchDistanceConstraintFunc(uintx value, bool verbose);
-
-JVMFlag::Error ArraycopySrcPrefetchDistanceConstraintFunc(uintx value, bool verbose);
-
-JVMFlag::Error TypeProfileLevelConstraintFunc(uintx value, bool verbose);
-
-JVMFlag::Error InitArrayShortSizeConstraintFunc(intx value, bool verbose);
-
-#ifdef COMPILER2
-JVMFlag::Error InteriorEntryAlignmentConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error NodeLimitFudgeFactorConstraintFunc(intx value, bool verbose);
-#endif
-
-JVMFlag::Error RTMTotalCountIncrRateConstraintFunc(int value, bool verbose);
-
-#ifdef COMPILER2
-JVMFlag::Error LoopStripMiningIterConstraintFunc(uintx value, bool verbose);
-#endif
+#define COMPILER_CONSTRAINTS(f)                         \
+  f(intx,  AliasLevelConstraintFunc)                    \
+  f(intx,  CICompilerCountConstraintFunc)               \
+  f(intx,  AllocatePrefetchDistanceConstraintFunc)      \
+  f(intx,  AllocatePrefetchInstrConstraintFunc)         \
+  f(intx,  AllocatePrefetchStepSizeConstraintFunc)      \
+  f(intx,  CompileThresholdConstraintFunc)              \
+  f(intx,  OnStackReplacePercentageConstraintFunc)      \
+  f(uintx, CodeCacheSegmentSizeConstraintFunc)          \
+  f(intx,  CodeEntryAlignmentConstraintFunc)            \
+  f(intx,  OptoLoopAlignmentConstraintFunc)             \
+  f(uintx, ArraycopyDstPrefetchDistanceConstraintFunc)  \
+  f(uintx, ArraycopySrcPrefetchDistanceConstraintFunc)  \
+  f(uintx, TypeProfileLevelConstraintFunc)              \
+  f(intx,  InitArrayShortSizeConstraintFunc)            \
+  f(int ,  RTMTotalCountIncrRateConstraintFunc)         \
+COMPILER2_PRESENT(                                      \
+  f(intx,  InteriorEntryAlignmentConstraintFunc)        \
+  f(intx,  NodeLimitFudgeFactorConstraintFunc)          \
+  f(uintx, LoopStripMiningIterConstraintFunc)           \
+)
+
+COMPILER_CONSTRAINTS(DECLARE_CONSTRAINT)
 
 #endif // SHARE_RUNTIME_FLAGS_JVMFLAGCONSTRAINTSCOMPILER_HPP
diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp
index 61d58c53829..9d55a110f46 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/flags/jvmFlag.hpp"
+#include "runtime/flags/jvmFlagLimit.hpp"
 #include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/safepointMechanism.hpp"
@@ -131,3 +132,32 @@ JVMFlag::Error PerfDataSamplingIntervalFunc(intx value, bool verbose) {
     return JVMFlag::SUCCESS;
   }
 }
+
+JVMFlag::Error VMPageSizeConstraintFunc(uintx value, bool verbose) {
+  uintx min = (uintx)os::vm_page_size();
+  if (value < min) {
+    JVMFlag::printError(verbose,
+                        "%s %s=" UINTX_FORMAT " is outside the allowed range [ " UINTX_FORMAT
+                        " ... " UINTX_FORMAT " ]\n",
+                        JVMFlagLimit::last_checked_flag()->_type,
+                        JVMFlagLimit::last_checked_flag()->_name,
+                        value, min, max_uintx);
+    return JVMFlag::VIOLATES_CONSTRAINT;
+  }
+
+  return JVMFlag::SUCCESS;
+}
+
+JVMFlag::Error NUMAInterleaveGranularityConstraintFunc(size_t value, bool verbose) {
+  size_t min = os::vm_allocation_granularity();
+  size_t max = NOT_LP64(2*G) LP64_ONLY(8192*G);
+
+  if (value < min || value > max) {
+    JVMFlag::printError(verbose,
+                        "size_t NUMAInterleaveGranularity=" UINTX_FORMAT " is outside the allowed range [ " UINTX_FORMAT
+                        " ... " UINTX_FORMAT " ]\n", value, min, max);
+    return JVMFlag::VIOLATES_CONSTRAINT;
+  }
+
+  return JVMFlag::SUCCESS;
+}
diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp
index 5e1f8d8bdf1..8bc3a9a1548 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,15 +33,17 @@
  * an appropriate error value.
  */
 
-JVMFlag::Error ObjectAlignmentInBytesConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error ContendedPaddingWidthConstraintFunc(intx value, bool verbose);
-
-JVMFlag::Error BiasedLockingBulkRebiasThresholdFunc(intx value, bool verbose);
-JVMFlag::Error BiasedLockingStartupDelayFunc(intx value, bool verbose);
-JVMFlag::Error BiasedLockingBulkRevokeThresholdFunc(intx value, bool verbose);
-JVMFlag::Error BiasedLockingDecayTimeFunc(intx value, bool verbose);
-
-JVMFlag::Error PerfDataSamplingIntervalFunc(intx value, bool verbose);
+#define RUNTIME_CONSTRAINTS(f)                        \
+  f(intx,   ObjectAlignmentInBytesConstraintFunc)     \
+  f(intx,   ContendedPaddingWidthConstraintFunc)      \
+  f(intx,   BiasedLockingBulkRebiasThresholdFunc)     \
+  f(intx,   BiasedLockingStartupDelayFunc)            \
+  f(intx,   BiasedLockingBulkRevokeThresholdFunc)     \
+  f(intx,   BiasedLockingDecayTimeFunc)               \
+  f(intx,   PerfDataSamplingIntervalFunc)             \
+  f(uintx,  VMPageSizeConstraintFunc)                 \
+  f(size_t, NUMAInterleaveGranularityConstraintFunc)
+
+RUNTIME_CONSTRAINTS(DECLARE_CONSTRAINT)
 
 #endif // SHARE_RUNTIME_FLAGS_JVMFLAGCONSTRAINTSRUNTIME_HPP
diff --git a/src/hotspot/share/runtime/flags/jvmFlagLimit.cpp b/src/hotspot/share/runtime/flags/jvmFlagLimit.cpp
new file mode 100644
index 00000000000..b9d5ae5a8e9
--- /dev/null
+++ b/src/hotspot/share/runtime/flags/jvmFlagLimit.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 "gc/shared/jvmFlagConstraintsGC.hpp"
+#include "runtime/flags/jvmFlag.hpp"
+#include "runtime/flags/jvmFlagLimit.hpp"
+#include "runtime/flags/jvmFlagConstraintList.hpp"
+#include "runtime/flags/jvmFlagConstraintsCompiler.hpp"
+#include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
+#include "runtime/flags/jvmFlagRangeList.hpp"
+#include "runtime/globals_extension.hpp"
+#include "gc/shared/referenceProcessor.hpp"
+#include "oops/markWord.hpp"
+#include "runtime/task.hpp"
+
+//----------------------------------------------------------------------
+// Build flagLimitTable[]
+
+#define CONSTRAINT_ENUM(func)         constraint_enum_ ## func
+#define CONSTRAINT_ENUM_(type, func)  CONSTRAINT_ENUM(func),
+#define CONSTRAINT_FUNC(type, func)   (void*)&func,
+
+enum JVMFlagConstraintsEnum : int {
+  ALL_CONSTRAINTS(CONSTRAINT_ENUM_)
+  NUM_JVMFlagConstraintsEnum
+};
+
+static void* const flagConstraintTable[NUM_JVMFlagConstraintsEnum] = {
+  ALL_CONSTRAINTS(CONSTRAINT_FUNC)
+};
+
+void* JVMFlagLimit::constraint_func() const {
+  int i = _constraint_func;
+  assert(0 <= i && i < NUM_JVMFlagConstraintsEnum, "sanity");
+  return flagConstraintTable[i];
+}
+
+struct DummyLimit {
+  char dummy;
+  constexpr DummyLimit(...) : dummy() {}
+};
+
+template <typename T>
+class LimitGetter {
+public:
+  // These functions return NULL for develop flags in a PRODUCT build
+  static constexpr const JVMFlagLimit* no_limit(...) {
+    return NULL;
+  }
+
+  // This is for flags that have neither range no constraint. We don't need the JVMFlagLimit struct.
+  static constexpr const JVMFlagLimit* get_limit(const JVMTypedFlagLimit<T>* p, int dummy) {
+    return NULL;
+  }
+
+  static constexpr const JVMFlagLimit* get_limit(const JVMTypedFlagLimit<T>* p, int dummy, T min, T max) {
+    return p;
+  }
+  static constexpr const JVMFlagLimit* get_limit(const JVMTypedFlagLimit<T>* p, int dummy, ConstraintMarker dummy2, short func, int phase) {
+    return p;
+  }
+  static constexpr const JVMFlagLimit* get_limit(const JVMTypedFlagLimit<T>* p, int dummy, T min, T max, ConstraintMarker dummy2, short func, int phase) {
+    return p;
+  }
+  static constexpr const JVMFlagLimit* get_limit(const JVMTypedFlagLimit<T>* p, int dummy, ConstraintMarker dummy2, short func, int phase, T min, T max) {
+    return p;
+  }
+};
+
+//           macro body starts here -------------------+
+//                                                     |
+//                                                     v
+#define FLAG_LIMIT_DEFINE(      type, name, ...)       ); constexpr JVMTypedFlagLimit<type> limit_##name(0
+#define FLAG_LIMIT_DEFINE_DUMMY(type, name, ...)       ); constexpr DummyLimit nolimit_##name(0
+#define FLAG_LIMIT_PTR(         type, name, ...)       ), LimitGetter<type>::get_limit(&limit_##name, 0
+#define FLAG_LIMIT_PTR_NONE(    type, name, ...)       ), LimitGetter<type>::no_limit(0
+#define APPLY_FLAG_RANGE(...)                          , __VA_ARGS__
+#define APPLY_FLAG_CONSTRAINT(func, phase)             , next_two_args_are_constraint, (short)CONSTRAINT_ENUM(func), int(JVMFlagConstraint::phase)
+
+constexpr JVMTypedFlagLimit<int> limit_dummy
+(
+#ifdef PRODUCT
+ ALL_FLAGS(FLAG_LIMIT_DEFINE_DUMMY,
+           FLAG_LIMIT_DEFINE_DUMMY,
+           FLAG_LIMIT_DEFINE,
+           FLAG_LIMIT_DEFINE,
+           FLAG_LIMIT_DEFINE_DUMMY,
+           APPLY_FLAG_RANGE,
+           APPLY_FLAG_CONSTRAINT)
+#else
+ ALL_FLAGS(FLAG_LIMIT_DEFINE,
+           FLAG_LIMIT_DEFINE,
+           FLAG_LIMIT_DEFINE,
+           FLAG_LIMIT_DEFINE,
+           FLAG_LIMIT_DEFINE,
+           APPLY_FLAG_RANGE,
+           APPLY_FLAG_CONSTRAINT)
+#endif
+);
+
+static constexpr const JVMFlagLimit* const flagLimitTable[1 + NUM_JVMFlagsEnum] = {
+  // Because FLAG_LIMIT_PTR must start with an "),", we have to place a dummy element here.
+  LimitGetter<int>::get_limit(NULL, 0
+
+#ifdef PRODUCT
+  ALL_FLAGS(FLAG_LIMIT_PTR_NONE,
+            FLAG_LIMIT_PTR_NONE,
+            FLAG_LIMIT_PTR,
+            FLAG_LIMIT_PTR,
+            FLAG_LIMIT_PTR_NONE,
+            APPLY_FLAG_RANGE,
+            APPLY_FLAG_CONSTRAINT)
+#else
+  ALL_FLAGS(FLAG_LIMIT_PTR,
+            FLAG_LIMIT_PTR,
+            FLAG_LIMIT_PTR,
+            FLAG_LIMIT_PTR,
+            FLAG_LIMIT_PTR,
+            APPLY_FLAG_RANGE,
+            APPLY_FLAG_CONSTRAINT)
+#endif
+  )
+};
+
+int JVMFlagLimit::_last_checked = -1;
+
+const JVMFlagLimit* const* JVMFlagLimit::flagLimits = &flagLimitTable[1]; // excludes dummy
diff --git a/src/hotspot/share/runtime/flags/jvmFlagLimit.hpp b/src/hotspot/share/runtime/flags/jvmFlagLimit.hpp
new file mode 100644
index 00000000000..4474b15963d
--- /dev/null
+++ b/src/hotspot/share/runtime/flags/jvmFlagLimit.hpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_RUNTIME_FLAGS_JVMFLAGLIMIT_HPP
+#define SHARE_RUNTIME_FLAGS_JVMFLAGLIMIT_HPP
+
+#include "runtime/flags/jvmFlag.hpp"
+
+#define ALL_LIMIT_TYPES(f)  \
+  f(int)                    \
+  f(intx)                   \
+  f(uint)                   \
+  f(uintx)                  \
+  f(uint64_t)               \
+  f(size_t)                 \
+  f(double)
+
+#define ALL_RANGE_TYPES(f) ALL_LIMIT_TYPES(f)
+#define ALL_CONSTRAINT_TYPES(f) ALL_LIMIT_TYPES(f) f(bool)
+
+template <typename T> class JVMTypedFlagLimit;
+
+
+// A JVMFlagLimit is created for each JVMFlag that has a range() and/or constraint() in its declaration in
+// the globals_xxx.hpp file.
+//
+// To query the range information of a JVMFlag:
+//     JVMFlagLimit::get_range(JVMFlag*)
+//     JVMFlagLimit::get_range_at(int flag_enum)
+// If the given flag doesn't have a range, NULL is returned.
+//
+// To query the constraint information of a JVMFlag:
+//     JVMFlagLimit::get_constraint(JVMFlag*)
+//     JVMFlagLimit::get_constraint_at(int flag_enum)
+// If the given flag doesn't have a constraint, NULL is returned.
+
+class JVMFlagLimit {
+  short _constraint_func;
+  char  _phase;
+  char  _kind;
+
+  static const JVMFlagLimit* const* flagLimits;
+  static int _last_checked;
+
+protected:
+  static constexpr int HAS_RANGE = 1;
+  static constexpr int HAS_CONSTRAINT = 2;
+
+private:
+  static const JVMFlagLimit* get_kind_at(int flag_enum, int required_kind) {
+    const JVMFlagLimit* limit = at(flag_enum);
+    if (limit != NULL && (limit->_kind & required_kind) != 0) {
+      _last_checked = flag_enum;
+      return limit;
+    } else {
+      return NULL;
+    }
+  }
+
+  static const JVMFlagLimit* at(int flag_enum) {
+    JVMFlag::assert_valid_flag_enum(flag_enum);
+    return flagLimits[flag_enum];
+  }
+
+public:
+  void* constraint_func() const;
+  char phase() const { return _phase; }
+  char kind()  const { return _kind; }
+
+  constexpr JVMFlagLimit(short func, short phase, short kind) : _constraint_func(func), _phase(phase), _kind(kind) {}
+
+  static const JVMFlagLimit* get_range(const JVMFlag* flag) {
+    return get_range_at(flag->flag_enum());
+  }
+  static const JVMFlagLimit* get_range_at(int flag_enum) {
+    return get_kind_at(flag_enum, HAS_RANGE);
+  }
+
+  static const JVMFlagLimit* get_constraint(const JVMFlag* flag) {
+    return get_constraint_at(flag->flag_enum());
+  }
+  static const JVMFlagLimit* get_constraint_at(int flag_enum) {
+    return get_kind_at(flag_enum, HAS_CONSTRAINT);
+  }
+
+  static const JVMFlag* last_checked_flag() {
+    if (_last_checked >= 0) {
+      return JVMFlag::flag_from_enum(_last_checked);
+    } else {
+      return NULL;
+    }
+  }
+
+#define AS_TYPED_LIMIT(type) inline JVMTypedFlagLimit<type>* as_ ## type() const { return (JVMTypedFlagLimit<type>*)this; }
+  ALL_RANGE_TYPES(AS_TYPED_LIMIT)
+
+};
+
+enum ConstraintMarker {
+  next_two_args_are_constraint,
+};
+
+template <typename T>
+class JVMTypedFlagLimit : public JVMFlagLimit {
+  const T _min;
+  const T _max;
+
+public:
+  // dummy - no range or constraint. This object will not be emitted into the .o file
+  // because we declare it as "const" but has no reference to it.
+  constexpr JVMTypedFlagLimit(int dummy) :
+    JVMFlagLimit(0, 0, 0), _min(0), _max(0) {}
+
+  // range only
+  constexpr JVMTypedFlagLimit(int dummy, T min, T max) :
+    JVMFlagLimit(0, 0, HAS_RANGE), _min(min), _max(max) {}
+
+  // constraint only
+  constexpr JVMTypedFlagLimit(int dummy, ConstraintMarker dummy2, short func, int phase) :
+    JVMFlagLimit(func, phase, HAS_CONSTRAINT), _min(0), _max(0) {}
+
+  // range and constraint
+  constexpr JVMTypedFlagLimit(int dummy, T min, T max, ConstraintMarker dummy2, short func, int phase)  :
+    JVMFlagLimit(func, phase, HAS_RANGE | HAS_CONSTRAINT), _min(min), _max(max) {}
+
+  // constraint and range
+  constexpr JVMTypedFlagLimit(int dummy, ConstraintMarker dummy2, short func, int phase, T min, T max)  :
+    JVMFlagLimit(func, phase, HAS_RANGE | HAS_CONSTRAINT), _min(min), _max(max) {}
+
+  T min() const { return _min; }
+  T max() const { return _max; }
+};
+
+#endif // SHARE_RUNTIME_FLAGS_JVMFLAGLIMIT_HPP
diff --git a/src/hotspot/share/runtime/flags/jvmFlagLookup.cpp b/src/hotspot/share/runtime/flags/jvmFlagLookup.cpp
new file mode 100644
index 00000000000..e8d57967251
--- /dev/null
+++ b/src/hotspot/share/runtime/flags/jvmFlagLookup.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 "runtime/flags/jvmFlag.hpp"
+#include "runtime/flags/jvmFlagLookup.hpp"
+#include "utilities/defaultStream.hpp"
+
+#define DO_FLAG(type, name,...) DO_HASH(FLAG_MEMBER_ENUM(name), XSTR(name))
+
+#define DO_HASH(flag_enum, flag_name) {          \
+  u2 hash = hash_code(flag_name);                \
+  int bucket_index = (int)(hash % NUM_BUCKETS);  \
+  _hashes[flag_enum] = hash;                     \
+  _table[flag_enum] = _buckets[bucket_index];    \
+  _buckets[bucket_index] = (short)flag_enum;     \
+}
+
+constexpr JVMFlagLookup::JVMFlagLookup() : _buckets(), _table(), _hashes() {
+  for (int i = 0; i < NUM_BUCKETS; i++) {
+    _buckets[i] = -1;
+  }
+
+  ALL_FLAGS(DO_FLAG,
+            DO_FLAG,
+            DO_FLAG,
+            DO_FLAG,
+            DO_FLAG,
+            IGNORE_RANGE,
+            IGNORE_CONSTRAINT)
+}
+
+constexpr JVMFlagLookup _flag_lookup_table;
+
+JVMFlag* JVMFlagLookup::find_impl(const char* name, size_t length) const {
+  u2 hash = hash_code(name, length);
+  int bucket_index = (int)(hash % NUM_BUCKETS);
+  for (int flag_enum = _buckets[bucket_index]; flag_enum >= 0; ) {
+    if (_hashes[flag_enum] == hash) {
+      JVMFlag* flag = JVMFlag::flags + flag_enum;
+      if (strncmp(name, flag->_name, length) == 0) {
+        // We know flag->_name has at least <length> bytes.
+        // Make sure it has exactly <length> bytes
+        if (flag->_name[length] == 0) {
+          return flag;
+        }
+      }
+    }
+    flag_enum = (int)_table[flag_enum];
+  }
+
+  return NULL;
+}
+
+JVMFlag* JVMFlagLookup::find(const char* name, size_t length) {
+  return _flag_lookup_table.find_impl(name, length);
+}
diff --git a/src/hotspot/share/runtime/flags/jvmFlagLookup.hpp b/src/hotspot/share/runtime/flags/jvmFlagLookup.hpp
new file mode 100644
index 00000000000..3ac31b0e61e
--- /dev/null
+++ b/src/hotspot/share/runtime/flags/jvmFlagLookup.hpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_RUNTIME_FLAGS_JVMFLAGLOOKUP_HPP
+#define SHARE_RUNTIME_FLAGS_JVMFLAGLOOKUP_HPP
+
+#include "runtime/globals_extension.hpp"
+#include "runtime/flags/jvmFlag.hpp"
+
+// This is a hashtable that maps from (const char*) to (JVMFlag*) to speed up
+// the processing of JVM command-line arguments at runtime.
+//
+// With constexpr, this table is generated at C++ compile time so there's
+// no set up cost at runtime.
+class JVMFlagLookup {
+  static constexpr int NUM_BUCKETS = 277;
+  short _buckets[NUM_BUCKETS];
+  short _table[NUM_JVMFlagsEnum];
+  u2    _hashes[NUM_JVMFlagsEnum];
+
+  // Cannot use strlen() -- it's not constexpr.
+  static constexpr size_t string_len(const char* s) {
+    size_t len = 0;
+    while (*s != 0) {
+      len++;
+      s++;
+    }
+    return len;
+  }
+
+  // This is executed at build-time only, so it doesn't matter if we walk
+  // the string twice.
+  static constexpr u2 hash_code(const char* s) {
+    return hash_code(s, string_len(s));
+  }
+
+  static constexpr u2 hash_code(const char* s, size_t len) {
+    u2 h = 0;
+    while (len -- > 0) {
+      h = (u2)(31*h + (u2) *s);
+      s++;
+    }
+    return h;
+  }
+
+  JVMFlag* find_impl(const char* flag_name, size_t length) const;
+
+public:
+  constexpr JVMFlagLookup();
+  static JVMFlag* find(const char* flag_name, size_t length);
+};
+
+#endif // SHARE_RUNTIME_FLAGS_JVMFLAGLOOKUP_HPP
diff --git a/src/hotspot/share/runtime/flags/jvmFlagRangeList.cpp b/src/hotspot/share/runtime/flags/jvmFlagRangeList.cpp
index 1751a92056f..f79f7ec47f8 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagRangeList.cpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagRangeList.cpp
@@ -31,6 +31,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/flags/jvmFlag.hpp"
 #include "runtime/flags/jvmFlagConstraintList.hpp"
+#include "runtime/flags/jvmFlagConstraintsRuntime.hpp"
 #include "runtime/flags/jvmFlagRangeList.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/globals_extension.hpp"
@@ -241,122 +242,69 @@ class JVMFlagRange_double : public JVMFlagRange {
   }
 };
 
-// No constraint emitting
-void emit_range_no(...)                         { /* NOP */ }
-
-// No constraint emitting if function argument is NOT provided
-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 JVMFlag* flag, int min, int max)       {
-  JVMFlagRangeList::add(new JVMFlagRange_int(flag, 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 JVMFlag* flag, uint min, uint max) {
-  JVMFlagRangeList::add(new JVMFlagRange_uint(flag, 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 JVMFlag* flag, uint64_t min, uint64_t max) {
-  JVMFlagRangeList::add(new JVMFlagRange_uint64_t(flag, 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 JVMFlag* flag, double min, double max) {
-  JVMFlagRangeList::add(new JVMFlagRange_double(flag, min, max));
+#define DEFINE_RANGE_CHECK(T)                                                            \
+JVMFlag::Error JVMFlagRangeChecker::check_ ## T(T value, bool verbose) const {           \
+  assert(exists(), "must be");                                                           \
+  JVMFlagRange_ ## T range(_flag, _limit->as_ ## T()->min(), _limit->as_ ## T()->max()); \
+  return range.check_ ## T(value, verbose);                                              \
 }
 
-// Generate code to call emit_range_xxx function
-#define EMIT_RANGE_START       (void)(0
-#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)
-#define EMIT_RANGE_EXPERIMENTAL_FLAG(type, name, value, doc) EMIT_RANGE(type, name)
-#define EMIT_RANGE_MANAGEABLE_FLAG(type, name, value, doc)   EMIT_RANGE(type, name)
-#define EMIT_RANGE_PRODUCT_RW_FLAG(type, name, value, doc)   EMIT_RANGE(type, name)
-#define EMIT_RANGE_PD_PRODUCT_FLAG(type, name, doc)          EMIT_RANGE(type, name)
-#define EMIT_RANGE_PD_DIAGNOSTIC_FLAG(type, name, doc)       EMIT_RANGE(type, name)
-#ifndef PRODUCT
-#define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    EMIT_RANGE(type, name)
-#define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        EMIT_RANGE(type, name)
-#define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   EMIT_RANGE(type, name)
-#else
-#define EMIT_RANGE_DEVELOPER_FLAG(type, name, value, doc)    EMIT_RANGE_NO
-#define EMIT_RANGE_PD_DEVELOPER_FLAG(type, name, doc)        EMIT_RANGE_NO
-#define EMIT_RANGE_NOTPRODUCT_FLAG(type, name, value, doc)   EMIT_RANGE_NO
-#endif
-#ifdef _LP64
-#define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_RANGE(type, name)
-#else
-#define EMIT_RANGE_LP64_PRODUCT_FLAG(type, name, value, doc) EMIT_RANGE_NO
-#endif
-#define EMIT_RANGE_END         );
-
-// Generate func argument to pass into emit_range_xxx functions
-#define EMIT_RANGE_CHECK(a, b)                               , a, b
-
-#define INITIAL_RANGES_SIZE 379
-GrowableArray<JVMFlagRange*>* JVMFlagRangeList::_ranges = NULL;
-
-// Check the ranges of all flags that have them
-void JVMFlagRangeList::init(void) {
-
-  _ranges = new (ResourceObj::C_HEAP, mtArguments) GrowableArray<JVMFlagRange*>(INITIAL_RANGES_SIZE, mtArguments);
-
-  EMIT_RANGE_START
-
-  ALL_FLAGS(EMIT_RANGE_DEVELOPER_FLAG,
-            EMIT_RANGE_PD_DEVELOPER_FLAG,
-            EMIT_RANGE_PRODUCT_FLAG,
-            EMIT_RANGE_PD_PRODUCT_FLAG,
-            EMIT_RANGE_DIAGNOSTIC_FLAG,
-            EMIT_RANGE_PD_DIAGNOSTIC_FLAG,
-            EMIT_RANGE_EXPERIMENTAL_FLAG,
-            EMIT_RANGE_NOTPRODUCT_FLAG,
-            EMIT_RANGE_MANAGEABLE_FLAG,
-            EMIT_RANGE_PRODUCT_RW_FLAG,
-            EMIT_RANGE_LP64_PRODUCT_FLAG,
-            EMIT_RANGE_CHECK,
-            IGNORE_CONSTRAINT)
-
-  EMIT_RANGE_END
+ALL_RANGE_TYPES(DEFINE_RANGE_CHECK)
+
+
+JVMFlag::Error JVMFlagRangeChecker::check(bool verbose) const {
+#define CHECK_RANGE(T)                                                                     \
+  if (_flag->is_ ## T()) {                                                                 \
+    JVMFlagRange_ ## T range(_flag, _limit->as_ ## T()->min(), _limit->as_ ## T()->max()); \
+    return range.check(verbose);                                                           \
+  }
+
+  ALL_RANGE_TYPES(CHECK_RANGE);
+
+  ShouldNotReachHere();
+  return JVMFlag::INVALID_FLAG;
 }
 
-JVMFlagRange* JVMFlagRangeList::find(const JVMFlag* flag) {
-  JVMFlagRange* found = NULL;
-  for (int i=0; i<length(); i++) {
-    JVMFlagRange* range = at(i);
-    if (range->flag() == flag) {
-      found = range;
-      break;
-    }
+void JVMFlagRangeChecker::print(outputStream* out) const {
+#define PRINT_RANGE(T)                                                                     \
+  if (_flag->is_ ## T()) {                                                                 \
+    JVMFlagRange_ ## T range(_flag, _limit->as_ ## T()->min(), _limit->as_ ## T()->max()); \
+    range.print(out);                                                                      \
+    return;                                                                                \
   }
-  return found;
+
+  ALL_RANGE_TYPES(PRINT_RANGE);
+
+  ShouldNotReachHere();
 }
 
 void JVMFlagRangeList::print(outputStream* st, const JVMFlag* flag, RangeStrFunc default_range_str_func) {
-  JVMFlagRange* range = JVMFlagRangeList::find(flag);
-  if (range != NULL) {
-    range->print(st);
+  JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
+  if (range.exists()) {
+    range.print(st);
   } else {
-    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());
+    const JVMFlagLimit* limit = JVMFlagLimit::get_constraint(flag);
+    if (limit != NULL) {
+      void* func = limit->constraint_func();
+
+      // Two special cases where the lower limit of the range is defined by an os:: function call
+      // and cannot be initialized at compile time with constexpr.
+      if (func == (void*)VMPageSizeConstraintFunc) {
+        uintx min = (uintx)os::vm_page_size();
+        uintx max = max_uintx;
+
+        JVMFlagRange_uintx tmp(flag, min, max);
+        tmp.print(st);
+      } else if (func == (void*)NUMAInterleaveGranularityConstraintFunc) {
+        size_t min = os::vm_allocation_granularity();
+        size_t max = NOT_LP64(2*G) LP64_ONLY(8192*G);
+
+        JVMFlagRange_size_t tmp(flag, min, max);
+        tmp.print(st);
+      } else {
+        assert(default_range_str_func!=NULL, "default_range_str_func must be provided");
+        st->print("%s", default_range_str_func());
+      }
     } else {
       st->print("[                           ...                           ]");
     }
@@ -365,9 +313,9 @@ void JVMFlagRangeList::print(outputStream* st, const JVMFlag* flag, RangeStrFunc
 
 bool JVMFlagRangeList::check_ranges() {
   bool status = true;
-  for (int i=0; i<length(); i++) {
-    JVMFlagRange* range = at(i);
-    if (range->check(true) != JVMFlag::SUCCESS) status = false;
+  for (int i = 0; i < NUM_JVMFlagsEnum; i++) {
+    JVMFlagRangeChecker range(&JVMFlag::flags[i], JVMFlagLimit::get_range_at(i));
+    if (range.exists() && range.check(true) != JVMFlag::SUCCESS) status = false;
   }
   return status;
 }
diff --git a/src/hotspot/share/runtime/flags/jvmFlagRangeList.hpp b/src/hotspot/share/runtime/flags/jvmFlagRangeList.hpp
index 0219f2fad94..ecc30842126 100644
--- a/src/hotspot/share/runtime/flags/jvmFlagRangeList.hpp
+++ b/src/hotspot/share/runtime/flags/jvmFlagRangeList.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 #define SHARE_RUNTIME_FLAGS_JVMFLAGRANGELIST_HPP
 
 #include "runtime/flags/jvmFlag.hpp"
-#include "utilities/growableArray.hpp"
+#include "runtime/flags/jvmFlagLimit.hpp"
 
 /*
  * Here we have a mechanism for extracting ranges specified in flag macro tables.
@@ -58,14 +58,23 @@ class JVMFlagRange : public CHeapObj<mtArguments> {
   virtual void print(outputStream* st) { ; }
 };
 
+class JVMFlagRangeChecker {
+  const JVMFlag* _flag;
+  const JVMFlagLimit* _limit;
+
+public:
+  JVMFlagRangeChecker(const JVMFlag* flag, const JVMFlagLimit* limit) : _flag(flag), _limit(limit) {}
+  bool exists() const { return _limit != NULL; }
+  JVMFlag::Error check(bool verbose = true) const;
+  void print(outputStream* st) const;
+
+#define DECLARE_RANGE_CHECK(T) JVMFlag::Error check_ ## T(T new_value, bool verbose = true) const;
+  ALL_RANGE_TYPES(DECLARE_RANGE_CHECK)
+};
+
 class JVMFlagRangeList : public AllStatic {
-  static GrowableArray<JVMFlagRange*>* _ranges;
 public:
-  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 JVMFlag* flag);
-  static void add(JVMFlagRange* range) { _ranges->append(range); }
+  static JVMFlagRangeChecker find(const JVMFlag* flag) { return JVMFlagRangeChecker(flag, JVMFlagLimit::get_range(flag)); }
   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();
diff --git a/src/hotspot/share/runtime/frame.cpp b/src/hotspot/share/runtime/frame.cpp
index 01b0e641cb1..f076b558d5d 100644
--- a/src/hotspot/share/runtime/frame.cpp
+++ b/src/hotspot/share/runtime/frame.cpp
@@ -672,13 +672,13 @@ void frame::print_on_error(outputStream* st, char* buf, int buflen, bool verbose
 */
 class InterpreterFrameClosure : public OffsetClosure {
  private:
-  frame* _fr;
-  OopClosure* _f;
-  int    _max_locals;
-  int    _max_stack;
+  const frame* _fr;
+  OopClosure*  _f;
+  int          _max_locals;
+  int          _max_stack;
 
  public:
-  InterpreterFrameClosure(frame* fr, int max_locals, int max_stack,
+  InterpreterFrameClosure(const frame* fr, int max_locals, int max_stack,
                           OopClosure* f) {
     _fr         = fr;
     _max_locals = max_locals;
@@ -709,16 +709,15 @@ class InterpreterFrameClosure : public OffsetClosure {
   }
 
   int max_locals()  { return _max_locals; }
-  frame* fr()       { return _fr; }
 };
 
 
 class InterpretedArgumentOopFinder: public SignatureIterator {
  private:
-  OopClosure* _f;        // Closure to invoke
-  int    _offset;        // TOS-relative offset, decremented with each argument
-  bool   _has_receiver;  // true if the callee has a receiver
-  frame* _fr;
+  OopClosure*  _f;             // Closure to invoke
+  int          _offset;        // TOS-relative offset, decremented with each argument
+  bool         _has_receiver;  // true if the callee has a receiver
+  const frame* _fr;
 
   friend class SignatureIterator;  // so do_parameters_on can call do_type
   void do_type(BasicType type) {
@@ -733,7 +732,7 @@ class InterpretedArgumentOopFinder: public SignatureIterator {
   }
 
  public:
-  InterpretedArgumentOopFinder(Symbol* signature, bool has_receiver, frame* fr, OopClosure* f) : SignatureIterator(signature), _has_receiver(has_receiver) {
+  InterpretedArgumentOopFinder(Symbol* signature, bool has_receiver, const frame* fr, OopClosure* f) : SignatureIterator(signature), _has_receiver(has_receiver) {
     // compute size of arguments
     int args_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
     assert(!fr->is_interpreted_frame() ||
@@ -769,10 +768,10 @@ class InterpretedArgumentOopFinder: public SignatureIterator {
 // visits and GC's all the arguments in entry frame
 class EntryFrameOopFinder: public SignatureIterator {
  private:
-  bool   _is_static;
-  int    _offset;
-  frame* _fr;
-  OopClosure* _f;
+  bool         _is_static;
+  int          _offset;
+  const frame* _fr;
+  OopClosure*  _f;
 
   friend class SignatureIterator;  // so do_parameters_on can call do_type
   void do_type(BasicType type) {
@@ -789,7 +788,7 @@ class EntryFrameOopFinder: public SignatureIterator {
   }
 
  public:
-  EntryFrameOopFinder(frame* frame, Symbol* signature, bool is_static) : SignatureIterator(signature) {
+  EntryFrameOopFinder(const frame* frame, Symbol* signature, bool is_static) : SignatureIterator(signature) {
     _f = NULL; // will be set later
     _fr = frame;
     _is_static = is_static;
@@ -811,7 +810,7 @@ oop* frame::interpreter_callee_receiver_addr(Symbol* signature) {
 }
 
 
-void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache) {
+void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache) const {
   assert(is_interpreted_frame(), "Not an interpreted frame");
   assert(map != NULL, "map must be set");
   Thread *thread = Thread::current();
@@ -892,12 +891,12 @@ void frame::oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool quer
 }
 
 
-void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) {
+void frame::oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) const {
   InterpretedArgumentOopFinder finder(signature, has_receiver, this, f);
   finder.oops_do();
 }
 
-void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) {
+void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) const {
   assert(_cb != NULL, "sanity check");
   if (_cb->oop_maps() != NULL) {
     OopMapSet::oops_do(this, reg_map, f);
@@ -974,7 +973,7 @@ class CompiledArgumentOopFinder: public SignatureIterator {
 };
 
 void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix,
-                                       const RegisterMap* reg_map, OopClosure* f) {
+                                       const RegisterMap* reg_map, OopClosure* f) const {
   ResourceMark rm;
   CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
   finder.oops_do();
@@ -1023,7 +1022,7 @@ oop frame::get_native_receiver() {
   return owner;
 }
 
-void frame::oops_entry_do(OopClosure* f, const RegisterMap* map) {
+void frame::oops_entry_do(OopClosure* f, const RegisterMap* map) const {
   assert(map != NULL, "map must be set");
   if (map->include_argument_oops()) {
     // must collect argument oops, as nobody else is doing it
@@ -1037,7 +1036,7 @@ void frame::oops_entry_do(OopClosure* f, const RegisterMap* map) {
 }
 
 
-void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache) {
+void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map, bool use_interpreter_oop_map_cache) const {
 #ifndef PRODUCT
   // simulate GC crash here to dump java thread in error report
   if (CrashGCForDumpingJavaThread) {
@@ -1056,7 +1055,7 @@ void frame::oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* ma
   }
 }
 
-void frame::nmethods_do(CodeBlobClosure* cf) {
+void frame::nmethods_do(CodeBlobClosure* cf) const {
   if (_cb != NULL && _cb->is_nmethod()) {
     cf->do_code_blob(_cb);
   }
@@ -1064,7 +1063,7 @@ void frame::nmethods_do(CodeBlobClosure* cf) {
 
 
 // Call f closure on the interpreted Method*s in the stack.
-void frame::metadata_do(MetadataClosure* f) {
+void frame::metadata_do(MetadataClosure* f) const {
   ResourceMark rm;
   if (is_interpreted_frame()) {
     Method* m = this->interpreter_frame_method();
@@ -1073,7 +1072,7 @@ void frame::metadata_do(MetadataClosure* f) {
   }
 }
 
-void frame::verify(const RegisterMap* map) {
+void frame::verify(const RegisterMap* map) const {
   // for now make sure receiver type is correct
   if (is_interpreted_frame()) {
     Method* method = interpreter_frame_method();
@@ -1087,7 +1086,7 @@ void frame::verify(const RegisterMap* map) {
 #if COMPILER2_OR_JVMCI
   assert(DerivedPointerTable::is_empty(), "must be empty before verify");
 #endif
-  oops_do_internal(&VerifyOopClosure::verify_oop, NULL, (RegisterMap*)map, false);
+  oops_do_internal(&VerifyOopClosure::verify_oop, NULL, map, false);
 }
 
 
diff --git a/src/hotspot/share/runtime/frame.hpp b/src/hotspot/share/runtime/frame.hpp
index 5dfe01d3ffa..fec45c5c11d 100644
--- a/src/hotspot/share/runtime/frame.hpp
+++ b/src/hotspot/share/runtime/frame.hpp
@@ -359,27 +359,27 @@ class frame {
   oop* oopmapreg_to_location(VMReg reg, const RegisterMap* reg_map) const;
 
   // Oops-do's
-  void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f);
-  void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true);
+  void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f) const;
+  void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true) const;
 
  private:
-  void oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f);
+  void oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f) const;
 
   // Iteration of oops
-  void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map, bool use_interpreter_oop_map_cache);
-  void oops_entry_do(OopClosure* f, const RegisterMap* map);
-  void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map);
+  void oops_do_internal(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map, bool use_interpreter_oop_map_cache) const;
+  void oops_entry_do(OopClosure* f, const RegisterMap* map) const;
+  void oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map) const;
   int adjust_offset(Method* method, int index); // helper for above fn
  public:
   // Memory management
-  void oops_do(OopClosure* f, CodeBlobClosure* cf, RegisterMap* map) { oops_do_internal(f, cf, map, true); }
-  void nmethods_do(CodeBlobClosure* cf);
+  void oops_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* map) const { oops_do_internal(f, cf, map, true); }
+  void nmethods_do(CodeBlobClosure* cf) const;
 
   // RedefineClasses support for finding live interpreted methods on the stack
-  void metadata_do(MetadataClosure* f);
+  void metadata_do(MetadataClosure* f) const;
 
   // Verification
-  void verify(const RegisterMap* map);
+  void verify(const RegisterMap* map) const;
   static bool verify_return_pc(address x);
   // Usage:
   // assert(frame::verify_return_pc(return_address), "must be a return pc");
diff --git a/src/hotspot/share/runtime/globals.cpp b/src/hotspot/share/runtime/globals.cpp
index 0a95d95f21e..0371fd72f9f 100644
--- a/src/hotspot/share/runtime/globals.cpp
+++ b/src/hotspot/share/runtime/globals.cpp
@@ -40,39 +40,22 @@
 #include "utilities/stringUtils.hpp"
 
 // Implementation macros
-#define MATERIALIZE_PRODUCT_FLAG(type, name, value, doc)      type name = value;
-#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, doc)          type name = pd_##name;
-#define MATERIALIZE_DIAGNOSTIC_FLAG(type, name, value, doc)   type name = value;
-#define MATERIALIZE_PD_DIAGNOSTIC_FLAG(type, name, doc)       type name = pd_##name;
-#define MATERIALIZE_EXPERIMENTAL_FLAG(type, name, value, doc) type name = value;
-#define MATERIALIZE_MANAGEABLE_FLAG(type, name, value, doc)   type name = value;
-#define MATERIALIZE_PRODUCT_RW_FLAG(type, name, value, doc)   type name = value;
+#define MATERIALIZE_PRODUCT_FLAG(type, name, value, ...)      type name = value;
+#define MATERIALIZE_PD_PRODUCT_FLAG(type, name, ...)          type name = pd_##name;
 #ifdef PRODUCT
-#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)
-#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)
-#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)
+#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, ...)
+#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, ...)
+#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, ...)
 #else
-#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, doc)    type name = value;
-#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, doc)        type name = pd_##name;
-#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, doc)   type name = value;
+#define MATERIALIZE_DEVELOPER_FLAG(type, name, value, ...)    type name = value;
+#define MATERIALIZE_PD_DEVELOPER_FLAG(type, name, ...)        type name = pd_##name;
+#define MATERIALIZE_NOTPRODUCT_FLAG(type, name, value, ...)   type name = value;
 #endif // PRODUCT
-#ifdef _LP64
-#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) type name = value;
-#else
-#define MATERIALIZE_LP64_PRODUCT_FLAG(type, name, value, doc) /* flag is constant */
-#endif // _LP64
-
 
-ALL_FLAGS(MATERIALIZE_DEVELOPER_FLAG,     \
-          MATERIALIZE_PD_DEVELOPER_FLAG,  \
-          MATERIALIZE_PRODUCT_FLAG,       \
-          MATERIALIZE_PD_PRODUCT_FLAG,    \
-          MATERIALIZE_DIAGNOSTIC_FLAG,    \
-          MATERIALIZE_PD_DIAGNOSTIC_FLAG, \
-          MATERIALIZE_EXPERIMENTAL_FLAG,  \
-          MATERIALIZE_NOTPRODUCT_FLAG,    \
-          MATERIALIZE_MANAGEABLE_FLAG,    \
-          MATERIALIZE_PRODUCT_RW_FLAG,    \
-          MATERIALIZE_LP64_PRODUCT_FLAG,  \
-          IGNORE_RANGE,                   \
+ALL_FLAGS(MATERIALIZE_DEVELOPER_FLAG,
+          MATERIALIZE_PD_DEVELOPER_FLAG,
+          MATERIALIZE_PRODUCT_FLAG,
+          MATERIALIZE_PD_PRODUCT_FLAG,
+          MATERIALIZE_NOTPRODUCT_FLAG,
+          IGNORE_RANGE,
           IGNORE_CONSTRAINT)
diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp
index 8ff669a408c..3c7c1df67af 100644
--- a/src/hotspot/share/runtime/globals.hpp
+++ b/src/hotspot/share/runtime/globals.hpp
@@ -38,23 +38,37 @@
 // develop flags are settable / visible only during development and are constant in the PRODUCT version
 // product flags are always settable / visible
 // notproduct flags are settable / visible only during development and are not declared in the PRODUCT version
+// develop_pd/product_pd flags are the same as develop/product, except that their default values
+// are specified in platform-dependent header files.
+
+// Flags must be declared with the following number of parameters:
+// non-pd flags:
+//    (type, name, default_value, doc), or
+//    (type, name, default_value, extra_attrs, doc)
+// pd flags:
+//    (type, name, doc), or
+//    (type, name, extra_attrs, doc)
 
 // A flag must be declared with one of the following types:
 // bool, int, uint, intx, uintx, size_t, ccstr, ccstrlist, double, or uint64_t.
 // The type "ccstr" and "ccstrlist" are an alias for "const char*" and is used
 // only in this file, because the macrology requires single-token type names.
 
-// Note: Diagnostic options not meant for VM tuning or for product modes.
-// They are to be used for VM quality assurance or field diagnosis
-// of VM bugs.  They are hidden so that users will not be encouraged to
-// try them as if they were VM ordinary execution options.  However, they
-// are available in the product version of the VM.  Under instruction
-// from support engineers, VM customers can turn them on to collect
-// diagnostic information about VM problems.  To use a VM diagnostic
-// option, you must first specify +UnlockDiagnosticVMOptions.
-// (This master switch also affects the behavior of -Xprintflags.)
+// The optional extra_attrs parameter may have one of the following values:
+// DIAGNOSTIC, EXPERIMENTAL, or MANAGEABLE. Currently extra_attrs can be used
+// only with product/product_pd flags.
+//
+// DIAGNOSTIC options are not meant for VM tuning or for product modes.
+//    They are to be used for VM quality assurance or field diagnosis
+//    of VM bugs.  They are hidden so that users will not be encouraged to
+//    try them as if they were VM ordinary execution options.  However, they
+//    are available in the product version of the VM.  Under instruction
+//    from support engineers, VM customers can turn them on to collect
+//    diagnostic information about VM problems.  To use a VM diagnostic
+//    option, you must first specify +UnlockDiagnosticVMOptions.
+//    (This master switch also affects the behavior of -Xprintflags.)
 //
-// experimental flags are in support of features that are not
+// EXPERIMENTAL flags are in support of features that are not
 //    part of the officially supported product, but are available
 //    for experimenting with. They could, for example, be performance
 //    features that may not have undergone full or rigorous QA, but which may
@@ -70,7 +84,7 @@
 //    and they are not supported on production loads, except under explicit
 //    direction from support engineers.
 //
-// manageable flags are writeable external product flags.
+// MANAGEABLE flags are writeable external product flags.
 //    They are dynamically writeable through the JDK management interface
 //    (com.sun.management.HotSpotDiagnosticMXBean API) and also through JConsole.
 //    These flags are external exported interface (see CCC).  The list of
@@ -84,20 +98,7 @@
 //      and not reuse state related to the flag state at any given time.
 //    - you want the flag to be queried programmatically by the customers.
 //
-// product_rw flags are writeable internal product flags.
-//    They are like "manageable" flags but for internal/private use.
-//    The list of product_rw flags are internal/private flags which
-//    may be changed/removed in a future release.  It can be set
-//    through the management interface to get/set value
-//    when the name of flag is supplied.
-//
-//    A flag can be made as "product_rw" only if
-//    - the VM implementation supports dynamic setting of the flag.
-//      This implies that the VM must *always* query the flag variable
-//      and not reuse state related to the flag state at any given time.
-//
-// Note that when there is a need to support develop flags to be writeable,
-// it can be done in the same way as product_rw.
+
 //
 // range is a macro that will expand to min and max arguments for range
 //    checking code if provided - see jvmFlagRangeList.hpp
@@ -112,28 +113,52 @@ const size_t minimumStringTableSize = 128;
 const size_t defaultSymbolTableSize = 32768; // 2^15
 const size_t minimumSymbolTableSize = 1024;
 
-#define RUNTIME_FLAGS(develop, \
-                      develop_pd, \
-                      product, \
-                      product_pd, \
-                      diagnostic, \
-                      diagnostic_pd, \
-                      experimental, \
-                      notproduct, \
-                      manageable, \
-                      product_rw, \
-                      lp64_product, \
-                      range, \
-                      constraint) \
-                                                                            \
-  lp64_product(bool, UseCompressedOops, false,                              \
+#ifdef _LP64
+#define LP64_RUNTIME_FLAGS(develop,                                         \
+                           develop_pd,                                      \
+                           product,                                         \
+                           product_pd,                                      \
+                           notproduct,                                      \
+                           range,                                           \
+                           constraint)                                      \
+                                                                            \
+  product(bool, UseCompressedOops, false,                                   \
           "Use 32-bit object references in 64-bit VM. "                     \
           "lp64_product means flag is always constant in 32 bit VM")        \
                                                                             \
-  lp64_product(bool, UseCompressedClassPointers, false,                     \
+  product(bool, UseCompressedClassPointers, false,                          \
           "Use 32-bit class pointers in 64-bit VM. "                        \
           "lp64_product means flag is always constant in 32 bit VM")        \
                                                                             \
+  product(intx, ObjectAlignmentInBytes, 8,                                  \
+          "Default object alignment in bytes, 8 is minimum")                \
+          range(8, 256)                                                     \
+          constraint(ObjectAlignmentInBytesConstraintFunc, AtParse)
+
+#else
+// !_LP64
+
+#define LP64_RUNTIME_FLAGS(develop,                                         \
+                           develop_pd,                                      \
+                           product,                                         \
+                           product_pd,                                      \
+                           notproduct,                                      \
+                           range,                                           \
+                           constraint)
+const bool UseCompressedOops = false;
+const bool UseCompressedClassPointers = false;
+const intx ObjectAlignmentInBytes = 8;
+
+#endif // _LP64
+
+#define RUNTIME_FLAGS(develop,                                              \
+                      develop_pd,                                           \
+                      product,                                              \
+                      product_pd,                                           \
+                      notproduct,                                           \
+                      range,                                                \
+                      constraint)                                           \
+                                                                            \
   notproduct(bool, CheckCompressedOops, true,                               \
           "Generate checks in encoding/decoding code in debug VM")          \
                                                                             \
@@ -143,24 +168,19 @@ const size_t minimumSymbolTableSize = 1024;
           "region.")                                                        \
           range(1, max_uintx)                                               \
                                                                             \
-  lp64_product(intx, ObjectAlignmentInBytes, 8,                             \
-          "Default object alignment in bytes, 8 is minimum")                \
-          range(8, 256)                                                     \
-          constraint(ObjectAlignmentInBytesConstraintFunc,AtParse)          \
-                                                                            \
   develop(bool, CleanChunkPoolAsync, true,                                  \
           "Clean the chunk pool asynchronously")                            \
                                                                             \
-  diagnostic(uint, HandshakeTimeout, 0,                                     \
+  product(uint, HandshakeTimeout, 0, DIAGNOSTIC,                            \
           "If nonzero set a timeout in milliseconds for handshakes")        \
                                                                             \
-  experimental(bool, AlwaysSafeConstructors, false,                         \
+  product(bool, AlwaysSafeConstructors, false, EXPERIMENTAL,                \
           "Force safe construction, as if all fields are final.")           \
                                                                             \
-  diagnostic(bool, UnlockDiagnosticVMOptions, trueInDebug,                  \
+  product(bool, UnlockDiagnosticVMOptions, trueInDebug, DIAGNOSTIC,         \
           "Enable normal processing of flags relating to field diagnostics")\
                                                                             \
-  experimental(bool, UnlockExperimentalVMOptions, false,                    \
+  product(bool, UnlockExperimentalVMOptions, false, EXPERIMENTAL,           \
           "Enable normal processing of flags relating to experimental "     \
           "features")                                                       \
                                                                             \
@@ -189,7 +209,7 @@ const size_t minimumSymbolTableSize = 1024;
                                                                             \
   product(size_t, NUMAInterleaveGranularity, 2*M,                           \
           "Granularity to use for NUMA interleaving on Windows OS")         \
-          range(os::vm_allocation_granularity(), NOT_LP64(2*G) LP64_ONLY(8192*G)) \
+          constraint(NUMAInterleaveGranularityConstraintFunc, AtParse)      \
                                                                             \
   product(uintx, NUMAChunkResizeWeight, 20,                                 \
           "Percentage (0-100) used to weight the current sample when "      \
@@ -220,7 +240,7 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, UseSHA, false,                                              \
           "Control whether SHA instructions are used when available")       \
                                                                             \
-  diagnostic(bool, UseGHASHIntrinsics, false,                               \
+  product(bool, UseGHASHIntrinsics, false, DIAGNOSTIC,                      \
           "Use intrinsics for GHASH versions of crypto")                    \
                                                                             \
   product(bool, UseBASE64Intrinsics, false,                                 \
@@ -243,15 +263,12 @@ const size_t minimumSymbolTableSize = 1024;
   develop(bool, TraceRelocator, false,                                      \
           "Trace the bytecode relocator")                                   \
                                                                             \
-  develop(bool, TraceLongCompiles, false,                                   \
-          "Print out every time compilation is longer than "                \
-          "a given threshold")                                              \
                                                                             \
-  diagnostic(bool, SafepointALot, false,                                    \
+  product(bool, SafepointALot, false, DIAGNOSTIC,                           \
           "Generate a lot of safepoints. This works with "                  \
           "GuaranteedSafepointInterval")                                    \
                                                                             \
-  diagnostic(bool, HandshakeALot, false,                                    \
+  product(bool, HandshakeALot, false, DIAGNOSTIC,                           \
           "Generate a lot of handshakes. This works with "                  \
           "GuaranteedSafepointInterval")                                    \
                                                                             \
@@ -265,7 +282,7 @@ const size_t minimumSymbolTableSize = 1024;
   develop(bool, VerifyStack, false,                                         \
           "Verify stack of each thread when it is entering a runtime call") \
                                                                             \
-  diagnostic(bool, ForceUnreachable, false,                                 \
+  product(bool, ForceUnreachable, false, DIAGNOSTIC,                        \
           "Make all non code cache addresses to be unreachable by "         \
           "forcing use of 64bit literal fixups")                            \
                                                                             \
@@ -285,27 +302,27 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, UseInlineCaches, true,                                      \
           "Use Inline Caches for virtual calls ")                           \
                                                                             \
-  diagnostic(bool, InlineArrayCopy, true,                                   \
+  product(bool, InlineArrayCopy, true, DIAGNOSTIC,                          \
           "Inline arraycopy native that is known to be part of "            \
           "base library DLL")                                               \
                                                                             \
-  diagnostic(bool, InlineObjectHash, true,                                  \
+  product(bool, InlineObjectHash, true, DIAGNOSTIC,                         \
           "Inline Object::hashCode() native that is known to be part "      \
           "of base library DLL")                                            \
                                                                             \
-  diagnostic(bool, InlineNatives, true,                                     \
+  product(bool, InlineNatives, true, DIAGNOSTIC,                            \
           "Inline natives that are known to be part of base library DLL")   \
                                                                             \
-  diagnostic(bool, InlineMathNatives, true,                                 \
+  product(bool, InlineMathNatives, true, DIAGNOSTIC,                        \
           "Inline SinD, CosD, etc.")                                        \
                                                                             \
-  diagnostic(bool, InlineClassNatives, true,                                \
+  product(bool, InlineClassNatives, true, DIAGNOSTIC,                       \
           "Inline Class.isInstance, etc")                                   \
                                                                             \
-  diagnostic(bool, InlineThreadNatives, true,                               \
+  product(bool, InlineThreadNatives, true, DIAGNOSTIC,                      \
           "Inline Thread.currentThread, etc")                               \
                                                                             \
-  diagnostic(bool, InlineUnsafeOps, true,                                   \
+  product(bool, InlineUnsafeOps, true, DIAGNOSTIC,                          \
           "Inline memory ops (native methods) from Unsafe")                 \
                                                                             \
   product(bool, CriticalJNINatives, true,                                   \
@@ -314,49 +331,49 @@ const size_t minimumSymbolTableSize = 1024;
   notproduct(bool, StressCriticalJNINatives, false,                         \
           "Exercise register saving code in critical natives")              \
                                                                             \
-  diagnostic(bool, UseAESIntrinsics, false,                                 \
+  product(bool, UseAESIntrinsics, false, DIAGNOSTIC,                        \
           "Use intrinsics for AES versions of crypto")                      \
                                                                             \
-  diagnostic(bool, UseAESCTRIntrinsics, false,                              \
+  product(bool, UseAESCTRIntrinsics, false, DIAGNOSTIC,                     \
           "Use intrinsics for the paralleled version of AES/CTR crypto")    \
                                                                             \
-  diagnostic(bool, UseMD5Intrinsics, false,                                 \
+  product(bool, UseMD5Intrinsics, false, DIAGNOSTIC,                        \
           "Use intrinsics for MD5 crypto hash function")                    \
                                                                             \
-  diagnostic(bool, UseSHA1Intrinsics, false,                                \
+  product(bool, UseSHA1Intrinsics, false, DIAGNOSTIC,                       \
           "Use intrinsics for SHA-1 crypto hash function. "                 \
           "Requires that UseSHA is enabled.")                               \
                                                                             \
-  diagnostic(bool, UseSHA256Intrinsics, false,                              \
+  product(bool, UseSHA256Intrinsics, false, DIAGNOSTIC,                     \
           "Use intrinsics for SHA-224 and SHA-256 crypto hash functions. "  \
           "Requires that UseSHA is enabled.")                               \
                                                                             \
-  diagnostic(bool, UseSHA512Intrinsics, false,                              \
+  product(bool, UseSHA512Intrinsics, false, DIAGNOSTIC,                     \
           "Use intrinsics for SHA-384 and SHA-512 crypto hash functions. "  \
           "Requires that UseSHA is enabled.")                               \
                                                                             \
-  diagnostic(bool, UseCRC32Intrinsics, false,                               \
+  product(bool, UseCRC32Intrinsics, false, DIAGNOSTIC,                      \
           "use intrinsics for java.util.zip.CRC32")                         \
                                                                             \
-  diagnostic(bool, UseCRC32CIntrinsics, false,                              \
+  product(bool, UseCRC32CIntrinsics, false, DIAGNOSTIC,                     \
           "use intrinsics for java.util.zip.CRC32C")                        \
                                                                             \
-  diagnostic(bool, UseAdler32Intrinsics, false,                             \
+  product(bool, UseAdler32Intrinsics, false, DIAGNOSTIC,                    \
           "use intrinsics for java.util.zip.Adler32")                       \
                                                                             \
-  diagnostic(bool, UseVectorizedMismatchIntrinsic, false,                   \
+  product(bool, UseVectorizedMismatchIntrinsic, false, DIAGNOSTIC,          \
           "Enables intrinsification of ArraysSupport.vectorizedMismatch()") \
                                                                             \
-  diagnostic(bool, UseCopySignIntrinsic, false,                             \
+  product(bool, UseCopySignIntrinsic, false, DIAGNOSTIC,                    \
           "Enables intrinsification of Math.copySign")                      \
                                                                             \
-  diagnostic(bool, UseSignumIntrinsic, false,                               \
+  product(bool, UseSignumIntrinsic, false, DIAGNOSTIC,                      \
           "Enables intrinsification of Math.signum")                        \
                                                                             \
-  diagnostic(ccstrlist, DisableIntrinsic, "",                               \
+  product(ccstrlist, DisableIntrinsic, "", DIAGNOSTIC,                      \
          "do not expand intrinsics whose (internal) names appear here")     \
                                                                             \
-  diagnostic(ccstrlist, ControlIntrinsic, "",                               \
+  product(ccstrlist, ControlIntrinsic, "", DIAGNOSTIC,                      \
          "Control intrinsics using a list of +/- (internal) names, "        \
          "separated by commas")                                             \
                                                                             \
@@ -389,13 +406,13 @@ const size_t minimumSymbolTableSize = 1024;
           "Time out and warn or fail after SafepointTimeoutDelay "          \
           "milliseconds if failed to reach safepoint")                      \
                                                                             \
-  diagnostic(bool, AbortVMOnSafepointTimeout, false,                        \
+  product(bool, AbortVMOnSafepointTimeout, false, DIAGNOSTIC,               \
           "Abort upon failure to reach safepoint (see SafepointTimeout)")   \
                                                                             \
-  diagnostic(bool, AbortVMOnVMOperationTimeout, false,                      \
+  product(bool, AbortVMOnVMOperationTimeout, false, DIAGNOSTIC,             \
           "Abort upon failure to complete VM operation promptly")           \
                                                                             \
-  diagnostic(intx, AbortVMOnVMOperationTimeoutDelay, 1000,                  \
+  product(intx, AbortVMOnVMOperationTimeoutDelay, 1000, DIAGNOSTIC,         \
           "Delay in milliseconds for option AbortVMOnVMOperationTimeout")   \
           range(0, max_intx)                                                \
                                                                             \
@@ -418,17 +435,17 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, MaxFDLimit, true,                                           \
           "Bump the number of file descriptors to maximum (Unix only)")     \
                                                                             \
-  diagnostic(bool, LogEvents, true,                                         \
+  product(bool, LogEvents, true, DIAGNOSTIC,                                \
           "Enable the various ring buffer event logs")                      \
                                                                             \
-  diagnostic(uintx, LogEventsBufferEntries, 20,                             \
+  product(uintx, LogEventsBufferEntries, 20, DIAGNOSTIC,                    \
           "Number of ring buffer event logs")                               \
           range(1, NOT_LP64(1*K) LP64_ONLY(1*M))                            \
                                                                             \
-  diagnostic(bool, BytecodeVerificationRemote, true,                        \
+  product(bool, BytecodeVerificationRemote, true, DIAGNOSTIC,               \
           "Enable the Java bytecode verifier for remote classes")           \
                                                                             \
-  diagnostic(bool, BytecodeVerificationLocal, false,                        \
+  product(bool, BytecodeVerificationLocal, false, DIAGNOSTIC,               \
           "Enable the Java bytecode verifier for local classes")            \
                                                                             \
   develop(bool, ForceFloatExceptions, trueInDebug,                          \
@@ -515,16 +532,16 @@ const size_t minimumSymbolTableSize = 1024;
   product(ccstrlist, OnOutOfMemoryError, "",                                \
           "Run user-defined commands on first java.lang.OutOfMemoryError")  \
                                                                             \
-  manageable(bool, HeapDumpBeforeFullGC, false,                             \
+  product(bool, HeapDumpBeforeFullGC, false, MANAGEABLE,                    \
           "Dump heap to file before any major stop-the-world GC")           \
                                                                             \
-  manageable(bool, HeapDumpAfterFullGC, false,                              \
+  product(bool, HeapDumpAfterFullGC, false, MANAGEABLE,                     \
           "Dump heap to file after any major stop-the-world GC")            \
                                                                             \
-  manageable(bool, HeapDumpOnOutOfMemoryError, false,                       \
+  product(bool, HeapDumpOnOutOfMemoryError, false, MANAGEABLE,              \
           "Dump heap to file when java.lang.OutOfMemoryError is thrown")    \
                                                                             \
-  manageable(ccstr, HeapDumpPath, NULL,                                     \
+  product(ccstr, HeapDumpPath, NULL, MANAGEABLE,                            \
           "When HeapDumpOnOutOfMemoryError is on, the path (filename or "   \
           "directory) of the dump file (defaults to java_pid<pid>.hprof "   \
           "in the working directory)")                                      \
@@ -535,23 +552,23 @@ const size_t minimumSymbolTableSize = 1024;
   product(ccstr, NativeMemoryTracking, "off",                               \
           "Native memory tracking options")                                 \
                                                                             \
-  diagnostic(bool, PrintNMTStatistics, false,                               \
+  product(bool, PrintNMTStatistics, false, DIAGNOSTIC,                      \
           "Print native memory tracking summary data if it is on")          \
                                                                             \
-  diagnostic(bool, LogCompilation, false,                                   \
+  product(bool, LogCompilation, false, DIAGNOSTIC,                          \
           "Log compilation activity in detail to LogFile")                  \
                                                                             \
   product(bool, PrintCompilation, false,                                    \
           "Print compilations")                                             \
                                                                             \
-  diagnostic(intx, RepeatCompilation, 0,                                    \
+  product(intx, RepeatCompilation, 0, DIAGNOSTIC,                           \
           "Repeat compilation without installing code (number of times)")   \
-          range(0, max_jint)                                                 \
+          range(0, max_jint)                                                \
                                                                             \
   product(bool, PrintExtendedThreadInfo, false,                             \
           "Print more information in thread dump")                          \
                                                                             \
-  diagnostic(intx, ScavengeRootsInCode, 2,                                  \
+  product(intx, ScavengeRootsInCode, 2, DIAGNOSTIC,                         \
           "0: do not allow scavengable oops in the code cache; "            \
           "1: allow scavenging from the code cache; "                       \
           "2: emit as many constants as the compiler can see")              \
@@ -560,31 +577,31 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, AlwaysRestoreFPU, false,                                    \
           "Restore the FPU control word after every JNI call (expensive)")  \
                                                                             \
-  diagnostic(bool, PrintCompilation2, false,                                \
+  product(bool, PrintCompilation2, false, DIAGNOSTIC,                       \
           "Print additional statistics per compilation")                    \
                                                                             \
-  diagnostic(bool, PrintAdapterHandlers, false,                             \
+  product(bool, PrintAdapterHandlers, false, DIAGNOSTIC,                    \
           "Print code generated for i2c/c2i adapters")                      \
                                                                             \
-  diagnostic(bool, VerifyAdapterCalls, trueInDebug,                         \
+  product(bool, VerifyAdapterCalls, trueInDebug, DIAGNOSTIC,                \
           "Verify that i2c/c2i adapters are called properly")               \
                                                                             \
   develop(bool, VerifyAdapterSharing, false,                                \
           "Verify that the code for shared adapters is the equivalent")     \
                                                                             \
-  diagnostic(bool, PrintAssembly, false,                                    \
+  product(bool, PrintAssembly, false, DIAGNOSTIC,                           \
           "Print assembly code (using external disassembler.so)")           \
                                                                             \
-  diagnostic(ccstr, PrintAssemblyOptions, NULL,                             \
+  product(ccstr, PrintAssemblyOptions, NULL, DIAGNOSTIC,                    \
           "Print options string passed to disassembler.so")                 \
                                                                             \
   notproduct(bool, PrintNMethodStatistics, false,                           \
           "Print a summary statistic for the generated nmethods")           \
                                                                             \
-  diagnostic(bool, PrintNMethods, false,                                    \
+  product(bool, PrintNMethods, false, DIAGNOSTIC,                           \
           "Print assembly code for nmethods when generated")                \
                                                                             \
-  diagnostic(bool, PrintNativeNMethods, false,                              \
+  product(bool, PrintNativeNMethods, false, DIAGNOSTIC,                     \
           "Print assembly code for native nmethods when generated")         \
                                                                             \
   develop(bool, PrintDebugInfo, false,                                      \
@@ -616,10 +633,10 @@ const size_t minimumSymbolTableSize = 1024;
           "Print the code cache memory usage each time a method is "        \
           "compiled")                                                       \
                                                                             \
-  diagnostic(bool, PrintCodeHeapAnalytics, false,                           \
+  product(bool, PrintCodeHeapAnalytics, false, DIAGNOSTIC,                  \
           "Print code heap usage statistics on exit and on full condition") \
                                                                             \
-  diagnostic(bool, PrintStubCode, false,                                    \
+  product(bool, PrintStubCode, false, DIAGNOSTIC,                           \
           "Print generated stub code")                                      \
                                                                             \
   product(bool, StackTraceInThrowable, true,                                \
@@ -628,7 +645,7 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, OmitStackTraceInFastThrow, true,                            \
           "Omit backtraces for some 'hot' exceptions in optimized code")    \
                                                                             \
-  manageable(bool, ShowCodeDetailsInExceptionMessages, true,                \
+  product(bool, ShowCodeDetailsInExceptionMessages, true, MANAGEABLE,       \
           "Show exception messages from RuntimeExceptions that contain "    \
           "snippets of the failing code. Disable this to improve privacy.") \
                                                                             \
@@ -675,7 +692,7 @@ const size_t minimumSymbolTableSize = 1024;
   notproduct(bool, PrintSystemDictionaryAtExit, false,                      \
           "Print the system dictionary at exit")                            \
                                                                             \
-  diagnostic(bool, DynamicallyResizeSystemDictionaries, true,               \
+  product(bool, DynamicallyResizeSystemDictionaries, true, DIAGNOSTIC,      \
           "Dynamically resize system dictionaries as needed")               \
                                                                             \
   product(bool, AlwaysLockClassLoader, false,                               \
@@ -690,24 +707,24 @@ const size_t minimumSymbolTableSize = 1024;
   product_pd(bool, DontYieldALot,                                           \
           "Throw away obvious excess yield calls")                          \
                                                                             \
-  experimental(bool, DisablePrimordialThreadGuardPages, false,              \
+  product(bool, DisablePrimordialThreadGuardPages, false, EXPERIMENTAL,     \
                "Disable the use of stack guard pages if the JVM is loaded " \
                "on the primordial process thread")                          \
                                                                             \
   /* notice: the max range value here is max_jint, not max_intx  */         \
   /* because of overflow issue                                   */         \
-  diagnostic(intx, AsyncDeflationInterval, 250,                             \
+  product(intx, AsyncDeflationInterval, 250, DIAGNOSTIC,                    \
           "Async deflate idle monitors every so many milliseconds when "    \
           "MonitorUsedDeflationThreshold is exceeded (0 is off).")          \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(intx, MonitorUsedDeflationThreshold, 90,                     \
+  product(intx, MonitorUsedDeflationThreshold, 90, EXPERIMENTAL,            \
           "Percentage of used monitors before triggering deflation (0 is "  \
           "off). The check is performed on GuaranteedSafepointInterval "    \
           "or AsyncDeflationInterval.")                                     \
           range(0, 100)                                                     \
                                                                             \
-  experimental(intx, hashCode, 5,                                           \
+  product(intx, hashCode, 5, EXPERIMENTAL,                                  \
                "(Unstable) select hashCode generation algorithm")           \
                                                                             \
   product(bool, FilterSpuriousWakeups, true,                                \
@@ -792,7 +809,7 @@ const size_t minimumSymbolTableSize = 1024;
           range(0, (intx)(max_jint-(max_jint%PeriodicTask::interval_gran))) \
           constraint(BiasedLockingStartupDelayFunc,AfterErgo)               \
                                                                             \
-  diagnostic(bool, PrintBiasedLockingStatistics, false,                     \
+  product(bool, PrintBiasedLockingStatistics, false, DIAGNOSTIC,            \
           "(Deprecated) Print statistics of biased locking in JVM")         \
                                                                             \
   product(intx, BiasedLockingBulkRebiasThreshold, 20,                       \
@@ -814,7 +831,7 @@ const size_t minimumSymbolTableSize = 1024;
           range(500, max_intx)                                              \
           constraint(BiasedLockingDecayTimeFunc,AfterErgo)                  \
                                                                             \
-  diagnostic(intx, DiagnoseSyncOnPrimitiveWrappers, 0,                      \
+  product(intx, DiagnoseSyncOnPrimitiveWrappers, 0, DIAGNOSTIC,             \
              "Detect and take action upon identifying synchronization on "  \
              "primitive wrappers. Modes: "                                  \
              "0: off; "                                                     \
@@ -918,20 +935,20 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, PrintHeapAtSIGBREAK, true,                                  \
           "Print heap layout in response to SIGBREAK")                      \
                                                                             \
-  manageable(bool, PrintClassHistogram, false,                              \
+  product(bool, PrintClassHistogram, false, MANAGEABLE,                     \
           "Print a histogram of class instances")                           \
                                                                             \
-  experimental(double, ObjectCountCutOffPercent, 0.5,                       \
+  product(double, ObjectCountCutOffPercent, 0.5, EXPERIMENTAL,              \
           "The percentage of the used heap that the instances of a class "  \
           "must occupy for the class to generate a trace event")            \
           range(0.0, 100.0)                                                 \
                                                                             \
   /* JVMTI heap profiling */                                                \
                                                                             \
-  diagnostic(bool, TraceJVMTIObjectTagging, false,                          \
+  product(bool, TraceJVMTIObjectTagging, false, DIAGNOSTIC,                 \
           "Trace JVMTI object tagging calls")                               \
                                                                             \
-  diagnostic(bool, VerifyBeforeIteration, false,                            \
+  product(bool, VerifyBeforeIteration, false, DIAGNOSTIC,                   \
           "Verify memory system before JVMTI iteration")                    \
                                                                             \
   /* compiler interface */                                                  \
@@ -939,7 +956,7 @@ const size_t minimumSymbolTableSize = 1024;
   develop(bool, CIPrintCompilerName, false,                                 \
           "when CIPrint is active, print the name of the active compiler")  \
                                                                             \
-  diagnostic(bool, CIPrintCompileQueue, false,                              \
+  product(bool, CIPrintCompileQueue, false, DIAGNOSTIC,                     \
           "display the contents of the compile queue whenever a "           \
           "compilation is enqueued")                                        \
                                                                             \
@@ -989,11 +1006,11 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, UseDynamicNumberOfCompilerThreads, true,                    \
           "Dynamically choose the number of parallel compiler threads")     \
                                                                             \
-  diagnostic(bool, ReduceNumberOfCompilerThreads, true,                     \
+  product(bool, ReduceNumberOfCompilerThreads, true, DIAGNOSTIC,            \
              "Reduce the number of parallel compiler threads when they "    \
              "are not used")                                                \
                                                                             \
-  diagnostic(bool, TraceCompilerThreads, false,                             \
+  product(bool, TraceCompilerThreads, false, DIAGNOSTIC,                    \
              "Trace creation and removal of compiler threads")              \
                                                                             \
   develop(bool, InjectCompilerCreationFailure, false,                       \
@@ -1012,7 +1029,7 @@ const size_t minimumSymbolTableSize = 1024;
   develop(bool, GenerateRangeChecks, true,                                  \
           "Generate range checks for array accesses")                       \
                                                                             \
-  diagnostic_pd(bool, ImplicitNullChecks,                                   \
+  product_pd(bool, ImplicitNullChecks, DIAGNOSTIC,                          \
           "Generate code for implicit null checks")                         \
                                                                             \
   product_pd(bool, TrapBasedNullChecks,                                     \
@@ -1021,10 +1038,10 @@ const size_t minimumSymbolTableSize = 1024;
           "null (+offset) will not raise a SIGSEGV, i.e.,"                  \
           "ImplicitNullChecks don't work (PPC64).")                         \
                                                                             \
-  diagnostic(bool, EnableThreadSMRExtraValidityChecks, true,                \
+  product(bool, EnableThreadSMRExtraValidityChecks, true, DIAGNOSTIC,       \
              "Enable Thread SMR extra validity checks")                     \
                                                                             \
-  diagnostic(bool, EnableThreadSMRStatistics, trueInDebug,                  \
+  product(bool, EnableThreadSMRStatistics, trueInDebug, DIAGNOSTIC,         \
              "Enable Thread SMR Statistics")                                \
                                                                             \
   product(bool, UseNotificationThread, true,                                \
@@ -1042,7 +1059,7 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, UseTypeProfile, true,                                       \
           "Check interpreter profile for historically monomorphic calls")   \
                                                                             \
-  diagnostic(bool, PrintInlining, false,                                    \
+  product(bool, PrintInlining, false, DIAGNOSTIC,                           \
           "Print inlining optimizations")                                   \
                                                                             \
   product(bool, UsePopCountInstruction, false,                              \
@@ -1051,10 +1068,10 @@ const size_t minimumSymbolTableSize = 1024;
   develop(bool, EagerInitialization, false,                                 \
           "Eagerly initialize classes if possible")                         \
                                                                             \
-  diagnostic(bool, LogTouchedMethods, false,                                \
+  product(bool, LogTouchedMethods, false, DIAGNOSTIC,                       \
           "Log methods which have been ever touched in runtime")            \
                                                                             \
-  diagnostic(bool, PrintTouchedMethodsAtExit, false,                        \
+  product(bool, PrintTouchedMethodsAtExit, false, DIAGNOSTIC,               \
           "Print all methods that have been ever touched in runtime")       \
                                                                             \
   develop(bool, TraceMethodReplacement, false,                              \
@@ -1063,15 +1080,15 @@ const size_t minimumSymbolTableSize = 1024;
   develop(bool, PrintMethodFlushing, false,                                 \
           "Print the nmethods being flushed")                               \
                                                                             \
-  diagnostic(bool, PrintMethodFlushingStatistics, false,                    \
+  product(bool, PrintMethodFlushingStatistics, false, DIAGNOSTIC,           \
           "print statistics about method flushing")                         \
                                                                             \
-  diagnostic(intx, HotMethodDetectionLimit, 100000,                         \
+  product(intx, HotMethodDetectionLimit, 100000, DIAGNOSTIC,                \
           "Number of compiled code invocations after which "                \
           "the method is considered as hot by the flusher")                 \
           range(1, max_jint)                                                \
                                                                             \
-  diagnostic(intx, MinPassesBeforeFlush, 10,                                \
+  product(intx, MinPassesBeforeFlush, 10, DIAGNOSTIC,                       \
           "Minimum number of sweeper passes before an nmethod "             \
           "can be flushed")                                                 \
           range(0, max_intx)                                                \
@@ -1079,13 +1096,13 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, UseCodeAging, true,                                         \
           "Insert counter to detect warm methods")                          \
                                                                             \
-  diagnostic(bool, StressCodeAging, false,                                  \
+  product(bool, StressCodeAging, false, DIAGNOSTIC,                         \
           "Start with counters compiled in")                                \
                                                                             \
   develop(bool, StressCodeBuffers, false,                                   \
           "Exercise code buffer expansion and other rare state changes")    \
                                                                             \
-  diagnostic(bool, DebugNonSafepoints, trueInDebug,                         \
+  product(bool, DebugNonSafepoints, trueInDebug, DIAGNOSTIC,                \
           "Generate extra debugging information for non-safepoints in "     \
           "nmethods")                                                       \
                                                                             \
@@ -1111,16 +1128,16 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, PrintFlagsRanges, false,                                    \
           "Print VM flags and their ranges")                                \
                                                                             \
-  diagnostic(bool, SerializeVMOutput, true,                                 \
+  product(bool, SerializeVMOutput, true, DIAGNOSTIC,                        \
           "Use a mutex to serialize output to tty and LogFile")             \
                                                                             \
-  diagnostic(bool, DisplayVMOutput, true,                                   \
+  product(bool, DisplayVMOutput, true, DIAGNOSTIC,                          \
           "Display all VM output on the tty, independently of LogVMOutput") \
                                                                             \
-  diagnostic(bool, LogVMOutput, false,                                      \
+  product(bool, LogVMOutput, false, DIAGNOSTIC,                             \
           "Save VM output to LogFile")                                      \
                                                                             \
-  diagnostic(ccstr, LogFile, NULL,                                          \
+  product(ccstr, LogFile, NULL, DIAGNOSTIC,                                 \
           "If LogVMOutput or LogCompilation is on, save VM output to "      \
           "this file [default: ./hotspot_pid%p.log] (%p replaced with pid)")\
                                                                             \
@@ -1150,7 +1167,7 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, PrintStringTableStatistics, false,                          \
           "print statistics about the StringTable and SymbolTable")         \
                                                                             \
-  diagnostic(bool, VerifyStringTableAtExit, false,                          \
+  product(bool, VerifyStringTableAtExit, false, DIAGNOSTIC,                 \
           "verify StringTable contents at exit")                            \
                                                                             \
   notproduct(bool, PrintSymbolTableSizeHistogram, false,                    \
@@ -1160,11 +1177,11 @@ const size_t minimumSymbolTableSize = 1024;
           "standard exit from VM if bytecode verify error "                 \
           "(only in debug mode)")                                           \
                                                                             \
-  diagnostic(ccstr, AbortVMOnException, NULL,                               \
+  product(ccstr, AbortVMOnException, NULL, DIAGNOSTIC,                      \
           "Call fatal if this exception is thrown.  Example: "              \
           "java -XX:AbortVMOnException=java.lang.NullPointerException Foo") \
                                                                             \
-  diagnostic(ccstr, AbortVMOnExceptionMessage, NULL,                        \
+  product(ccstr, AbortVMOnExceptionMessage, NULL, DIAGNOSTIC,               \
           "Call fatal if the exception pointed by AbortVMOnException "      \
           "has this message")                                               \
                                                                             \
@@ -1248,7 +1265,7 @@ const size_t minimumSymbolTableSize = 1024;
   product_pd(bool, RewriteFrequentPairs,                                    \
           "Rewrite frequently used bytecode pairs into a single bytecode")  \
                                                                             \
-  diagnostic(bool, PrintInterpreter, false,                                 \
+  product(bool, PrintInterpreter, false, DIAGNOSTIC,                        \
           "Print the generated interpreter code")                           \
                                                                             \
   product(bool, UseInterpreter, true,                                       \
@@ -1280,7 +1297,7 @@ const size_t minimumSymbolTableSize = 1024;
   develop(bool, PrintBytecodePairHistogram, false,                          \
           "Print histogram of the executed bytecode pairs")                 \
                                                                             \
-  diagnostic(bool, PrintSignatureHandlers, false,                           \
+  product(bool, PrintSignatureHandlers, false, DIAGNOSTIC,                  \
           "Print code generated for native method signature handlers")      \
                                                                             \
   develop(bool, VerifyOops, false,                                          \
@@ -1328,7 +1345,7 @@ const size_t minimumSymbolTableSize = 1024;
           "CompileThreshold) before using the method's profile")            \
           range(0, 100)                                                     \
                                                                             \
-  diagnostic(bool, PrintMethodData, false,                                  \
+  product(bool, PrintMethodData, false, DIAGNOSTIC,                         \
           "Print the results of +ProfileInterpreter at end of run")         \
                                                                             \
   develop(bool, VerifyDataPointer, trueInDebug,                             \
@@ -1432,15 +1449,14 @@ const size_t minimumSymbolTableSize = 1024;
                                                                             \
   /* notice: the max range value here is max_jint, not max_intx  */         \
   /* because of overflow issue                                   */         \
-  diagnostic(intx, GuaranteedSafepointInterval, 1000,                       \
+  product(intx, GuaranteedSafepointInterval, 1000, DIAGNOSTIC,              \
           "Guarantee a safepoint (at least) every so many milliseconds "    \
           "(0 means none)")                                                 \
           range(0, max_jint)                                                \
                                                                             \
   product(intx, SafepointTimeoutDelay, 10000,                               \
           "Delay in milliseconds for option SafepointTimeout")              \
-  LP64_ONLY(range(0, max_intx/MICROUNITS))                                  \
-  NOT_LP64(range(0, max_intx))                                              \
+          range(0, max_intx LP64_ONLY(/MICROUNITS))                         \
                                                                             \
   product(intx, NmethodSweepActivity, 10,                                   \
           "Removes cold nmethods from code cache if > 0. Higher values "    \
@@ -1493,7 +1509,7 @@ const size_t minimumSymbolTableSize = 1024;
   notproduct(intx, ZombieALotInterval,     5,                               \
           "Number of exits until ZombieALot kicks in")                      \
                                                                             \
-  diagnostic(uintx, MallocMaxTestWords,     0,                              \
+  product(uintx, MallocMaxTestWords,     0, DIAGNOSTIC,                     \
           "If non-zero, maximum number of words that malloc/realloc can "   \
           "allocate (for testing only)")                                    \
           range(0, max_uintx)                                               \
@@ -1517,7 +1533,7 @@ const size_t minimumSymbolTableSize = 1024;
           "Limit on traps (of one kind) in a method (includes inlines)")    \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(intx, PerMethodSpecTrapLimit,  5000,                         \
+  product(intx, PerMethodSpecTrapLimit,  5000, EXPERIMENTAL,                \
           "Limit on speculative traps (of one kind) in a method "           \
           "(includes inlines)")                                             \
           range(0, max_jint)                                                \
@@ -1526,14 +1542,14 @@ const size_t minimumSymbolTableSize = 1024;
           "Limit on traps (of one kind) at a particular BCI")               \
           range(0, max_jint)                                                \
                                                                             \
-  experimental(intx, SpecTrapLimitExtraEntries,  3,                         \
+  product(intx, SpecTrapLimitExtraEntries,  3, EXPERIMENTAL,                \
           "Extra method data trap entries for speculation")                 \
                                                                             \
   develop(intx, InlineFrequencyRatio,    20,                                \
           "Ratio of call site execution to caller method invocation")       \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic_pd(intx, InlineFrequencyCount,                                 \
+  product_pd(intx, InlineFrequencyCount, DIAGNOSTIC,                        \
           "Count of call site execution necessary to trigger frequent "     \
           "inlining")                                                       \
           range(0, max_jint)                                                \
@@ -1564,14 +1580,14 @@ const size_t minimumSymbolTableSize = 1024;
           "class pointers are used")                                        \
           range(1*M, 3*G)                                                   \
                                                                             \
-  manageable(uintx, MinHeapFreeRatio, 40,                                   \
+  product(uintx, MinHeapFreeRatio, 40, MANAGEABLE,                          \
           "The minimum percentage of heap free after GC to avoid expansion."\
           " For most GCs this applies to the old generation. In G1 and"     \
           " ParallelGC it applies to the whole heap.")                      \
           range(0, 100)                                                     \
           constraint(MinHeapFreeRatioConstraintFunc,AfterErgo)              \
                                                                             \
-  manageable(uintx, MaxHeapFreeRatio, 70,                                   \
+  product(uintx, MaxHeapFreeRatio, 70, MANAGEABLE,                          \
           "The maximum percentage of heap free after GC to avoid shrinking."\
           " For most GCs this applies to the old generation. In G1 and"     \
           " ParallelGC it applies to the whole heap.")                      \
@@ -1671,7 +1687,7 @@ const size_t minimumSymbolTableSize = 1024;
                                                                             \
   product_pd(uintx, InitialCodeCacheSize,                                   \
           "Initial code cache size (in bytes)")                             \
-          range(os::vm_page_size(), max_uintx)                              \
+          constraint(VMPageSizeConstraintFunc, AtParse)                     \
                                                                             \
   develop_pd(uintx, CodeCacheMinimumUseSpace,                               \
           "Minimum code cache size (in bytes) required to start VM.")       \
@@ -1682,7 +1698,7 @@ const size_t minimumSymbolTableSize = 1024;
                                                                             \
   product_pd(uintx, ReservedCodeCacheSize,                                  \
           "Reserved code cache size (in bytes) - maximum code cache size")  \
-          range(os::vm_page_size(), max_uintx)                              \
+          constraint(VMPageSizeConstraintFunc, AtParse)                     \
                                                                             \
   product_pd(uintx, NonProfiledCodeHeapSize,                                \
           "Size of code heap with non-profiled methods (in bytes)")         \
@@ -1694,13 +1710,13 @@ const size_t minimumSymbolTableSize = 1024;
                                                                             \
   product_pd(uintx, NonNMethodCodeHeapSize,                                 \
           "Size of code heap with non-nmethods (in bytes)")                 \
-          range(os::vm_page_size(), max_uintx)                              \
+          constraint(VMPageSizeConstraintFunc, AtParse)                     \
                                                                             \
   product_pd(uintx, CodeCacheExpansionSize,                                 \
           "Code cache expansion size (in bytes)")                           \
           range(32*K, max_uintx)                                            \
                                                                             \
-  diagnostic_pd(uintx, CodeCacheMinBlockLength,                             \
+  product_pd(uintx, CodeCacheMinBlockLength, DIAGNOSTIC,                    \
           "Minimum number of segments in a code cache block")               \
           range(1, 100)                                                     \
                                                                             \
@@ -1722,19 +1738,19 @@ const size_t minimumSymbolTableSize = 1024;
           range(0, 100)                                                     \
                                                                             \
   /* AOT parameters */                                                      \
-  experimental(bool, UseAOT, false,                                         \
+  product(bool, UseAOT, false, EXPERIMENTAL,                                \
           "Use AOT compiled files")                                         \
                                                                             \
-  experimental(ccstrlist, AOTLibrary, NULL,                                 \
+  product(ccstrlist, AOTLibrary, NULL, EXPERIMENTAL,                        \
           "AOT library")                                                    \
                                                                             \
-  experimental(bool, PrintAOT, false,                                       \
+  product(bool, PrintAOT, false, EXPERIMENTAL,                              \
           "Print used AOT klasses and methods")                             \
                                                                             \
   notproduct(bool, PrintAOTStatistics, false,                               \
           "Print AOT statistics")                                           \
                                                                             \
-  diagnostic(bool, UseAOTStrictLoading, false,                              \
+  product(bool, UseAOTStrictLoading, false, DIAGNOSTIC,                     \
           "Exit the VM if any of the AOT libraries has invalid config")     \
                                                                             \
   product(bool, CalculateClassFingerprint, false,                           \
@@ -1778,7 +1794,7 @@ const size_t minimumSymbolTableSize = 1024;
   product(ccstr, CompileCommandFile, NULL,                                  \
           "Read compiler commands from this file [.hotspot_compiler]")      \
                                                                             \
-  diagnostic(ccstr, CompilerDirectivesFile, NULL,                           \
+  product(ccstr, CompilerDirectivesFile, NULL, DIAGNOSTIC,                  \
           "Read compiler directives from this file")                        \
                                                                             \
   product(ccstrlist, CompileCommand, "",                                    \
@@ -1819,7 +1835,7 @@ const size_t minimumSymbolTableSize = 1024;
   notproduct(bool, CIObjectFactoryVerify, false,                            \
           "enable potentially expensive verification in ciObjectFactory")   \
                                                                             \
-  diagnostic(bool, AbortVMOnCompilationFailure, false,                      \
+  product(bool, AbortVMOnCompilationFailure, false, DIAGNOSTIC,             \
           "Abort VM when method had failed to compile.")                    \
                                                                             \
   /* Priorities */                                                          \
@@ -1900,10 +1916,10 @@ const size_t minimumSymbolTableSize = 1024;
           "Map Java priorities to OS priorities")                           \
           range(-1, 127)                                                    \
                                                                             \
-  experimental(bool, UseCriticalJavaThreadPriority, false,                  \
+  product(bool, UseCriticalJavaThreadPriority, false, EXPERIMENTAL,         \
           "Java thread priority 10 maps to critical scheduling priority")   \
                                                                             \
-  experimental(bool, UseCriticalCompilerThreadPriority, false,              \
+  product(bool, UseCriticalCompilerThreadPriority, false, EXPERIMENTAL,     \
           "Compiler thread(s) run at critical scheduling priority")         \
                                                                             \
   develop(intx, NewCodeParameter,      0,                                   \
@@ -1914,10 +1930,6 @@ const size_t minimumSymbolTableSize = 1024;
   develop(intx, MinOopMapAllocation,     8,                                 \
           "Minimum number of OopMap entries in an OopMapSet")               \
                                                                             \
-  /* Background Compilation */                                              \
-  develop(intx, LongCompileThreshold,     50,                               \
-          "Used with +TraceLongCompiles")                                   \
-                                                                            \
   /* recompilation */                                                       \
   product_pd(intx, CompileThreshold,                                        \
           "number of interpreted method invocations before (re-)compiling") \
@@ -2012,21 +2024,21 @@ const size_t minimumSymbolTableSize = 1024;
           "if coming from AOT")                                             \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic(intx, Tier0AOTInvocationThreshold, 200,                        \
+  product(intx, Tier0AOTInvocationThreshold, 200, DIAGNOSTIC,               \
           "Switch to interpreter to profile if the number of method "       \
           "invocations crosses this threshold if coming from AOT "          \
           "(applicable only with "                                          \
           "CompilationMode=high-only|high-only-quick-internal)")            \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic(intx, Tier0AOTMinInvocationThreshold, 100,                     \
+  product(intx, Tier0AOTMinInvocationThreshold, 100, DIAGNOSTIC,            \
           "Minimum number of invocations to switch to interpreter "         \
           "to profile if coming from AOT "                                  \
           "(applicable only with "                                          \
           "CompilationMode=high-only|high-only-quick-internal)")            \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic(intx, Tier0AOTCompileThreshold, 2000,                          \
+  product(intx, Tier0AOTCompileThreshold, 2000, DIAGNOSTIC,                 \
           "Threshold at which to switch to interpreter to profile "         \
           "if coming from AOT "                                             \
           "(invocation minimum must be satisfied, "                         \
@@ -2034,7 +2046,7 @@ const size_t minimumSymbolTableSize = 1024;
           "CompilationMode=high-only|high-only-quick-internal)")            \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic(intx, Tier0AOTBackEdgeThreshold,  60000,                       \
+  product(intx, Tier0AOTBackEdgeThreshold,  60000, DIAGNOSTIC,              \
           "Back edge threshold at which to switch to interpreter "          \
           "to profile if coming from AOT "                                  \
           "(applicable only with "                                          \
@@ -2059,31 +2071,31 @@ const size_t minimumSymbolTableSize = 1024;
           "Back edge threshold at which tier 4 OSR compilation is invoked") \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic(intx, Tier40InvocationThreshold, 5000,                         \
+  product(intx, Tier40InvocationThreshold, 5000, DIAGNOSTIC,                \
           "Compile if number of method invocations crosses this "           \
           "threshold (applicable only with "                                \
           "CompilationMode=high-only|high-only-quick-internal)")            \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic(intx, Tier40MinInvocationThreshold, 600,                       \
+  product(intx, Tier40MinInvocationThreshold, 600, DIAGNOSTIC,              \
           "Minimum number of invocations to compile at tier 4 "             \
           "(applicable only with "                                          \
           "CompilationMode=high-only|high-only-quick-internal)")            \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic(intx, Tier40CompileThreshold, 10000,                           \
+  product(intx, Tier40CompileThreshold, 10000, DIAGNOSTIC,                  \
           "Threshold at which tier 4 compilation is invoked (invocation "   \
           "minimum must be satisfied, applicable only with "                \
           "CompilationMode=high-only|high-only-quick-internal)")            \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic(intx, Tier40BackEdgeThreshold, 15000,                          \
+  product(intx, Tier40BackEdgeThreshold, 15000, DIAGNOSTIC,                 \
           "Back edge threshold at which tier 4 OSR compilation is invoked " \
           "(applicable only with "                                          \
           "CompilationMode=high-only|high-only-quick-internal)")            \
           range(0, max_jint)                                                \
                                                                             \
-  diagnostic(intx, Tier0Delay, 5,                                           \
+  product(intx, Tier0Delay, 5, DIAGNOSTIC,                                  \
           "If C2 queue size grows over this amount per compiler thread "    \
           "do not start profiling in the interpreter "                      \
           "(applicable only with "                                          \
@@ -2178,13 +2190,13 @@ const size_t minimumSymbolTableSize = 1024;
                                                                             \
   /* Flags used for temporary code during development  */                   \
                                                                             \
-  diagnostic(bool, UseNewCode, false,                                       \
+  product(bool, UseNewCode, false, DIAGNOSTIC,                              \
           "Testing Only: Use the new version while testing")                \
                                                                             \
-  diagnostic(bool, UseNewCode2, false,                                      \
+  product(bool, UseNewCode2, false, DIAGNOSTIC,                             \
           "Testing Only: Use the new version while testing")                \
                                                                             \
-  diagnostic(bool, UseNewCode3, false,                                      \
+  product(bool, UseNewCode3, false, DIAGNOSTIC,                             \
           "Testing Only: Use the new version while testing")                \
                                                                             \
   /* flags for performance data collection */                               \
@@ -2243,7 +2255,7 @@ const size_t minimumSymbolTableSize = 1024;
   product(bool, EnableDynamicAgentLoading, true,                            \
           "Allow tools to load agents with the attach mechanism")           \
                                                                             \
-  manageable(bool, PrintConcurrentLocks, false,                             \
+  product(bool, PrintConcurrentLocks, false, MANAGEABLE,                    \
           "Print java.util.concurrent locks in thread dump")                \
                                                                             \
   /* Shared spaces */                                                       \
@@ -2284,25 +2296,25 @@ const size_t minimumSymbolTableSize = 1024;
           "Average number of symbols per bucket in shared table")           \
           range(2, 246)                                                     \
                                                                             \
-  diagnostic(bool, AllowArchivingWithJavaAgent, false,                      \
+  product(bool, AllowArchivingWithJavaAgent, false, DIAGNOSTIC,             \
           "Allow Java agent to be run with CDS dumping")                    \
                                                                             \
-  diagnostic(bool, PrintMethodHandleStubs, false,                           \
+  product(bool, PrintMethodHandleStubs, false, DIAGNOSTIC,                  \
           "Print generated stub code for method handles")                   \
                                                                             \
-  diagnostic(bool, VerifyMethodHandles, trueInDebug,                        \
+  product(bool, VerifyMethodHandles, trueInDebug, DIAGNOSTIC,               \
           "perform extra checks when constructing method handles")          \
                                                                             \
-  diagnostic(bool, ShowHiddenFrames, false,                                 \
+  product(bool, ShowHiddenFrames, false, DIAGNOSTIC,                        \
           "show method handle implementation frames (usually hidden)")      \
                                                                             \
-  experimental(bool, TrustFinalNonStaticFields, false,                      \
+  product(bool, TrustFinalNonStaticFields, false, EXPERIMENTAL,             \
           "trust final non-static declarations for constant folding")       \
                                                                             \
-  diagnostic(bool, FoldStableValues, true,                                  \
+  product(bool, FoldStableValues, true, DIAGNOSTIC,                         \
           "Optimize loads from stable fields (marked w/ @Stable)")          \
                                                                             \
-  diagnostic(int, UseBootstrapCallInfo, 1,                                  \
+  product(int, UseBootstrapCallInfo, 1, DIAGNOSTIC,                         \
           "0: when resolving InDy or ConDy, force all BSM arguments to be " \
           "resolved before the bootstrap method is called; 1: when a BSM "  \
           "that may accept a BootstrapCallInfo is detected, use that API "  \
@@ -2310,15 +2322,15 @@ const size_t minimumSymbolTableSize = 1024;
           "resolution; 2+: stress test the BCI API by calling more BSMs "   \
           "via that API, instead of with the eagerly-resolved array.")      \
                                                                             \
-  diagnostic(bool, PauseAtStartup,      false,                              \
+  product(bool, PauseAtStartup,      false, DIAGNOSTIC,                     \
           "Causes the VM to pause at startup time and wait for the pause "  \
           "file to be removed (default: ./vm.paused.<pid>)")                \
                                                                             \
-  diagnostic(ccstr, PauseAtStartupFile, NULL,                               \
+  product(ccstr, PauseAtStartupFile, NULL, DIAGNOSTIC,                      \
           "The file to create and for whose removal to await when pausing " \
           "at startup. (default: ./vm.paused.<pid>)")                       \
                                                                             \
-  diagnostic(bool, PauseAtExit, false,                                      \
+  product(bool, PauseAtExit, false, DIAGNOSTIC,                             \
           "Pause and wait for keypress on exit if a debugger is attached")  \
                                                                             \
   product(bool, ExtendedDTraceProbes,    false,                             \
@@ -2341,7 +2353,7 @@ const size_t minimumSymbolTableSize = 1024;
           "(will be rounded to nearest higher power of 2)")                 \
           range(minimumStringTableSize, 16777216ul /* 2^24 */)              \
                                                                             \
-  experimental(uintx, SymbolTableSize, defaultSymbolTableSize,              \
+  product(uintx, SymbolTableSize, defaultSymbolTableSize, EXPERIMENTAL,     \
           "Number of buckets in the JVM internal Symbol table")             \
           range(minimumSymbolTableSize, 16777216ul /* 2^24 */)              \
                                                                             \
@@ -2353,16 +2365,16 @@ const size_t minimumSymbolTableSize = 1024;
           "to be considered for deduplication")                             \
           range(1, markWord::max_age)                                       \
                                                                             \
-  diagnostic(bool, StringDeduplicationResizeALot, false,                    \
+  product(bool, StringDeduplicationResizeALot, false, DIAGNOSTIC,           \
           "Force table resize every time the table is scanned")             \
                                                                             \
-  diagnostic(bool, StringDeduplicationRehashALot, false,                    \
+  product(bool, StringDeduplicationRehashALot, false, DIAGNOSTIC,           \
           "Force table rehash every time the table is scanned")             \
                                                                             \
-  diagnostic(bool, WhiteBoxAPI, false,                                      \
+  product(bool, WhiteBoxAPI, false, DIAGNOSTIC,                             \
           "Enable internal testing APIs")                                   \
                                                                             \
-  experimental(intx, SurvivorAlignmentInBytes, 0,                           \
+  product(intx, SurvivorAlignmentInBytes, 0, EXPERIMENTAL,                  \
            "Default survivor space alignment in bytes")                     \
            range(8, 256)                                                    \
            constraint(SurvivorAlignmentInBytesConstraintFunc,AfterErgo)     \
@@ -2383,7 +2395,7 @@ const size_t minimumSymbolTableSize = 1024;
   product(ccstr, ExtraSharedClassListFile, NULL,                            \
           "Extra classlist for building the CDS archive file")              \
                                                                             \
-  diagnostic(intx, ArchiveRelocationMode, 0,                                \
+  product(intx, ArchiveRelocationMode, 0, DIAGNOSTIC,                       \
            "(0) first map at preferred address, and if "                    \
            "unsuccessful, map at alternative address (default); "           \
            "(1) always map at alternative address; "                        \
@@ -2391,21 +2403,21 @@ const size_t minimumSymbolTableSize = 1024;
            "do not map the archive")                                        \
            range(0, 2)                                                      \
                                                                             \
-  experimental(size_t, ArrayAllocatorMallocLimit, (size_t)-1,               \
+  product(size_t, ArrayAllocatorMallocLimit, (size_t)-1, EXPERIMENTAL,      \
           "Allocation less than this value will be allocated "              \
           "using malloc. Larger allocations will use mmap.")                \
                                                                             \
-  experimental(bool, AlwaysAtomicAccesses, false,                           \
+  product(bool, AlwaysAtomicAccesses, false, EXPERIMENTAL,                  \
           "Accesses to all variables should always be atomic")              \
                                                                             \
-  diagnostic(bool, UseUnalignedAccesses, false,                             \
+  product(bool, UseUnalignedAccesses, false, DIAGNOSTIC,                    \
           "Use unaligned memory accesses in Unsafe")                        \
                                                                             \
   product_pd(bool, PreserveFramePointer,                                    \
              "Use the FP register for holding the frame pointer "           \
              "and not as a general purpose register.")                      \
                                                                             \
-  diagnostic(bool, CheckIntrinsics, true,                                   \
+  product(bool, CheckIntrinsics, true, DIAGNOSTIC,                          \
              "When a class C is loaded, check that "                        \
              "(1) all intrinsics defined by the VM for class C are present "\
              "in the loaded class file and are marked with the "            \
@@ -2418,26 +2430,26 @@ const size_t minimumSymbolTableSize = 1024;
              "in the loaded class C. "                                      \
              "Check (3) is available only in debug builds.")                \
                                                                             \
-  diagnostic_pd(intx, InitArrayShortSize,                                   \
+  product_pd(intx, InitArrayShortSize, DIAGNOSTIC,                          \
           "Threshold small size (in bytes) for clearing arrays. "           \
           "Anything this size or smaller may get converted to discrete "    \
           "scalar stores.")                                                 \
           range(0, max_intx)                                                \
           constraint(InitArrayShortSizeConstraintFunc, AfterErgo)           \
                                                                             \
-  diagnostic(bool, CompilerDirectivesIgnoreCompileCommands, false,          \
+  product(bool, CompilerDirectivesIgnoreCompileCommands, false, DIAGNOSTIC, \
              "Disable backwards compatibility for compile commands.")       \
                                                                             \
-  diagnostic(bool, CompilerDirectivesPrint, false,                          \
+  product(bool, CompilerDirectivesPrint, false, DIAGNOSTIC,                 \
              "Print compiler directives on installation.")                  \
-  diagnostic(int,  CompilerDirectivesLimit, 50,                             \
+  product(int,  CompilerDirectivesLimit, 50, DIAGNOSTIC,                    \
              "Limit on number of compiler directives.")                     \
                                                                             \
   product(ccstr, AllocateHeapAt, NULL,                                      \
           "Path to the directoy where a temporary file will be created "    \
           "to use as the backing store for Java Heap.")                     \
                                                                             \
-  experimental(ccstr, AllocateOldGenAt, NULL,                               \
+  product(ccstr, AllocateOldGenAt, NULL, EXPERIMENTAL,                      \
           "Path to the directoy where a temporary file will be "            \
           "created to use as the backing store for old generation."         \
           "File of size Xmx is pre-allocated for performance reason, so"    \
@@ -2447,10 +2459,10 @@ const size_t minimumSymbolTableSize = 1024;
                "Run periodic metaspace verifications (0 - none, "           \
                "1 - always, >1 every nth interval)")                        \
                                                                             \
-  diagnostic(bool, ShowRegistersOnAssert, true,                             \
+  product(bool, ShowRegistersOnAssert, true, DIAGNOSTIC,                    \
           "On internal errors, include registers in error report.")         \
                                                                             \
-  diagnostic(bool, UseSwitchProfiling, true,                                \
+  product(bool, UseSwitchProfiling, true, DIAGNOSTIC,                       \
           "leverage profiling for table/lookup switch")                     \
                                                                             \
   develop(bool, TraceMemoryWriteback, false,                                \
@@ -2465,51 +2477,36 @@ const size_t minimumSymbolTableSize = 1024;
   JFR_ONLY(product(ccstr, StartFlightRecording, NULL,                       \
           "Start flight recording with options"))                           \
                                                                             \
-  experimental(bool, UseFastUnorderedTimeStamps, false,                     \
+  product(bool, UseFastUnorderedTimeStamps, false, EXPERIMENTAL,            \
           "Use platform unstable time where supported for timestamps only") \
                                                                             \
   product(bool, UseEmptySlotsInSupers, true,                                \
                 "Allow allocating fields in empty slots of super-classes")  \
                                                                             \
-  diagnostic(bool, DeoptimizeNMethodBarriersALot, false,                    \
-                "Make nmethod barriers deoptimise a lot.")                  \
+  product(bool, DeoptimizeNMethodBarriersALot, false, DIAGNOSTIC,           \
+                "Make nmethod barriers deoptimise a lot.")
+
+// end of RUNTIME_FLAGS
 
 // Interface macros
-#define DECLARE_PRODUCT_FLAG(type, name, value, doc)      extern "C" type name;
-#define DECLARE_PD_PRODUCT_FLAG(type, name, doc)          extern "C" type name;
-#define DECLARE_DIAGNOSTIC_FLAG(type, name, value, doc)   extern "C" type name;
-#define DECLARE_PD_DIAGNOSTIC_FLAG(type, name, doc)       extern "C" type name;
-#define DECLARE_EXPERIMENTAL_FLAG(type, name, value, doc) extern "C" type name;
-#define DECLARE_MANAGEABLE_FLAG(type, name, value, doc)   extern "C" type name;
-#define DECLARE_PRODUCT_RW_FLAG(type, name, value, doc)   extern "C" type name;
+#define DECLARE_PRODUCT_FLAG(type, name, value, ...)      extern "C" type name;
+#define DECLARE_PD_PRODUCT_FLAG(type, name, ...)          extern "C" type name;
 #ifdef PRODUCT
-#define DECLARE_DEVELOPER_FLAG(type, name, value, doc)    const type name = value;
-#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)        const type name = pd_##name;
-#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)   const type name = value;
+#define DECLARE_DEVELOPER_FLAG(type, name, value, ...)    const type name = value;
+#define DECLARE_PD_DEVELOPER_FLAG(type, name, ...)        const type name = pd_##name;
+#define DECLARE_NOTPRODUCT_FLAG(type, name, value, ...)   const type name = value;
 #else
-#define DECLARE_DEVELOPER_FLAG(type, name, value, doc)    extern "C" type name;
-#define DECLARE_PD_DEVELOPER_FLAG(type, name, doc)        extern "C" type name;
-#define DECLARE_NOTPRODUCT_FLAG(type, name, value, doc)   extern "C" type name;
+#define DECLARE_DEVELOPER_FLAG(type, name, value, ...)    extern "C" type name;
+#define DECLARE_PD_DEVELOPER_FLAG(type, name, ...)        extern "C" type name;
+#define DECLARE_NOTPRODUCT_FLAG(type, name, value, ...)   extern "C" type name;
 #endif // PRODUCT
-// Special LP64 flags, product only needed for now.
-#ifdef _LP64
-#define DECLARE_LP64_PRODUCT_FLAG(type, name, value, doc) extern "C" type name;
-#else
-#define DECLARE_LP64_PRODUCT_FLAG(type, name, value, doc) const type name = value;
-#endif // _LP64
 
-ALL_FLAGS(DECLARE_DEVELOPER_FLAG,     \
-          DECLARE_PD_DEVELOPER_FLAG,  \
-          DECLARE_PRODUCT_FLAG,       \
-          DECLARE_PD_PRODUCT_FLAG,    \
-          DECLARE_DIAGNOSTIC_FLAG,    \
-          DECLARE_PD_DIAGNOSTIC_FLAG, \
-          DECLARE_EXPERIMENTAL_FLAG,  \
-          DECLARE_NOTPRODUCT_FLAG,    \
-          DECLARE_MANAGEABLE_FLAG,    \
-          DECLARE_PRODUCT_RW_FLAG,    \
-          DECLARE_LP64_PRODUCT_FLAG,  \
-          IGNORE_RANGE,               \
+ALL_FLAGS(DECLARE_DEVELOPER_FLAG,
+          DECLARE_PD_DEVELOPER_FLAG,
+          DECLARE_PRODUCT_FLAG,
+          DECLARE_PD_PRODUCT_FLAG,
+          DECLARE_NOTPRODUCT_FLAG,
+          IGNORE_RANGE,
           IGNORE_CONSTRAINT)
 
 #endif // SHARE_RUNTIME_GLOBALS_HPP
diff --git a/src/hotspot/share/runtime/globals_extension.hpp b/src/hotspot/share/runtime/globals_extension.hpp
index 1116a6a023a..fd906760db9 100644
--- a/src/hotspot/share/runtime/globals_extension.hpp
+++ b/src/hotspot/share/runtime/globals_extension.hpp
@@ -34,34 +34,18 @@
 #define FLAG_MEMBER_ENUM(name) Flag_##name##_enum
 #define FLAG_MEMBER_ENUM_(name) FLAG_MEMBER_ENUM(name),
 
-#define FLAG_MEMBER_ENUM_PRODUCT(type, name, value, doc)      FLAG_MEMBER_ENUM_(name)
-#define FLAG_MEMBER_ENUM_PD_PRODUCT(type, name, doc)          FLAG_MEMBER_ENUM_(name)
-#define FLAG_MEMBER_ENUM_DIAGNOSTIC(type, name, value, doc)   FLAG_MEMBER_ENUM_(name)
-#define FLAG_MEMBER_ENUM_PD_DIAGNOSTIC(type, name, doc)       FLAG_MEMBER_ENUM_(name)
-#define FLAG_MEMBER_ENUM_EXPERIMENTAL(type, name, value, doc) FLAG_MEMBER_ENUM_(name)
-#define FLAG_MEMBER_ENUM_MANAGEABLE(type, name, value, doc)   FLAG_MEMBER_ENUM_(name)
-#define FLAG_MEMBER_ENUM_PRODUCT_RW(type, name, value, doc)   FLAG_MEMBER_ENUM_(name)
-#define FLAG_MEMBER_ENUM_DEVELOP(type, name, value, doc)      FLAG_MEMBER_ENUM_(name)
-#define FLAG_MEMBER_ENUM_PD_DEVELOP(type, name, doc)          FLAG_MEMBER_ENUM_(name)
-#define FLAG_MEMBER_ENUM_NOTPRODUCT(type, name, value, doc)   FLAG_MEMBER_ENUM_(name)
-#ifdef _LP64
-#define FLAG_MEMBER_ENUM_LP64_PRODUCT(type, name, value, doc) FLAG_MEMBER_ENUM_(name)
-#else
-#define FLAG_MEMBER_ENUM_LP64_PRODUCT(type, name, value, doc) /* flag is constant */
-#endif // _LP64
-
-typedef enum {
+#define FLAG_MEMBER_ENUM_PRODUCT(type, name, value, ...)      FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_PD_PRODUCT(type, name, ...)          FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_DEVELOP(type, name, value, ...)      FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_PD_DEVELOP(type, name, ...)          FLAG_MEMBER_ENUM_(name)
+#define FLAG_MEMBER_ENUM_NOTPRODUCT(type, name, value, ...)   FLAG_MEMBER_ENUM_(name)
+
+typedef enum : int {
   ALL_FLAGS(FLAG_MEMBER_ENUM_DEVELOP,
             FLAG_MEMBER_ENUM_PD_DEVELOP,
             FLAG_MEMBER_ENUM_PRODUCT,
             FLAG_MEMBER_ENUM_PD_PRODUCT,
-            FLAG_MEMBER_ENUM_DIAGNOSTIC,
-            FLAG_MEMBER_ENUM_PD_DIAGNOSTIC,
-            FLAG_MEMBER_ENUM_EXPERIMENTAL,
             FLAG_MEMBER_ENUM_NOTPRODUCT,
-            FLAG_MEMBER_ENUM_MANAGEABLE,
-            FLAG_MEMBER_ENUM_PRODUCT_RW,
-            FLAG_MEMBER_ENUM_LP64_PRODUCT,
             IGNORE_RANGE,
             IGNORE_CONSTRAINT)
   NUM_JVMFlagsEnum
@@ -100,33 +84,17 @@ class JVMFlagEx : JVMFlag {
 #define FLAG_MEMBER_SET(name) Flag_##name##_set
 #define FLAG_MEMBER_SET_(type, name) inline JVMFlag::Error FLAG_MEMBER_SET(name)(type value, JVMFlag::Flags origin) { return JVMFlagEx::type##AtPut(FLAG_MEMBER_ENUM(name), value, origin); }
 
-#define FLAG_MEMBER_SET_PRODUCT(type, name, value, doc)      FLAG_MEMBER_SET_(type, name)
-#define FLAG_MEMBER_SET_PD_PRODUCT(type, name, doc)          FLAG_MEMBER_SET_(type, name)
-#define FLAG_MEMBER_SET_DIAGNOSTIC(type, name, value, doc)   FLAG_MEMBER_SET_(type, name)
-#define FLAG_MEMBER_SET_PD_DIAGNOSTIC(type, name, doc)       FLAG_MEMBER_SET_(type, name)
-#define FLAG_MEMBER_SET_EXPERIMENTAL(type, name, value, doc) FLAG_MEMBER_SET_(type, name)
-#define FLAG_MEMBER_SET_MANAGEABLE(type, name, value, doc)   FLAG_MEMBER_SET_(type, name)
-#define FLAG_MEMBER_SET_PRODUCT_RW(type, name, value, doc)   FLAG_MEMBER_SET_(type, name)
-#define FLAG_MEMBER_SET_DEVELOP(type, name, value, doc)      FLAG_MEMBER_SET_(type, name)
-#define FLAG_MEMBER_SET_PD_DEVELOP(type, name, doc)          FLAG_MEMBER_SET_(type, name)
-#define FLAG_MEMBER_SET_NOTPRODUCT(type, name, value, doc)   FLAG_MEMBER_SET_(type, name)
-#ifdef _LP64
-#define FLAG_MEMBER_SET_LP64_PRODUCT(type, name, value, doc) FLAG_MEMBER_SET_(type, name)
-#else
-#define FLAG_MEMBER_SET_LP64_PRODUCT(type, name, value, doc) /* flag is constant */
-#endif // _LP64
+#define FLAG_MEMBER_SET_PRODUCT(type, name, value, ...)      FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_PD_PRODUCT(type, name, ...)          FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_DEVELOP(type, name, value, ...)      FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_PD_DEVELOP(type, name, ...)          FLAG_MEMBER_SET_(type, name)
+#define FLAG_MEMBER_SET_NOTPRODUCT(type, name, value, ...)   FLAG_MEMBER_SET_(type, name)
 
 ALL_FLAGS(FLAG_MEMBER_SET_DEVELOP,
           FLAG_MEMBER_SET_PD_DEVELOP,
           FLAG_MEMBER_SET_PRODUCT,
           FLAG_MEMBER_SET_PD_PRODUCT,
-          FLAG_MEMBER_SET_DIAGNOSTIC,
-          FLAG_MEMBER_SET_PD_DIAGNOSTIC,
-          FLAG_MEMBER_SET_EXPERIMENTAL,
           FLAG_MEMBER_SET_NOTPRODUCT,
-          FLAG_MEMBER_SET_MANAGEABLE,
-          FLAG_MEMBER_SET_PRODUCT_RW,
-          FLAG_MEMBER_SET_LP64_PRODUCT,
           IGNORE_RANGE,
           IGNORE_CONSTRAINT)
 
diff --git a/src/hotspot/share/runtime/globals_shared.hpp b/src/hotspot/share/runtime/globals_shared.hpp
index bca28da8dc8..36dc9409762 100644
--- a/src/hotspot/share/runtime/globals_shared.hpp
+++ b/src/hotspot/share/runtime/globals_shared.hpp
@@ -37,7 +37,7 @@
 // parts of the memory system may require additional alignment
 // and are responsible for those alignments.
 #ifdef _LP64
-#define ScaleForWordSize(x) align_down_((x) * 13 / 10, HeapWordSize)
+#define ScaleForWordSize(x) align_down((x) * 13 / 10, HeapWordSize)
 #else
 #define ScaleForWordSize(x) (x)
 #endif
@@ -77,18 +77,14 @@
 // Only materialize src code for contraint checking when required, ignore otherwise
 #define IGNORE_CONSTRAINT(func,type)
 
+#define IGNORE_FLAG(...)
+
 #define VM_FLAGS(             \
     develop,                  \
     develop_pd,               \
     product,                  \
     product_pd,               \
-    diagnostic,               \
-    diagnostic_pd,            \
-    experimental,             \
     notproduct,               \
-    manageable,               \
-    product_rw,               \
-    lp64_product,             \
     range,                    \
     constraint)               \
                               \
@@ -97,13 +93,7 @@
     develop_pd,               \
     product,                  \
     product_pd,               \
-    diagnostic,               \
-    diagnostic_pd,            \
-    experimental,             \
     notproduct,               \
-    manageable,               \
-    product_rw,               \
-    lp64_product,             \
     range,                    \
     constraint)               \
                               \
@@ -112,100 +102,87 @@
     develop_pd,               \
     product,                  \
     product_pd,               \
-    diagnostic,               \
-    diagnostic_pd,            \
-    experimental,             \
     notproduct,               \
-    manageable,               \
-    product_rw,               \
-    lp64_product,             \
     range,                    \
     constraint)               \
 
+// Put the LP64/JVMCI/COMPILER1/COMPILER1/ARCH at
+// the top, as they are processed by jvmFlags.cpp in that
+// order.
 
 #define ALL_FLAGS(            \
     develop,                  \
     develop_pd,               \
     product,                  \
     product_pd,               \
-    diagnostic,               \
-    diagnostic_pd,            \
-    experimental,             \
     notproduct,               \
-    manageable,               \
-    product_rw,               \
-    lp64_product,             \
     range,                    \
     constraint)               \
                               \
-  VM_FLAGS(                   \
+  LP64_RUNTIME_FLAGS(         \
     develop,                  \
     develop_pd,               \
     product,                  \
     product_pd,               \
-    diagnostic,               \
-    diagnostic_pd,            \
-    experimental,             \
     notproduct,               \
-    manageable,               \
-    product_rw,               \
-    lp64_product,             \
     range,                    \
     constraint)               \
                               \
-  RUNTIME_OS_FLAGS(           \
+  JVMCI_ONLY(JVMCI_FLAGS(     \
     develop,                  \
     develop_pd,               \
     product,                  \
     product_pd,               \
-    diagnostic,               \
-    diagnostic_pd,            \
     notproduct,               \
     range,                    \
-    constraint)               \
+    constraint))              \
                               \
-  JVMCI_ONLY(JVMCI_FLAGS(     \
+  COMPILER1_PRESENT(C1_FLAGS( \
     develop,                  \
     develop_pd,               \
     product,                  \
     product_pd,               \
-    diagnostic,               \
-    diagnostic_pd,            \
-    experimental,             \
     notproduct,               \
     range,                    \
     constraint))              \
                               \
-  COMPILER1_PRESENT(C1_FLAGS( \
+  COMPILER2_PRESENT(C2_FLAGS( \
     develop,                  \
     develop_pd,               \
     product,                  \
     product_pd,               \
-    diagnostic,               \
-    diagnostic_pd,            \
     notproduct,               \
     range,                    \
     constraint))              \
                               \
-  COMPILER2_PRESENT(C2_FLAGS( \
+  ARCH_FLAGS(                 \
+    develop,                  \
+    product,                  \
+    notproduct,               \
+    range,                    \
+    constraint)               \
+                              \
+  VM_FLAGS(                   \
     develop,                  \
     develop_pd,               \
     product,                  \
     product_pd,               \
-    diagnostic,               \
-    diagnostic_pd,            \
-    experimental,             \
     notproduct,               \
     range,                    \
-    constraint))              \
+    constraint)               \
                               \
-  ARCH_FLAGS(                 \
+  RUNTIME_OS_FLAGS(           \
     develop,                  \
+    develop_pd,               \
     product,                  \
-    diagnostic,               \
-    experimental,             \
+    product_pd,               \
     notproduct,               \
     range,                    \
     constraint)
 
+#define ALL_CONSTRAINTS(f)    \
+  COMPILER_CONSTRAINTS(f)     \
+  RUNTIME_CONSTRAINTS(f)      \
+  GC_CONSTRAINTS(f)
+
 #endif // SHARE_RUNTIME_GLOBALS_SHARED_HPP
diff --git a/src/hotspot/share/runtime/handshake.cpp b/src/hotspot/share/runtime/handshake.cpp
index e7875690ed1..89d27898186 100644
--- a/src/hotspot/share/runtime/handshake.cpp
+++ b/src/hotspot/share/runtime/handshake.cpp
@@ -141,7 +141,7 @@ class HandshakeSpinYield : public StackObj {
       // On UP this is always true.
       Thread* self = Thread::current();
       if (self->is_Java_thread()) {
-        wait_blocked((JavaThread*)self, now);
+        wait_blocked(self->as_Java_thread(), now);
       } else {
         wait_raw(now);
       }
@@ -393,7 +393,6 @@ void HandshakeState::set_operation(HandshakeOperation* op) {
     assert(Thread::current()->is_VM_thread(), "should be the VMThread");
     _operation = op;
   } else {
-    assert(Thread::current()->is_Java_thread(), "should be a JavaThread");
     // Serialize direct handshakes so that only one proceeds at a time for a given target
     _handshake_turn_sem.wait_with_safepoint_check(JavaThread::current());
     _operation_direct = op;
diff --git a/src/hotspot/share/runtime/interfaceSupport.cpp b/src/hotspot/share/runtime/interfaceSupport.cpp
index 42d8d073872..98bbb5e8687 100644
--- a/src/hotspot/share/runtime/interfaceSupport.cpp
+++ b/src/hotspot/share/runtime/interfaceSupport.cpp
@@ -107,7 +107,7 @@ void InterfaceSupport::gc_alot() {
   Thread *thread = Thread::current();
   if (!thread->is_Java_thread()) return; // Avoid concurrent calls
   // Check for new, not quite initialized thread. A thread in new mode cannot initiate a GC.
-  JavaThread *current_thread = (JavaThread *)thread;
+  JavaThread *current_thread = thread->as_Java_thread();
   if (current_thread->active_handles() == NULL) return;
 
   // Short-circuit any possible re-entrant gc-a-lot attempt
diff --git a/src/hotspot/share/runtime/interfaceSupport.inline.hpp b/src/hotspot/share/runtime/interfaceSupport.inline.hpp
index 45a931eef80..cb7154f7192 100644
--- a/src/hotspot/share/runtime/interfaceSupport.inline.hpp
+++ b/src/hotspot/share/runtime/interfaceSupport.inline.hpp
@@ -75,7 +75,7 @@ class ThreadStateTransition : public StackObj {
  public:
   ThreadStateTransition(JavaThread *thread) {
     _thread = thread;
-    assert(thread != NULL && thread->is_Java_thread(), "must be Java thread");
+    assert(thread != NULL, "must be active Java thread");
   }
 
   // Change threadstate in a manner, so safepoint can detect changes.
@@ -186,7 +186,7 @@ class ThreadInVMfromUnknown {
   ThreadInVMfromUnknown() : _thread(NULL) {
     Thread* t = Thread::current();
     if (t->is_Java_thread()) {
-      JavaThread* t2 = (JavaThread*) t;
+      JavaThread* t2 = t->as_Java_thread();
       if (t2->thread_state() == _thread_in_native) {
         _thread = t2;
         ThreadStateTransition::transition_from_native(t2, _thread_in_vm);
diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp
index dc1bc43a4ad..d40202beede 100644
--- a/src/hotspot/share/runtime/java.cpp
+++ b/src/hotspot/share/runtime/java.cpp
@@ -536,7 +536,7 @@ void vm_exit(int code) {
       // Historically there must have been some exit path for which
       // that was not the case and so we set it explicitly - even
       // though we no longer know what that path may be.
-      ((JavaThread*)thread)->set_thread_state(_thread_in_vm);
+      thread->as_Java_thread()->set_thread_state(_thread_in_vm);
     }
 
     // Fire off a VM_Exit operation to bring VM to a safepoint and exit
@@ -577,7 +577,7 @@ void vm_perform_shutdown_actions() {
     if (thread != NULL && thread->is_Java_thread()) {
       // We are leaving the VM, set state to native (in case any OS exit
       // handlers call back to the VM)
-      JavaThread* jt = (JavaThread*)thread;
+      JavaThread* jt = thread->as_Java_thread();
       // Must always be walkable or have no last_Java_frame when in
       // thread_in_native
       jt->frame_anchor()->make_walkable(jt);
diff --git a/src/hotspot/share/runtime/javaCalls.cpp b/src/hotspot/share/runtime/javaCalls.cpp
index e08b1232777..72a87d6b9fc 100644
--- a/src/hotspot/share/runtime/javaCalls.cpp
+++ b/src/hotspot/share/runtime/javaCalls.cpp
@@ -52,7 +52,7 @@
 // Implementation of JavaCallWrapper
 
 JavaCallWrapper::JavaCallWrapper(const methodHandle& callee_method, Handle receiver, JavaValue* result, TRAPS) {
-  JavaThread* thread = (JavaThread *)THREAD;
+  JavaThread* thread = THREAD->as_Java_thread();
   bool clear_pending_exception = true;
 
   guarantee(thread->is_Java_thread(), "crucial check - the VM thread cannot and must not escape to Java code");
@@ -88,7 +88,7 @@ JavaCallWrapper::JavaCallWrapper(const methodHandle& callee_method, Handle recei
   THREAD->allow_unhandled_oop(&_receiver);
 #endif // CHECK_UNHANDLED_OOPS
 
-  _thread       = (JavaThread *)thread;
+  _thread       = thread;
   _handles      = _thread->active_handles();    // save previous handle block & Java frame linkage
 
   // For the profiler, the last_Java_frame information in thread must always be in
@@ -343,8 +343,7 @@ void JavaCalls::call(JavaValue* result, const methodHandle& method, JavaCallArgu
 
 void JavaCalls::call_helper(JavaValue* result, const methodHandle& method, JavaCallArguments* args, TRAPS) {
 
-  JavaThread* thread = (JavaThread*)THREAD;
-  assert(thread->is_Java_thread(), "must be called by a java thread");
+  JavaThread* thread = THREAD->as_Java_thread();
   assert(method.not_null(), "must have a method to call");
   assert(!SafepointSynchronize::is_at_safepoint(), "call to Java code during VM operation");
   assert(!thread->handle_area()->no_handle_mark_active(), "cannot call out to Java here");
diff --git a/src/hotspot/share/runtime/jniHandles.cpp b/src/hotspot/share/runtime/jniHandles.cpp
index 11c0bee4e89..a77d50500ae 100644
--- a/src/hotspot/share/runtime/jniHandles.cpp
+++ b/src/hotspot/share/runtime/jniHandles.cpp
@@ -206,7 +206,7 @@ jobjectRefType JNIHandles::handle_type(Thread* thread, jobject handle) {
       // Not in global storage.  Might be a local handle.
       if (is_local_handle(thread, handle) ||
           (thread->is_Java_thread() &&
-           is_frame_handle((JavaThread*)thread, handle))) {
+           is_frame_handle(thread->as_Java_thread(), handle))) {
         result = JNILocalRefType;
       }
       break;
@@ -301,7 +301,7 @@ void JNIHandles::verify() {
 bool JNIHandles::current_thread_in_native() {
   Thread* thread = Thread::current();
   return (thread->is_Java_thread() &&
-          JavaThread::current()->thread_state() == _thread_in_native);
+          thread->as_Java_thread()->thread_state() == _thread_in_native);
 }
 
 
diff --git a/src/hotspot/share/runtime/mutex.cpp b/src/hotspot/share/runtime/mutex.cpp
index 2211cd1221f..e8eb720e2a6 100644
--- a/src/hotspot/share/runtime/mutex.cpp
+++ b/src/hotspot/share/runtime/mutex.cpp
@@ -84,7 +84,7 @@ void Mutex::lock_contended(Thread* self) {
     // 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_mutex);
+      { ThreadBlockInVMWithDeadlockCheck tbivmdc(self->as_Java_thread(), &in_flight_mutex);
         in_flight_mutex = this;  // save for ~ThreadBlockInVMWithDeadlockCheck
         _lock.lock();
       }
@@ -206,7 +206,7 @@ bool Monitor::wait_without_safepoint_check(int64_t timeout) {
 }
 
 bool Monitor::wait(int64_t timeout, bool as_suspend_equivalent) {
-  Thread* const self = Thread::current();
+  JavaThread* const self = JavaThread::current();
 
   // timeout is in milliseconds - with zero meaning never timeout
   assert(timeout >= 0, "negative timeout");
@@ -223,14 +223,14 @@ bool Monitor::wait(int64_t timeout, bool as_suspend_equivalent) {
   set_owner(NULL);
   // Check safepoint state after resetting owner and possible NSV.
   check_safepoint_state(self);
-  JavaThread *jt = (JavaThread *)self;
+
   Mutex* in_flight_mutex = NULL;
 
   {
-    ThreadBlockInVMWithDeadlockCheck tbivmdc(jt, &in_flight_mutex);
+    ThreadBlockInVMWithDeadlockCheck tbivmdc(self, &in_flight_mutex);
     OSThreadWaitState osts(self->osthread(), false /* not Object.wait() */);
     if (as_suspend_equivalent) {
-      jt->set_suspend_equivalent();
+      self->set_suspend_equivalent();
       // cleared by handle_special_suspend_equivalent_condition() or
       // java_suspend_self()
     }
@@ -239,13 +239,13 @@ bool Monitor::wait(int64_t timeout, bool as_suspend_equivalent) {
     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()) {
+    if (as_suspend_equivalent && self->handle_special_suspend_equivalent_condition()) {
       // Our event wait has finished and we own the lock, but
       // while we were waiting another thread suspended us. We don't
       // want to hold the lock while suspended because that
       // would surprise the thread that suspended us.
       _lock.unlock();
-      jt->java_suspend_self();
+      self->java_suspend_self();
       _lock.lock();
     }
   }
diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp
index 90b1b2b9c28..5db41d59c0f 100644
--- a/src/hotspot/share/runtime/mutexLocker.cpp
+++ b/src/hotspot/share/runtime/mutexLocker.cpp
@@ -151,6 +151,7 @@ Mutex*   CDSClassFileStream_lock      = NULL;
 #endif
 Mutex*   DumpTimeTable_lock           = NULL;
 Mutex*   CDSLambda_lock               = NULL;
+Mutex*   DumpRegion_lock              = NULL;
 #endif // INCLUDE_CDS
 
 #if INCLUDE_JVMCI
@@ -346,6 +347,7 @@ void mutex_init() {
 #endif
   def(DumpTimeTable_lock           , PaddedMutex  , leaf - 1,    true,  _safepoint_check_never);
   def(CDSLambda_lock               , PaddedMutex  , leaf,        true,  _safepoint_check_never);
+  def(DumpRegion_lock              , PaddedMutex  , leaf,        true,  _safepoint_check_never);
 #endif // INCLUDE_CDS
 
 #if INCLUDE_JVMCI
diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp
index fa82246169e..26103c85904 100644
--- a/src/hotspot/share/runtime/mutexLocker.hpp
+++ b/src/hotspot/share/runtime/mutexLocker.hpp
@@ -130,6 +130,7 @@ extern Mutex*   CDSClassFileStream_lock;         // FileMapInfo::open_stream_for
 #endif
 extern Mutex*   DumpTimeTable_lock;              // SystemDictionaryShared::find_or_allocate_info_for
 extern Mutex*   CDSLambda_lock;                  // SystemDictionaryShared::get_shared_lambda_proxy_class
+extern Mutex*   DumpRegion_lock;                 // Symbol::operator new(size_t sz, int len)
 #endif // INCLUDE_CDS
 #if INCLUDE_JFR
 extern Mutex*   JfrStacktrace_lock;              // used to guard access to the JFR stacktrace table
diff --git a/src/hotspot/share/runtime/objectMonitor.cpp b/src/hotspot/share/runtime/objectMonitor.cpp
index 226713c8363..b558e3f6252 100644
--- a/src/hotspot/share/runtime/objectMonitor.cpp
+++ b/src/hotspot/share/runtime/objectMonitor.cpp
@@ -276,9 +276,9 @@ bool ObjectMonitor::enter(TRAPS) {
   if (TrySpin(Self) > 0) {
     assert(_owner == Self, "must be Self: owner=" INTPTR_FORMAT, p2i(_owner));
     assert(_recursions == 0, "must be 0: recursions=" INTX_FORMAT, _recursions);
-    assert(((oop)object())->mark() == markWord::encode(this),
+    assert(object()->mark() == markWord::encode(this),
            "object mark must match encoded this: mark=" INTPTR_FORMAT
-           ", encoded this=" INTPTR_FORMAT, ((oop)object())->mark().value(),
+           ", encoded this=" INTPTR_FORMAT, object()->mark().value(),
            markWord::encode(this).value());
     Self->_Stalled = 0;
     return true;
@@ -286,8 +286,7 @@ bool ObjectMonitor::enter(TRAPS) {
 
   assert(_owner != Self, "invariant");
   assert(_succ != Self, "invariant");
-  assert(Self->is_Java_thread(), "invariant");
-  JavaThread * jt = (JavaThread *) Self;
+  JavaThread * jt = Self->as_Java_thread();
   assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
   assert(jt->thread_state() != _thread_blocked, "invariant");
 
@@ -297,7 +296,7 @@ bool ObjectMonitor::enter(TRAPS) {
     // Async deflation is in progress and our contentions increment
     // above lost the race to async deflation. Undo the work and
     // force the caller to retry.
-    const oop l_object = (oop)object();
+    const oop l_object = object();
     if (l_object != NULL) {
       // Attempt to restore the header/dmw to the object's header so that
       // we only retry once if the deflater thread happens to be slow.
@@ -311,8 +310,8 @@ bool ObjectMonitor::enter(TRAPS) {
   JFR_ONLY(JfrConditionalFlushWithStacktrace<EventJavaMonitorEnter> flush(jt);)
   EventJavaMonitorEnter event;
   if (event.should_commit()) {
-    event.set_monitorClass(((oop)this->object())->klass());
-    event.set_address((uintptr_t)(this->object_addr()));
+    event.set_monitorClass(object()->klass());
+    event.set_address((uintptr_t)object_addr());
   }
 
   { // Change java thread status to indicate blocked on monitor enter.
@@ -375,7 +374,7 @@ bool ObjectMonitor::enter(TRAPS) {
   assert(_recursions == 0, "invariant");
   assert(_owner == Self, "invariant");
   assert(_succ != Self, "invariant");
-  assert(((oop)(object()))->mark() == markWord::encode(this), "invariant");
+  assert(object()->mark() == markWord::encode(this), "invariant");
 
   // The thread -- now the owner -- is back in vm mode.
   // Report the glorious news via TI,DTrace and jvmstat.
@@ -447,7 +446,7 @@ void ObjectMonitor::install_displaced_markword_in_object(const oop obj) {
     OrderAccess::loadload();
   }
 
-  const oop l_object = (oop)object();
+  const oop l_object = object();
   if (l_object == NULL) {
     // ObjectMonitor's object ref has already been cleared by async
     // deflation so we're done here.
@@ -506,8 +505,7 @@ const char* ObjectMonitor::is_busy_to_string(stringStream* ss) {
 
 void ObjectMonitor::EnterI(TRAPS) {
   Thread * const Self = THREAD;
-  assert(Self->is_Java_thread(), "invariant");
-  assert(((JavaThread *) Self)->thread_state() == _thread_blocked, "invariant");
+  assert(Self->as_Java_thread()->thread_state() == _thread_blocked, "invariant");
 
   // Try the lock - TATAS
   if (TryLock (Self) > 0) {
@@ -772,9 +770,10 @@ void ObjectMonitor::ReenterI(Thread * Self, ObjectWaiter * SelfNode) {
   assert(SelfNode != NULL, "invariant");
   assert(SelfNode->_thread == Self, "invariant");
   assert(_waiters > 0, "invariant");
-  assert(((oop)(object()))->mark() == markWord::encode(this), "invariant");
-  assert(((JavaThread *)Self)->thread_state() != _thread_blocked, "invariant");
-  JavaThread * jt = (JavaThread *) Self;
+  assert(object()->mark() == markWord::encode(this), "invariant");
+
+  JavaThread * jt = Self->as_Java_thread();
+  assert(jt->thread_state() != _thread_blocked, "invariant");
 
   int nWakeups = 0;
   for (;;) {
@@ -840,7 +839,7 @@ void ObjectMonitor::ReenterI(Thread * Self, ObjectWaiter * SelfNode) {
   // In addition, Self.TState is stable.
 
   assert(_owner == Self, "invariant");
-  assert(((oop)(object()))->mark() == markWord::encode(this), "invariant");
+  assert(object()->mark() == markWord::encode(this), "invariant");
   UnlinkAfterAcquire(Self, SelfNode);
   if (_succ == Self) _succ = NULL;
   assert(_succ != Self, "invariant");
@@ -1227,8 +1226,7 @@ void ObjectMonitor::ExitEpilog(Thread * Self, ObjectWaiter * Wakee) {
 // thread due to contention.
 intx ObjectMonitor::complete_exit(TRAPS) {
   Thread * const Self = THREAD;
-  assert(Self->is_Java_thread(), "Must be Java thread!");
-  JavaThread *jt = (JavaThread *)THREAD;
+  JavaThread * jt = Self->as_Java_thread();
 
   assert(InitDone, "Unexpectedly not initialized");
 
@@ -1253,8 +1251,7 @@ intx ObjectMonitor::complete_exit(TRAPS) {
 // complete_exit/reenter operate as a wait without waiting
 bool ObjectMonitor::reenter(intx recursions, TRAPS) {
   Thread * const Self = THREAD;
-  assert(Self->is_Java_thread(), "Must be Java thread!");
-  JavaThread *jt = (JavaThread *)THREAD;
+  JavaThread * jt = Self->as_Java_thread();
 
   guarantee(_owner != Self, "reenter already owner");
   if (!enter(THREAD)) {
@@ -1304,7 +1301,7 @@ static void post_monitor_wait_event(EventJavaMonitorWait* event,
                                     bool timedout) {
   assert(event != NULL, "invariant");
   assert(monitor != NULL, "invariant");
-  event->set_monitorClass(((oop)monitor->object())->klass());
+  event->set_monitorClass(monitor->object()->klass());
   event->set_timeout(timeout);
   event->set_address((uintptr_t)monitor->object_addr());
   event->set_notifier(notifier_tid);
@@ -1319,8 +1316,7 @@ static void post_monitor_wait_event(EventJavaMonitorWait* event,
 // will need to be replicated in complete_exit
 void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
   Thread * const Self = THREAD;
-  assert(Self->is_Java_thread(), "Must be Java thread!");
-  JavaThread *jt = (JavaThread *)THREAD;
+  JavaThread * jt = Self->as_Java_thread();
 
   assert(InitDone, "Unexpectedly not initialized");
 
@@ -1523,7 +1519,7 @@ void ObjectMonitor::wait(jlong millis, bool interruptible, TRAPS) {
   // Verify a few postconditions
   assert(_owner == Self, "invariant");
   assert(_succ != Self, "invariant");
-  assert(((oop)(object()))->mark() == markWord::encode(this), "invariant");
+  assert(object()->mark() == markWord::encode(this), "invariant");
 
   // check if the notification happened
   if (!WasNotified) {
@@ -1948,12 +1944,12 @@ ObjectWaiter::ObjectWaiter(Thread* thread) {
 }
 
 void ObjectWaiter::wait_reenter_begin(ObjectMonitor * const mon) {
-  JavaThread *jt = (JavaThread *)this->_thread;
+  JavaThread *jt = this->_thread->as_Java_thread();
   _active = JavaThreadBlockedOnMonitorEnterState::wait_reenter_begin(jt, mon);
 }
 
 void ObjectWaiter::wait_reenter_end(ObjectMonitor * const mon) {
-  JavaThread *jt = (JavaThread *)this->_thread;
+  JavaThread *jt = this->_thread->as_Java_thread();
   JavaThreadBlockedOnMonitorEnterState::wait_reenter_end(jt, _active);
 }
 
@@ -2107,7 +2103,7 @@ void ObjectMonitor::print() const { print_on(tty); }
 void ObjectMonitor::print_debug_style_on(outputStream* st) const {
   st->print_cr("(ObjectMonitor*) " INTPTR_FORMAT " = {", p2i(this));
   st->print_cr("  _header = " INTPTR_FORMAT, header().value());
-  st->print_cr("  _object = " INTPTR_FORMAT, p2i(_object));
+  st->print_cr("  _object = " INTPTR_FORMAT, p2i(object()));
   st->print("  _allocation_state = ");
   if (is_free()) {
     st->print("Free");
diff --git a/src/hotspot/share/runtime/objectMonitor.hpp b/src/hotspot/share/runtime/objectMonitor.hpp
index b56207e314c..8a4eaf5bb5c 100644
--- a/src/hotspot/share/runtime/objectMonitor.hpp
+++ b/src/hotspot/share/runtime/objectMonitor.hpp
@@ -328,9 +328,9 @@ class ObjectMonitor {
 
  public:
 
-  void*     object() const;
-  void*     object_addr();
-  void      set_object(void* obj);
+  oop       object() const;
+  oop*      object_addr();
+  void      set_object(oop obj);
   void      release_set_allocation_state(AllocationState s);
   void      set_allocation_state(AllocationState s);
   AllocationState allocation_state() const;
diff --git a/src/hotspot/share/runtime/objectMonitor.inline.hpp b/src/hotspot/share/runtime/objectMonitor.inline.hpp
index a88b5c4a3b3..a55eb5b7f87 100644
--- a/src/hotspot/share/runtime/objectMonitor.inline.hpp
+++ b/src/hotspot/share/runtime/objectMonitor.inline.hpp
@@ -92,22 +92,22 @@ inline void ObjectMonitor::clear_common() {
   assert(contentions() <= 0, "must not be positive: contentions=%d", contentions());
   assert(_waiters == 0, "must be 0: waiters=%d", _waiters);
   assert(_recursions == 0, "must be 0: recursions=" INTX_FORMAT, _recursions);
-  assert(_object != NULL, "must be non-NULL");
+  assert(object() != NULL, "must be non-NULL");
 
   set_allocation_state(Free);
-  _object = NULL;
+  set_object(NULL);
 }
 
-inline void* ObjectMonitor::object() const {
-  return _object;
+inline oop ObjectMonitor::object() const {
+  return (oop)_object;
 }
 
-inline void* ObjectMonitor::object_addr() {
-  return (void *)(&_object);
+inline oop* ObjectMonitor::object_addr() {
+  return (oop*)&_object;
 }
 
-inline void ObjectMonitor::set_object(void* obj) {
-  _object = obj;
+inline void ObjectMonitor::set_object(oop obj) {
+  _object = (void*)obj;
 }
 
 // Return number of threads contending for this monitor.
diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp
index a10c7ba2f55..2a3621f3712 100644
--- a/src/hotspot/share/runtime/os.cpp
+++ b/src/hotspot/share/runtime/os.cpp
@@ -1375,7 +1375,7 @@ bool os::stack_shadow_pages_available(Thread *thread, const methodHandle& method
   const int framesize_in_bytes =
     Interpreter::size_top_interpreter_activation(method()) * wordSize;
 
-  address limit = ((JavaThread*)thread)->stack_end() +
+  address limit = thread->as_Java_thread()->stack_end() +
                   (JavaThread::stack_guard_zone_size() + JavaThread::stack_shadow_zone_size());
 
   return sp > (limit + framesize_in_bytes);
diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp
index d42d864c2d9..50bb12861fe 100644
--- a/src/hotspot/share/runtime/reflection.cpp
+++ b/src/hotspot/share/runtime/reflection.cpp
@@ -1033,7 +1033,7 @@ static oop invoke(InstanceKlass* klass,
           // JVMTI has already reported the pending exception
           // JVMTI internal flag reset is needed in order to report InvocationTargetException
           if (THREAD->is_Java_thread()) {
-            JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
+            JvmtiExport::clear_detected_exception(THREAD->as_Java_thread());
           }
           JavaCallArguments args(Handle(THREAD, resolution_exception));
           THROW_ARG_0(vmSymbols::java_lang_reflect_InvocationTargetException(),
@@ -1147,7 +1147,7 @@ static oop invoke(InstanceKlass* klass,
     // JVMTI has already reported the pending exception
     // JVMTI internal flag reset is needed in order to report InvocationTargetException
     if (THREAD->is_Java_thread()) {
-      JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
+      JvmtiExport::clear_detected_exception(THREAD->as_Java_thread());
     }
 
     JavaCallArguments args(Handle(THREAD, target_exception));
diff --git a/src/hotspot/share/runtime/safepoint.cpp b/src/hotspot/share/runtime/safepoint.cpp
index 9e167d53070..bc25b4032fb 100644
--- a/src/hotspot/share/runtime/safepoint.cpp
+++ b/src/hotspot/share/runtime/safepoint.cpp
@@ -693,7 +693,6 @@ static void check_for_lazy_critical_native(JavaThread *thread, JavaThreadState s
 
 void SafepointSynchronize::block(JavaThread *thread) {
   assert(thread != NULL, "thread must be set");
-  assert(thread->is_Java_thread(), "not a Java thread");
 
   // Threads shouldn't block if they are in the middle of printing, but...
   ttyLocker::break_tty_lock_for_safepoint(os::current_thread_id());
@@ -783,7 +782,6 @@ void SafepointSynchronize::block(JavaThread *thread) {
 
 
 void SafepointSynchronize::handle_polling_page_exception(JavaThread *thread) {
-  assert(thread->is_Java_thread(), "polling reference encountered by VM thread");
   assert(thread->thread_state() == _thread_in_Java, "should come from Java code");
 
   if (log_is_enabled(Info, safepoint, stats)) {
diff --git a/src/hotspot/share/runtime/safepointMechanism.inline.hpp b/src/hotspot/share/runtime/safepointMechanism.inline.hpp
index cec1513cbd5..9410544c076 100644
--- a/src/hotspot/share/runtime/safepointMechanism.inline.hpp
+++ b/src/hotspot/share/runtime/safepointMechanism.inline.hpp
@@ -40,7 +40,7 @@ bool SafepointMechanism::global_poll() {
 
 bool SafepointMechanism::local_poll(Thread* thread) {
   if (thread->is_Java_thread()) {
-    return local_poll_armed((JavaThread*)thread);
+    return local_poll_armed(thread->as_Java_thread());
   } else {
     // If the poll is on a non-java thread we can only check the global state.
     return global_poll();
diff --git a/src/hotspot/share/runtime/sharedRuntime.cpp b/src/hotspot/share/runtime/sharedRuntime.cpp
index 256f42b5485..63922c34c0f 100644
--- a/src/hotspot/share/runtime/sharedRuntime.cpp
+++ b/src/hotspot/share/runtime/sharedRuntime.cpp
@@ -950,7 +950,7 @@ JRT_END
 jlong SharedRuntime::get_java_tid(Thread* thread) {
   if (thread != NULL) {
     if (thread->is_Java_thread()) {
-      oop obj = ((JavaThread*)thread)->threadObj();
+      oop obj = thread->as_Java_thread()->threadObj();
       return (obj == NULL) ? 0 : java_lang_Thread::thread_id(obj);
     }
   }
@@ -3147,9 +3147,8 @@ void AdapterHandlerLibrary::print_statistics() {
 #endif /* PRODUCT */
 
 JRT_LEAF(void, SharedRuntime::enable_stack_reserved_zone(JavaThread* thread))
-  assert(thread->is_Java_thread(), "Only Java threads have a stack reserved zone");
   if (thread->stack_reserved_zone_disabled()) {
-  thread->enable_stack_reserved_zone();
+    thread->enable_stack_reserved_zone();
   }
   thread->set_reserved_stack_activation(thread->stack_base());
 JRT_END
diff --git a/src/hotspot/share/runtime/sweeper.cpp b/src/hotspot/share/runtime/sweeper.cpp
index 04e3ec8e131..cffae92ccc2 100644
--- a/src/hotspot/share/runtime/sweeper.cpp
+++ b/src/hotspot/share/runtime/sweeper.cpp
@@ -158,8 +158,7 @@ class NMethodMarkingClosure : public HandshakeClosure {
   NMethodMarkingClosure(CodeBlobClosure* cl) : HandshakeClosure("NMethodMarking"), _cl(cl) {}
   void do_thread(Thread* thread) {
     if (thread->is_Java_thread() && ! thread->is_Code_cache_sweeper_thread()) {
-      JavaThread* jt = (JavaThread*) thread;
-      jt->nmethods_do(_cl);
+      thread->as_Java_thread()->nmethods_do(_cl);
     }
   }
 };
diff --git a/src/hotspot/share/runtime/synchronizer.cpp b/src/hotspot/share/runtime/synchronizer.cpp
index 2585f4b3e9e..8b47d243ee1 100644
--- a/src/hotspot/share/runtime/synchronizer.cpp
+++ b/src/hotspot/share/runtime/synchronizer.cpp
@@ -449,8 +449,7 @@ static ObjectMonitor* take_from_start_of_om_free_list(Thread* self) {
 
 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");
+  assert(self->as_Java_thread()->thread_state() == _thread_in_Java, "invariant");
   NoSafepointVerifier nsv;
   if (obj == NULL) return false;  // slow-path for invalid obj
   const markWord mark = obj->mark();
@@ -463,7 +462,7 @@ bool ObjectSynchronizer::quick_notify(oopDesc* obj, Thread* self, bool all) {
 
   if (mark.has_monitor()) {
     ObjectMonitor* const mon = mark.monitor();
-    assert(mon->object() == obj, "invariant");
+    assert(mon->object() == oop(obj), "invariant");
     if (mon->owner() != self) return false;  // slow-path for IMS exception
 
     if (mon->first_waiter() != NULL) {
@@ -499,8 +498,7 @@ bool ObjectSynchronizer::quick_notify(oopDesc* obj, Thread* self, bool all) {
 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->as_Java_thread()->thread_state() == _thread_in_Java, "invariant");
   NoSafepointVerifier nsv;
   if (obj == NULL) return false;       // Need to throw NPE
 
@@ -560,8 +558,7 @@ bool ObjectSynchronizer::quick_enter(oop obj, Thread* self,
 
 // Handle notifications when synchronizing on primitive wrappers
 void ObjectSynchronizer::handle_sync_on_primitive_wrapper(Handle obj, Thread* current) {
-  assert(current->is_Java_thread(), "must be for java object synchronization");
-  JavaThread* self = (JavaThread*) current;
+  JavaThread* self = current->as_Java_thread();
 
   frame last_frame = self->last_frame();
   if (last_frame.is_interpreted_frame()) {
@@ -686,7 +683,7 @@ void ObjectSynchronizer::exit(oop object, BasicLock* lock, TRAPS) {
         // 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->object()->mark() == mark, "invariant");
         assert(m->is_entered(THREAD), "invariant");
       }
     }
@@ -1428,7 +1425,7 @@ void ObjectSynchronizer::list_oops_do(ObjectMonitor* list, OopClosure* f) {
   // so no need to lock ObjectMonitors for the list traversal.
   for (ObjectMonitor* mid = list; mid != NULL; mid = unmarked_next(mid)) {
     if (mid->object() != NULL) {
-      f->do_oop((oop*)mid->object_addr());
+      f->do_oop(mid->object_addr());
     }
   }
 }
@@ -2149,7 +2146,7 @@ bool ObjectSynchronizer::deflate_monitor_using_JT(ObjectMonitor* mid,
             "must be no entering threads: EntryList=" INTPTR_FORMAT,
             p2i(mid->_EntryList));
 
-  const oop obj = (oop) mid->object();
+  const oop obj = mid->object();
   if (log_is_enabled(Trace, monitorinflation)) {
     ResourceMark rm;
     log_trace(monitorinflation)("deflate_monitor_using_JT: "
@@ -2426,7 +2423,6 @@ void ObjectSynchronizer::deflate_idle_monitors_using_JT() {
 // Deflate global idle ObjectMonitors using a JavaThread.
 //
 void ObjectSynchronizer::deflate_global_idle_monitors_using_JT() {
-  assert(Thread::current()->is_Java_thread(), "precondition");
   JavaThread* self = JavaThread::current();
 
   deflate_common_idle_monitors_using_JT(true /* is_global */, self);
@@ -2871,7 +2867,7 @@ void ObjectSynchronizer::chk_in_use_entry(JavaThread* jt, ObjectMonitor* n,
     }
     *error_cnt_p = *error_cnt_p + 1;
   }
-  const oop obj = (oop)n->object();
+  const oop obj = n->object();
   const markWord mark = obj->mark();
   if (!mark.has_monitor()) {
     if (jt != NULL) {
@@ -2981,7 +2977,7 @@ void ObjectSynchronizer::log_in_use_monitor_details(outputStream * out) {
     if ((cur = get_list_head_locked(&om_list_globals._in_use_list)) != NULL) {
       // Marked the global in-use list head so process the list.
       while (true) {
-        const oop obj = (oop) cur->object();
+        const oop obj = cur->object();
         const markWord mark = cur->header();
         ResourceMark rm;
         out->print(INTPTR_FORMAT "  %d%d%d  " INTPTR_FORMAT "  %s", p2i(cur),
@@ -3011,7 +3007,7 @@ void ObjectSynchronizer::log_in_use_monitor_details(outputStream * out) {
     if ((cur = get_list_head_locked(&jt->om_in_use_list)) != NULL) {
       // Marked the global in-use list head so process the list.
       while (true) {
-        const oop obj = (oop) cur->object();
+        const oop obj = cur->object();
         const markWord mark = cur->header();
         ResourceMark rm;
         out->print(INTPTR_FORMAT "  " INTPTR_FORMAT "  %d%d%d  " INTPTR_FORMAT
diff --git a/src/hotspot/share/runtime/thread.cpp b/src/hotspot/share/runtime/thread.cpp
index de4ec7eae13..204cd033589 100644
--- a/src/hotspot/share/runtime/thread.cpp
+++ b/src/hotspot/share/runtime/thread.cpp
@@ -355,8 +355,8 @@ void Thread::record_stack_base_and_size() {
 
   // Set stack limits after thread is initialized.
   if (is_Java_thread()) {
-    ((JavaThread*) this)->set_stack_overflow_limit();
-    ((JavaThread*) this)->set_reserved_stack_activation(stack_base());
+    as_Java_thread()->set_stack_overflow_limit();
+    as_Java_thread()->set_reserved_stack_activation(stack_base());
   }
 }
 
@@ -483,9 +483,9 @@ Thread::~Thread() {
 //
 void Thread::check_for_dangling_thread_pointer(Thread *thread) {
   assert(!thread->is_Java_thread() || Thread::current() == thread ||
-         !((JavaThread *) thread)->on_thread_list() ||
+         !thread->as_Java_thread()->on_thread_list() ||
          SafepointSynchronize::is_at_safepoint() ||
-         ThreadsSMRSupport::is_a_protected_JavaThread_with_lock((JavaThread *) thread),
+         ThreadsSMRSupport::is_a_protected_JavaThread_with_lock(thread->as_Java_thread()),
          "possibility of dangling Thread pointer");
 }
 #endif
@@ -514,7 +514,7 @@ void Thread::start(Thread* thread) {
       // Can not set it after the thread started because we do not know the
       // exact thread state at that time. It could be in MONITOR_WAIT or
       // in SLEEPING or some other state.
-      java_lang_Thread::set_thread_status(((JavaThread*)thread)->threadObj(),
+      java_lang_Thread::set_thread_status(thread->as_Java_thread()->threadObj(),
                                           java_lang_Thread::RUNNABLE);
     }
     os::start_thread(thread);
@@ -527,7 +527,7 @@ class InstallAsyncExceptionClosure : public HandshakeClosure {
   InstallAsyncExceptionClosure(Handle throwable) : HandshakeClosure("InstallAsyncException"), _throwable(throwable) {}
 
   void do_thread(Thread* thr) {
-    JavaThread* target = (JavaThread*)thr;
+    JavaThread* target = thr->as_Java_thread();
     // Note that this now allows multiple ThreadDeath exceptions to be
     // thrown at a thread.
     // The target thread has run and has not exited yet.
@@ -1005,7 +1005,7 @@ void Thread::check_for_valid_safepoint_state() {
   // are held.
   check_possible_safepoint();
 
-  if (((JavaThread*)this)->thread_state() != _thread_in_vm) {
+  if (this->as_Java_thread()->thread_state() != _thread_in_vm) {
     fatal("LEAF method calling lock?");
   }
 
@@ -1030,7 +1030,7 @@ bool Thread::set_as_starting_thread() {
          "_starting_thread=" INTPTR_FORMAT, p2i(_starting_thread));
   // NOTE: this must be called inside the main thread.
   DEBUG_ONLY(_starting_thread = this;)
-  return os::create_main_thread((JavaThread*)this);
+  return os::create_main_thread(this->as_Java_thread());
 }
 
 static void initialize_class(Symbol* class_name, TRAPS) {
@@ -2278,12 +2278,11 @@ void JavaThread::cleanup_failed_attach_current_thread(bool is_daemon) {
 JavaThread* JavaThread::active() {
   Thread* thread = Thread::current();
   if (thread->is_Java_thread()) {
-    return (JavaThread*) thread;
+    return thread->as_Java_thread();
   } else {
     assert(thread->is_VM_thread(), "this must be a vm thread");
     VM_Operation* op = ((VMThread*) thread)->vm_operation();
-    JavaThread *ret=op == NULL ? NULL : (JavaThread *)op->calling_thread();
-    assert(ret->is_Java_thread(), "must be a Java thread");
+    JavaThread *ret = op == NULL ? NULL : op->calling_thread()->as_Java_thread();
     return ret;
   }
 }
@@ -2554,8 +2553,7 @@ int JavaThread::java_suspend_self() {
     return ret;
   }
 
-  assert(_anchor.walkable() ||
-         (is_Java_thread() && !((JavaThread*)this)->has_last_Java_frame()),
+  assert(_anchor.walkable() || !has_last_Java_frame(),
          "must have walkable stack");
 
   MonitorLocker ml(SR_lock(), Mutex::_no_safepoint_check_flag);
@@ -3202,10 +3200,9 @@ const char* JavaThread::get_thread_name() const {
 #ifdef ASSERT
   // early safepoints can hit while current thread does not yet have TLS
   if (!SafepointSynchronize::is_at_safepoint()) {
-    Thread *cur = Thread::current();
-    if (!(cur->is_Java_thread() && cur == this)) {
-      // Current JavaThreads are allowed to get their own name without
-      // the Threads_lock.
+    // Current JavaThreads are allowed to get their own name without
+    // the Threads_lock.
+    if (Thread::current() != this) {
       assert_locked_or_safepoint_or_handshake(Threads_lock, this);
     }
   }
diff --git a/src/hotspot/share/runtime/thread.hpp b/src/hotspot/share/runtime/thread.hpp
index c8bfc1b7824..0c4668ce9fc 100644
--- a/src/hotspot/share/runtime/thread.hpp
+++ b/src/hotspot/share/runtime/thread.hpp
@@ -98,6 +98,8 @@ DEBUG_ONLY(class ResourceMark;)
 
 class WorkerThread;
 
+class JavaThread;
+
 // Class hierarchy
 // - Thread
 //   - JavaThread
@@ -501,6 +503,8 @@ class Thread: public ThreadShadow {
 
   // Casts
   virtual WorkerThread* as_Worker_thread() const     { return NULL; }
+  inline JavaThread* as_Java_thread();
+  inline const JavaThread* as_Java_thread() const;
 
   virtual char* name() const { return (char*)"Unknown thread"; }
 
@@ -2110,9 +2114,7 @@ class JavaThread: public Thread {
 
 // Inline implementation of JavaThread::current
 inline JavaThread* JavaThread::current() {
-  Thread* thread = Thread::current();
-  assert(thread->is_Java_thread(), "just checking");
-  return (JavaThread*)thread;
+  return Thread::current()->as_Java_thread();
 }
 
 inline CompilerThread* JavaThread::as_CompilerThread() {
@@ -2209,6 +2211,16 @@ class CompilerThread : public JavaThread {
   void         set_task(CompileTask* task) { _task = task; }
 };
 
+inline JavaThread* Thread::as_Java_thread() {
+  assert(is_Java_thread(), "incorrect cast to JavaThread");
+  return static_cast<JavaThread*>(this);
+}
+
+inline const JavaThread* Thread::as_Java_thread() const {
+  assert(is_Java_thread(), "incorrect cast to const JavaThread");
+  return static_cast<const JavaThread*>(this);
+}
+
 inline CompilerThread* CompilerThread::current() {
   return JavaThread::current()->as_CompilerThread();
 }
diff --git a/src/hotspot/share/runtime/timer.cpp b/src/hotspot/share/runtime/timer.cpp
index aa64cc2bff8..d810f4524db 100644
--- a/src/hotspot/share/runtime/timer.cpp
+++ b/src/hotspot/share/runtime/timer.cpp
@@ -42,6 +42,11 @@ jlong TimeHelper::millis_to_counter(jlong millis) {
   return millis * freq;
 }
 
+jlong TimeHelper::micros_to_counter(jlong micros) {
+  jlong freq = os::elapsed_frequency() / MICROUNITS;
+  return micros * freq;
+}
+
 elapsedTimer::elapsedTimer(jlong time, jlong timeUnitsPerSecond) {
   _active = false;
   jlong osTimeUnitsPerSecond = os::elapsed_frequency();
diff --git a/src/hotspot/share/runtime/timer.hpp b/src/hotspot/share/runtime/timer.hpp
index 5f9cb17e6f2..9e29072a124 100644
--- a/src/hotspot/share/runtime/timer.hpp
+++ b/src/hotspot/share/runtime/timer.hpp
@@ -77,6 +77,7 @@ class TimeHelper {
   static double counter_to_seconds(jlong counter);
   static double counter_to_millis(jlong counter);
   static jlong millis_to_counter(jlong millis);
+  static jlong micros_to_counter(jlong micros);
 };
 
 #endif // SHARE_RUNTIME_TIMER_HPP
diff --git a/src/hotspot/share/runtime/vframeArray.cpp b/src/hotspot/share/runtime/vframeArray.cpp
index 759bb82445e..4221425738f 100644
--- a/src/hotspot/share/runtime/vframeArray.cpp
+++ b/src/hotspot/share/runtime/vframeArray.cpp
@@ -176,7 +176,7 @@ void vframeArrayElement::unpack_on_stack(int caller_actual_parameters,
                                          bool is_top_frame,
                                          bool is_bottom_frame,
                                          int exec_mode) {
-  JavaThread* thread = (JavaThread*) Thread::current();
+  JavaThread* thread = JavaThread::current();
 
   bool realloc_failure_exception = thread->frames_to_pop_failed_realloc() > 0;
 
diff --git a/src/hotspot/share/runtime/vmOperations.cpp b/src/hotspot/share/runtime/vmOperations.cpp
index c54548a6a52..3b50a480d1a 100644
--- a/src/hotspot/share/runtime/vmOperations.cpp
+++ b/src/hotspot/share/runtime/vmOperations.cpp
@@ -150,9 +150,7 @@ void VM_DeoptimizeAll::doit() {
 
 
 void VM_ZombieAll::doit() {
-  JavaThread *thread = (JavaThread *)calling_thread();
-  assert(thread->is_Java_thread(), "must be a Java thread");
-  thread->make_zombies();
+  calling_thread()->as_Java_thread()->make_zombies();
 }
 
 #endif // !PRODUCT
diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp
index 669aeff7f1c..d69954a44ce 100644
--- a/src/hotspot/share/runtime/vmStructs.cpp
+++ b/src/hotspot/share/runtime/vmStructs.cpp
@@ -338,9 +338,9 @@ typedef HashtableEntry<InstanceKlass*, mtClass>  KlassHashtableEntry;
   volatile_nonstatic_field(ConstantPoolCacheEntry,      _f2,                                  intx)                                  \
   volatile_nonstatic_field(ConstantPoolCacheEntry,      _flags,                               intx)                                  \
                                                                                                                                      \
-  /********************************/                                                                                                 \
-  /* MethodOop-related structures */                                                                                                 \
-  /********************************/                                                                                                 \
+  /*****************************/                                                                                                    \
+  /* Method related structures */                                                                                                    \
+  /*****************************/                                                                                                    \
                                                                                                                                      \
   nonstatic_field(CheckedExceptionElement,     class_cp_index,                                u2)                                    \
   nonstatic_field(LocalVariableTableElement,   start_bci,                                     u2)                                    \
@@ -1284,9 +1284,9 @@ typedef HashtableEntry<InstanceKlass*, mtClass>  KlassHashtableEntry;
                                                                           \
   declare_toplevel_type(OopHandle)                                        \
                                                                           \
-  /*************************************/                                 \
-  /* MethodOop-related data structures */                                 \
-  /*************************************/                                 \
+  /**********************************/                                    \
+  /* Method related data structures */                                    \
+  /**********************************/                                    \
                                                                           \
   declare_toplevel_type(CheckedExceptionElement)                          \
   declare_toplevel_type(LocalVariableTableElement)                        \
diff --git a/src/hotspot/share/runtime/vmThread.cpp b/src/hotspot/share/runtime/vmThread.cpp
index d208264f202..f9eae673b36 100644
--- a/src/hotspot/share/runtime/vmThread.cpp
+++ b/src/hotspot/share/runtime/vmThread.cpp
@@ -309,8 +309,7 @@ void VMThread::run() {
 // Notify the VMThread that the last non-daemon JavaThread has terminated,
 // and wait until operation is performed.
 void VMThread::wait_for_vm_thread_exit() {
-  assert(Thread::current()->is_Java_thread(), "Should be a JavaThread");
-  assert(((JavaThread*)Thread::current())->is_terminated(), "Should be terminated");
+  assert(JavaThread::current()->is_terminated(), "Should be terminated");
   { MonitorLocker mu(VMOperationQueue_lock, Mutex::_no_safepoint_check_flag);
     _should_terminate = true;
     mu.notify();
@@ -377,9 +376,7 @@ class HandshakeALotClosure : public HandshakeClosure {
   HandshakeALotClosure() : HandshakeClosure("HandshakeALot") {}
   void do_thread(Thread* thread) {
 #ifdef ASSERT
-    assert(thread->is_Java_thread(), "must be");
-    JavaThread* jt = (JavaThread*)thread;
-    jt->verify_states_for_handshake();
+    thread->as_Java_thread()->verify_states_for_handshake();
 #endif
   }
 };
@@ -446,9 +443,6 @@ void VMThread::loop() {
             // something. This will run all the clean-up processing that needs
             // to be done at a safepoint.
             SafepointSynchronize::begin();
-            #ifdef ASSERT
-            if (GCALotAtAllSafepoints) InterfaceSupport::check_gc_alot();
-            #endif
             SafepointSynchronize::end();
             _cur_vm_operation = NULL;
           }
@@ -490,22 +484,7 @@ void VMThread::loop() {
 
       } else {  // not a safepoint operation
         log_debug(vmthread)("Evaluating non-safepoint VM operation: %s", _cur_vm_operation->name());
-        if (TraceLongCompiles) {
-          elapsedTimer t;
-          t.start();
-          evaluate_operation(_cur_vm_operation);
-          t.stop();
-          double secs = t.seconds();
-          if (secs * 1e3 > LongCompileThreshold) {
-            // XXX - _cur_vm_operation should not be accessed after
-            // the completed count has been incremented; the waiting
-            // thread may have already freed this memory.
-            tty->print_cr("vm %s: %3.7f secs]", _cur_vm_operation->name(), secs);
-          }
-        } else {
-          evaluate_operation(_cur_vm_operation);
-        }
-
+        evaluate_operation(_cur_vm_operation);
         _cur_vm_operation = NULL;
       }
     }
diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp
index c7be958fd1d..e884a3f3580 100644
--- a/src/hotspot/share/services/diagnosticCommand.cpp
+++ b/src/hotspot/share/services/diagnosticCommand.cpp
@@ -1073,7 +1073,7 @@ void DebugOnCmdStartDCmd::execute(DCmdSource source, TRAPS) {
   char const* transport = NULL;
   char const* addr = NULL;
   jboolean is_first_start = JNI_FALSE;
-  JavaThread* thread = (JavaThread*) THREAD;
+  JavaThread* thread = THREAD->as_Java_thread();
   jthread jt = JNIHandles::make_local(thread->threadObj());
   ThreadToNativeFromVM ttn(thread);
   const char *error = "Could not find jdwp agent.";
diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp
index 12e6160f83a..fa18c3093c4 100644
--- a/src/hotspot/share/services/management.cpp
+++ b/src/hotspot/share/services/management.cpp
@@ -2071,12 +2071,8 @@ JVM_ENTRY(jlong, jmm_GetOneThreadAllocatedMemory(JNIEnv *env, jlong thread_id))
                "Invalid thread ID", -1);
   }
 
-  if (thread_id == 0) {
-    // current thread
-    if (THREAD->is_Java_thread()) {
-      return ((JavaThread*)THREAD)->cooked_allocated_bytes();
-    }
-    return -1;
+  if (thread_id == 0) { // current thread
+    return thread->cooked_allocated_bytes();
   }
 
   ThreadsListHandle tlh;
diff --git a/src/hotspot/share/services/memoryPool.cpp b/src/hotspot/share/services/memoryPool.cpp
index a60dcf6492e..e2159a12583 100644
--- a/src/hotspot/share/services/memoryPool.cpp
+++ b/src/hotspot/share/services/memoryPool.cpp
@@ -29,6 +29,7 @@
 #include "memory/universe.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
+#include "runtime/globals_extension.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
 #include "services/lowMemoryDetector.hpp"
diff --git a/src/hotspot/share/services/nmtCommon.hpp b/src/hotspot/share/services/nmtCommon.hpp
index 7fb7975567b..ea2f396fa8b 100644
--- a/src/hotspot/share/services/nmtCommon.hpp
+++ b/src/hotspot/share/services/nmtCommon.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,7 @@
 #include "utilities/align.hpp"
 #include "utilities/globalDefinitions.hpp"
 
-#define CALC_OBJ_SIZE_IN_TYPE(obj, type) (align_up_(sizeof(obj), sizeof(type))/sizeof(type))
+#define CALC_OBJ_SIZE_IN_TYPE(obj, type) (align_up(sizeof(obj), sizeof(type))/sizeof(type))
 
 // Native memory tracking level
 enum NMT_TrackingLevel {
diff --git a/src/hotspot/share/services/threadService.cpp b/src/hotspot/share/services/threadService.cpp
index 28e054c0fb5..e31e935ad84 100644
--- a/src/hotspot/share/services/threadService.cpp
+++ b/src/hotspot/share/services/threadService.cpp
@@ -229,12 +229,12 @@ Handle ThreadService::get_current_contended_monitor(JavaThread* thread) {
   oop obj = NULL;
   if (wait_obj != NULL) {
     // thread is doing an Object.wait() call
-    obj = (oop) wait_obj->object();
+    obj = wait_obj->object();
   } else {
     ObjectMonitor *enter_obj = thread->current_pending_monitor();
     if (enter_obj != NULL) {
       // thread is trying to enter() an ObjectMonitor.
-      obj = (oop) enter_obj->object();
+      obj = enter_obj->object();
     }
   }
 
@@ -422,8 +422,7 @@ DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(ThreadsList * t_list,
         Thread* owner = waitingToLockRawMonitor->owner();
         if (owner != NULL && // the raw monitor could be released at any time
             owner->is_Java_thread()) {
-          // only JavaThreads can be reported here
-          currentThread = (JavaThread*) owner;
+          currentThread = owner->as_Java_thread();
         }
       } else if (waitingToLockMonitor != NULL) {
         address currentOwner = (address)waitingToLockMonitor->owner();
@@ -626,7 +625,7 @@ class InflatedMonitorsClosure: public MonitorClosure {
   }
   void do_monitor(ObjectMonitor* mid) {
     if (mid->owner() == _thread) {
-      oop object = (oop) mid->object();
+      oop object = mid->object();
       if (!_stack_trace->is_owned_monitor_on_stack(object)) {
         _stack_trace->add_jni_locked_monitor(object);
       }
@@ -878,6 +877,8 @@ void ThreadSnapshot::initialize(ThreadsList * t_list, JavaThread* thread) {
   _is_ext_suspended = thread->is_being_ext_suspended();
   _is_in_native = (thread->thread_state() == _thread_in_native);
 
+  Handle obj = ThreadService::get_current_contended_monitor(thread);
+
   oop blocker_object = NULL;
   oop blocker_object_owner = NULL;
 
@@ -885,7 +886,6 @@ void ThreadSnapshot::initialize(ThreadsList * t_list, JavaThread* thread) {
       _thread_status == java_lang_Thread::IN_OBJECT_WAIT ||
       _thread_status == java_lang_Thread::IN_OBJECT_WAIT_TIMED) {
 
-    Handle obj = ThreadService::get_current_contended_monitor(thread);
     if (obj() == NULL) {
       // monitor no longer exists; thread is not blocked
       _thread_status = java_lang_Thread::RUNNABLE;
@@ -986,7 +986,7 @@ void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const
       // Could be NULL as the raw monitor could be released at any time if held by non-JavaThread
       if (owner != NULL) {
         if (owner->is_Java_thread()) {
-          currentThread = (JavaThread*) owner;
+          currentThread = owner->as_Java_thread();
           st->print_cr("%s \"%s\"", owner_desc, currentThread->get_thread_name());
         } else {
           st->print_cr(",\n  which has now been released");
@@ -998,7 +998,7 @@ void DeadlockCycle::print_on_with(ThreadsList * t_list, outputStream* st) const
 
     if (waitingToLockMonitor != NULL) {
       st->print("  waiting to lock monitor " INTPTR_FORMAT, p2i(waitingToLockMonitor));
-      oop obj = (oop)waitingToLockMonitor->object();
+      oop obj = waitingToLockMonitor->object();
       st->print(" (object " INTPTR_FORMAT ", a %s)", p2i(obj),
                  obj->klass()->external_name());
 
diff --git a/src/hotspot/share/services/writeableFlags.cpp b/src/hotspot/share/services/writeableFlags.cpp
index f5d5e321b43..84aa9edc578 100644
--- a/src/hotspot/share/services/writeableFlags.cpp
+++ b/src/hotspot/share/services/writeableFlags.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,12 +39,12 @@ static void buffer_concat(char* buffer, const char* src) {
 }
 
 static void print_flag_error_message_bounds(const JVMFlag* flag, char* buffer) {
-  JVMFlagRange* range = JVMFlagRangeList::find(flag);
-  if (range != NULL) {
+  JVMFlagRangeChecker range = JVMFlagRangeList::find(flag);
+  if (range.exists()) {
     buffer_concat(buffer, "must have value in range ");
 
     stringStream stream;
-    range->print(&stream);
+    range.print(&stream);
     const char* range_string = stream.as_string();
     size_t j = strlen(buffer);
     for (size_t i=0; j<TEMP_BUF_SIZE-1; i++) {
diff --git a/src/hotspot/share/utilities/align.hpp b/src/hotspot/share/utilities/align.hpp
index 50c9808c7fa..7c7a4f67bc5 100644
--- a/src/hotspot/share/utilities/align.hpp
+++ b/src/hotspot/share/utilities/align.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,65 +25,64 @@
 #ifndef SHARE_UTILITIES_ALIGN_HPP
 #define SHARE_UTILITIES_ALIGN_HPP
 
+#include "metaprogramming/enableIf.hpp"
+#include "utilities/debug.hpp"
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/powerOfTwo.hpp"
-
-// Signed variants of alignment helpers.  There are two versions of each, a macro
-// for use in places like enum definitions that require compile-time constant
-// expressions and a function for all other places so as to get type checking.
-
-// Using '(what) & ~align_mask(alignment)' to align 'what' down is broken when
-// 'alignment' is an unsigned int and 'what' is a wider type. The & operation
-// will widen the inverted mask, and not sign extend it, leading to a mask with
-// zeros in the most significant bits. The use of align_mask_widened() solves
-// this problem.
-#define align_mask(alignment) ((alignment) - 1)
-#define widen_to_type_of(what, type_carrier) (true ? (what) : (type_carrier))
-#define align_mask_widened(alignment, type_carrier) widen_to_type_of(align_mask(alignment), (type_carrier))
-
-#define align_down_(size, alignment) ((size) & ~align_mask_widened((alignment), (size)))
-
-#define align_up_(size, alignment) (align_down_((size) + align_mask(alignment), (alignment)))
-
-#define is_aligned_(size, alignment) (((size) & align_mask(alignment)) == 0)
-
-// Helpers to align sizes and check for alignment
-
-template <typename T, typename A>
-inline T align_up(T size, A alignment) {
-  assert(is_power_of_2(alignment), "must be a power of 2: " UINT64_FORMAT, (uint64_t)alignment);
-
-  T ret = align_up_(size, alignment);
-  assert(is_aligned_(ret, alignment), "must be aligned: " UINT64_FORMAT, (uint64_t)ret);
-
-  return ret;
+#include <type_traits>
+
+// Compute mask to use for aligning to or testing alignment.
+// The alignment must be a power of 2. Returns alignment - 1, which is
+// a mask with all bits set below alignment's single bit.
+template<typename T, ENABLE_IF(std::is_integral<T>::value)>
+static constexpr T alignment_mask(T alignment) {
+  assert(is_power_of_2(alignment),
+         "must be a power of 2: " UINT64_FORMAT, (uint64_t)alignment);
+  return alignment - 1;
 }
 
-template <typename T, typename A>
-inline T align_down(T size, A alignment) {
-  assert(is_power_of_2(alignment), "must be a power of 2: " UINT64_FORMAT, (uint64_t)alignment);
+// Some "integral" constant alignments are defined via enum.
+template<typename T, ENABLE_IF(std::is_enum<T>::value)>
+static constexpr auto alignment_mask(T alignment) {
+  return alignment_mask(static_cast<std::underlying_type_t<T>>(alignment));
+}
 
-  T ret = align_down_(size, alignment);
-  assert(is_aligned_(ret, alignment), "must be aligned: " UINT64_FORMAT, (uint64_t)ret);
+// Align integers and check for alignment.
+// The is_integral filtering here is not for disambiguation with the T*
+// overloads; if those match then they are a better match.  Rather, the
+// is_integral filtering is to prevent back-sliding on the use of enums
+// as "integral" constants that need aligning.
 
-  return ret;
+template<typename T, typename A, ENABLE_IF(std::is_integral<T>::value)>
+constexpr bool is_aligned(T size, A alignment) {
+  return (size & alignment_mask(alignment)) == 0;
 }
 
-template <typename T, typename A>
-inline bool is_aligned(T size, A alignment) {
-  assert(is_power_of_2(alignment), "must be a power of 2: " UINT64_FORMAT, (uint64_t)alignment);
+template<typename T, typename A, ENABLE_IF(std::is_integral<T>::value)>
+constexpr T align_down(T size, A alignment) {
+  // Convert mask to T before logical_not.  Otherwise, if alignment is unsigned
+  // and smaller than T, the result of the logical_not will be zero-extended
+  // by integral promotion, and upper bits of size will be discarded.
+  T result = size & ~T(alignment_mask(alignment));
+  assert(is_aligned(result, alignment),
+         "must be aligned: " UINT64_FORMAT, (uint64_t)result);
+  return result;
+}
 
-  return is_aligned_(size, alignment);
+template<typename T, typename A, ENABLE_IF(std::is_integral<T>::value)>
+constexpr T align_up(T size, A alignment) {
+  T adjusted = size + alignment_mask(alignment);
+  return align_down(adjusted, alignment);
 }
 
 // Align down with a lower bound. If the aligning results in 0, return 'alignment'.
 template <typename T, typename A>
-inline T align_down_bounded(T size, A alignment) {
-  A aligned_size = align_down(size, alignment);
-  return aligned_size > 0 ? aligned_size : alignment;
+constexpr T align_down_bounded(T size, A alignment) {
+  T aligned_size = align_down(size, alignment);
+  return (aligned_size > 0) ? aligned_size : T(alignment);
 }
 
-// Helpers to align pointers and check for alignment.
+// Align pointers and check for alignment.
 
 template <typename T, typename A>
 inline T* align_up(T* ptr, A alignment) {
@@ -122,7 +121,7 @@ inline bool is_object_aligned(const void* addr) {
 
 // Pad out certain offsets to jlong alignment, in HeapWord units.
 template <typename T>
-inline T align_object_offset(T offset) {
+constexpr T align_object_offset(T offset) {
   return align_up(offset, HeapWordsPerLong);
 }
 
diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp
index 62d9a3ec14d..ebd2ffc2266 100644
--- a/src/hotspot/share/utilities/globalDefinitions.hpp
+++ b/src/hotspot/share/utilities/globalDefinitions.hpp
@@ -972,12 +972,12 @@ inline intptr_t bitfield(intptr_t x, int start_bit_no, int field_length) {
 // and 64-bit overloaded functions, which does not work, and having
 // explicitly-typed versions of these routines (i.e., MAX2I, MAX2L)
 // will be even more error-prone than macros.
-template<class T> inline T MAX2(T a, T b)           { return (a > b) ? a : b; }
-template<class T> inline T MIN2(T a, T b)           { return (a < b) ? a : b; }
-template<class T> inline T MAX3(T a, T b, T c)      { return MAX2(MAX2(a, b), c); }
-template<class T> inline T MIN3(T a, T b, T c)      { return MIN2(MIN2(a, b), c); }
-template<class T> inline T MAX4(T a, T b, T c, T d) { return MAX2(MAX3(a, b, c), d); }
-template<class T> inline T MIN4(T a, T b, T c, T d) { return MIN2(MIN3(a, b, c), d); }
+template<class T> constexpr T MAX2(T a, T b)           { return (a > b) ? a : b; }
+template<class T> constexpr T MIN2(T a, T b)           { return (a < b) ? a : b; }
+template<class T> constexpr T MAX3(T a, T b, T c)      { return MAX2(MAX2(a, b), c); }
+template<class T> constexpr T MIN3(T a, T b, T c)      { return MIN2(MIN2(a, b), c); }
+template<class T> constexpr T MAX4(T a, T b, T c, T d) { return MAX2(MAX3(a, b, c), d); }
+template<class T> constexpr T MIN4(T a, T b, T c, T d) { return MIN2(MIN3(a, b, c), d); }
 
 template<class T> inline T ABS(T x)                 { return (x > 0) ? x : -x; }
 
diff --git a/src/hotspot/share/utilities/powerOfTwo.hpp b/src/hotspot/share/utilities/powerOfTwo.hpp
index a8cc68fe506..fb96b1242f9 100644
--- a/src/hotspot/share/utilities/powerOfTwo.hpp
+++ b/src/hotspot/share/utilities/powerOfTwo.hpp
@@ -26,16 +26,17 @@
 #define SHARE_UTILITIES_POWEROFTWO_HPP
 
 #include "metaprogramming/enableIf.hpp"
-#include "metaprogramming/isIntegral.hpp"
-#include "metaprogramming/isSigned.hpp"
 #include "utilities/count_leading_zeros.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include <limits>
+#include <type_traits>
 
 // Power of two convenience library.
 
-template <typename T>
-bool is_power_of_2(T x) {
+// Returns true iff there exists integer i such that (T(1) << i) == x.
+template <typename T, ENABLE_IF(std::is_integral<T>::value)>
+constexpr bool is_power_of_2(T x) {
   return (x > T(0)) && ((x & (x - 1)) == T(0));
 }
 
@@ -55,94 +56,36 @@ inline int exact_log2_long(jlong x) {
   return bits - count_leading_zeros(x) - 1;
 }
 
-// Round down to the closest power of two greater to or equal to the given
-// value.
-
-// Signed version: 0 is an invalid input, negative values are invalid
-template <typename T>
-inline typename EnableIf<IsSigned<T>::value, T>::type round_down_power_of_2(T value) {
-  STATIC_ASSERT(IsIntegral<T>::value);
+// Round down to the closest power of two less than or equal to the given value.
+// precondition: value > 0.
+template<typename T, ENABLE_IF(std::is_integral<T>::value)>
+inline T round_down_power_of_2(T value) {
   assert(value > 0, "Invalid value");
   uint32_t lz = count_leading_zeros(value);
-  assert(lz < sizeof(T) * BitsPerByte, "Sanity");
-  return T(1) << (sizeof(T) * BitsPerByte - 1 - lz);
-}
-
-// Unsigned version: 0 is an invalid input
-template <typename T>
-inline typename EnableIf<!IsSigned<T>::value, T>::type round_down_power_of_2(T value) {
-  STATIC_ASSERT(IsIntegral<T>::value);
-  assert(value != 0, "Invalid value");
-  uint32_t lz = count_leading_zeros(value);
-  assert(lz < sizeof(T) * BitsPerByte, "Sanity");
   return T(1) << (sizeof(T) * BitsPerByte - 1 - lz);
 }
 
-// Round up to the closest power of two greater to or equal to
-// the given value.
-
-// Signed version: 0 is an invalid input, negative values are invalid,
-// overflows with assert if value is larger than 2^30 or 2^62 for 32- and
-// 64-bit integers, respectively
-template <typename T>
-inline typename EnableIf<IsSigned<T>::value, T>::type round_up_power_of_2(T value) {
-  STATIC_ASSERT(IsIntegral<T>::value);
-  STATIC_ASSERT(IsSigned<T>::value);
+// Round up to the closest power of two greater to or equal to the given value.
+// precondition: value > 0.
+// precondition: value <= maximum power of two representable by T.
+template<typename T, ENABLE_IF(std::is_integral<T>::value)>
+inline T round_up_power_of_2(T value) {
   assert(value > 0, "Invalid value");
+  const T max_value = std::numeric_limits<T>::max();
+  assert(value <= (max_value - (max_value >> 1)), "Overflow");
   if (is_power_of_2(value)) {
     return value;
   }
   uint32_t lz = count_leading_zeros(value);
-  assert(lz < sizeof(T) * BitsPerByte, "Sanity");
-  assert(lz > 1, "Will overflow");
-  return T(1) << (sizeof(T) * BitsPerByte - lz);
-}
-
-// Unsigned version: 0 is an invalid input, overflows with assert if value
-// is larger than 2^31 or 2^63 for 32- and 64-bit integers, respectively
-template <typename T>
-inline typename EnableIf<!IsSigned<T>::value, T>::type round_up_power_of_2(T value) {
-  STATIC_ASSERT(IsIntegral<T>::value);
-  STATIC_ASSERT(!IsSigned<T>::value);
-  assert(value != 0, "Invalid value");
-  if (is_power_of_2(value)) {
-    return value;
-  }
-  uint32_t lz = count_leading_zeros(value);
-  assert(lz < sizeof(T) * BitsPerByte, "Sanity");
-  assert(lz > 0, "Will overflow");
   return T(1) << (sizeof(T) * BitsPerByte - lz);
 }
 
-// Helper function to get the maximum positive value. Implemented here
-// since using std::numeric_limits<T>::max() seems problematic on some
-// platforms.
-
-template <typename T> T max_value() {
-  if (IsSigned<T>::value) {
-    // Highest positive power of two expressible in the type
-    uint64_t val = static_cast<T>(1) << (sizeof(T) * BitsPerByte - 2);
-    // Fill lower bits with ones
-    val |= val >> 1;
-    val |= val >> 2;
-    val |= val >> 4;
-    if (sizeof(T) >= 2)  val |= val >> 8;
-    if (sizeof(T) >= 4)  val |= val >> 16;
-    if (sizeof(T) == 8)  val |= val >> 32;
-    return (T)val;
-  } else {
-    return ~(static_cast<T>(0));
-  }
-}
-
 // Calculate the next power of two greater than the given value.
-
-// Accepts 0 (returns 1), overflows with assert if value is larger than
-// or equal to 2^31 (signed: 2^30) or 2^63 (signed: 2^62), for 32-
-// and 64-bit integers, respectively
-template <typename T>
+// precondition: if signed, value >= 0.
+// precondition: value < maximum power of two representable by T.
+template <typename T, ENABLE_IF(std::is_integral<T>::value)>
 inline T next_power_of_2(T value)  {
-  assert(value != max_value<T>(), "Overflow");
+  assert(value < std::numeric_limits<T>::max(), "Overflow");
   return round_up_power_of_2(value + 1);
 }
 
diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp
index b49984de8d9..f767cdad803 100644
--- a/src/hotspot/share/utilities/vmError.cpp
+++ b/src/hotspot/share/utilities/vmError.cpp
@@ -144,8 +144,7 @@ static void print_bug_submit_message(outputStream *out, Thread *thread) {
   // provider of that code.
   if (thread && thread->is_Java_thread() &&
       !thread->is_hidden_from_external_view()) {
-    JavaThread* jt = (JavaThread*)thread;
-    if (jt->thread_state() == _thread_in_native) {
+    if (thread->as_Java_thread()->thread_state() == _thread_in_native) {
       out->print_cr("# The crash happened outside the Java Virtual Machine in native code.\n# See problematic frame for where to report the bug.");
     }
   }
@@ -259,7 +258,7 @@ void VMError::print_native_stack(outputStream* st, frame fr, Thread* t, char* bu
           break;
         }
         if (fr.is_java_frame() || fr.is_native_frame() || fr.is_runtime_frame()) {
-          RegisterMap map((JavaThread*)t, false); // No update
+          RegisterMap map(t->as_Java_thread(), false); // No update
           fr = fr.sender(&map);
         } else {
           // is_first_C_frame() does only simple checks for frame pointer,
@@ -743,7 +742,7 @@ void VMError::report(outputStream* st, bool _verbose) {
   STEP("printing Java stack")
 
      if (_verbose && _thread && _thread->is_Java_thread()) {
-       print_stack_trace(st, (JavaThread*)_thread, buf, sizeof(buf));
+       print_stack_trace(st, _thread->as_Java_thread(), buf, sizeof(buf));
      }
 
   STEP("printing target Java thread stack")
diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java
index 1fabad43738..cdd45808bf2 100644
--- a/src/java.base/share/classes/java/lang/Class.java
+++ b/src/java.base/share/classes/java/lang/Class.java
@@ -4424,17 +4424,22 @@ public ClassDesc[] permittedSubclasses() {
     }
 
     /**
-     * * {@preview Associated with sealed classes, a preview feature of the Java language.
+     * {@preview Associated with sealed classes, a preview feature of the Java language.
      *
      *           This method is associated with <i>sealed classes</i>, a preview
      *           feature of the Java language. Preview features
      *           may be removed in a future release, or upgraded to permanent
      *           features of the Java language.}
      *
-     * Returns {@code true} if and only if this {@code Class} object represents a sealed class or interface.
-     * If this {@code Class} object represents a primitive type, {@code void}, or an array type, this method returns
+     * Returns {@code true} if and only if this {@code Class} object represents
+     * a sealed class or interface. If this {@code Class} object represents a
+     * primitive type, {@code void}, or an array type, this method returns
      * {@code false}.
      *
+     * @apiNote
+     * This method reports on a distinct concept of sealing from
+     * {@link Package#isSealed() Package::isSealed}.
+     *
      * @return {@code true} if and only if this {@code Class} object represents a sealed class or interface.
      *
      * @jls 8.1 Class Declarations
diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java
index aff4857e410..0b870c23be2 100644
--- a/src/java.base/share/classes/java/lang/ClassLoader.java
+++ b/src/java.base/share/classes/java/lang/ClassLoader.java
@@ -2714,6 +2714,17 @@ private boolean trySetObjectField(String name, Object obj) {
         offset = unsafe.objectFieldOffset(k, name);
         return unsafe.compareAndSetReference(this, offset, null, obj);
     }
+
+    /**
+     * Called by the VM, during -Xshare:dump
+     */
+    private void resetArchivedStates() {
+        parallelLockMap.clear();
+        packages.clear();
+        package2certs.clear();
+        classes.clear();
+        classLoaderValueMap = null;
+    }
 }
 
 /*
diff --git a/src/java.base/share/classes/java/lang/ClassValue.java b/src/java.base/share/classes/java/lang/ClassValue.java
index 1b4c114a8ac..beb07bb2782 100644
--- a/src/java.base/share/classes/java/lang/ClassValue.java
+++ b/src/java.base/share/classes/java/lang/ClassValue.java
@@ -29,6 +29,8 @@
 import java.lang.ref.WeakReference;
 import java.util.concurrent.atomic.AtomicInteger;
 
+import jdk.internal.misc.Unsafe;
+
 import static java.lang.ClassValue.ClassValueMap.probeHomeLocation;
 import static java.lang.ClassValue.ClassValueMap.probeBackupLocations;
 
@@ -369,12 +371,22 @@ private static ClassValueMap getMap(Class<?> type) {
     }
 
     private static final Object CRITICAL_SECTION = new Object();
+    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
     private static ClassValueMap initializeMap(Class<?> type) {
         ClassValueMap map;
         synchronized (CRITICAL_SECTION) {  // private object to avoid deadlocks
             // happens about once per type
-            if ((map = type.classValueMap) == null)
-                type.classValueMap = map = new ClassValueMap();
+            if ((map = type.classValueMap) == null) {
+                map = new ClassValueMap();
+                // Place a Store fence after construction and before publishing to emulate
+                // ClassValueMap containing final fields. This ensures it can be
+                // published safely in the non-volatile field Class.classValueMap,
+                // since stores to the fields of ClassValueMap will not be reordered
+                // to occur after the store to the field type.classValueMap
+                UNSAFE.storeFence();
+
+                type.classValueMap = map;
+            }
         }
         return map;
     }
diff --git a/src/java.base/share/classes/java/lang/Module.java b/src/java.base/share/classes/java/lang/Module.java
index 119621c9b16..3d5734f7a91 100644
--- a/src/java.base/share/classes/java/lang/Module.java
+++ b/src/java.base/share/classes/java/lang/Module.java
@@ -55,6 +55,7 @@
 import jdk.internal.loader.BuiltinClassLoader;
 import jdk.internal.loader.BootLoader;
 import jdk.internal.loader.ClassLoaders;
+import jdk.internal.misc.VM;
 import jdk.internal.module.IllegalAccessLogger;
 import jdk.internal.module.ModuleLoaderMap;
 import jdk.internal.module.ServicesCatalog;
@@ -246,12 +247,55 @@ public ModuleLayer getLayer() {
     // --
 
     // special Module to mean "all unnamed modules"
-    private static final Module ALL_UNNAMED_MODULE = new Module(null);
-    private static final Set<Module> ALL_UNNAMED_MODULE_SET = Set.of(ALL_UNNAMED_MODULE);
+    private static final Module ALL_UNNAMED_MODULE;
+    private static final Set<Module> ALL_UNNAMED_MODULE_SET;
 
     // special Module to mean "everyone"
-    private static final Module EVERYONE_MODULE = new Module(null);
-    private static final Set<Module> EVERYONE_SET = Set.of(EVERYONE_MODULE);
+    private static final Module EVERYONE_MODULE;
+    private static final Set<Module> EVERYONE_SET;
+
+    private static class ArchivedData {
+        private static ArchivedData archivedData;
+        private final Module allUnnamedModule;
+        private final Set<Module> allUnnamedModules;
+        private final Module everyoneModule;
+        private final Set<Module> everyoneSet;
+
+        private ArchivedData() {
+            this.allUnnamedModule = ALL_UNNAMED_MODULE;
+            this.allUnnamedModules = ALL_UNNAMED_MODULE_SET;
+            this.everyoneModule = EVERYONE_MODULE;
+            this.everyoneSet = EVERYONE_SET;
+        }
+
+        static void archive() {
+            archivedData = new ArchivedData();
+        }
+
+        static ArchivedData get() {
+            return archivedData;
+        }
+
+        static {
+            VM.initializeFromArchive(ArchivedData.class);
+        }
+    }
+
+    static {
+        ArchivedData archivedData = ArchivedData.get();
+        if (archivedData != null) {
+            ALL_UNNAMED_MODULE = archivedData.allUnnamedModule;
+            ALL_UNNAMED_MODULE_SET = archivedData.allUnnamedModules;
+            EVERYONE_MODULE = archivedData.everyoneModule;
+            EVERYONE_SET = archivedData.everyoneSet;
+        } else {
+            ALL_UNNAMED_MODULE = new Module(null);
+            ALL_UNNAMED_MODULE_SET = Set.of(ALL_UNNAMED_MODULE);
+            EVERYONE_MODULE = new Module(null);
+            EVERYONE_SET = Set.of(EVERYONE_MODULE);
+            ArchivedData.archive();
+        }
+    }
 
     /**
      * The holder of data structures to support readability, exports, and
diff --git a/src/java.base/share/classes/java/lang/Package.java b/src/java.base/share/classes/java/lang/Package.java
index 934bc0ed992..98e14ae7be6 100644
--- a/src/java.base/share/classes/java/lang/Package.java
+++ b/src/java.base/share/classes/java/lang/Package.java
@@ -223,6 +223,10 @@ public String getImplementationVendor() {
     /**
      * Returns true if this package is sealed.
      *
+     * @apiNote
+     * This method reports on a distinct concept of sealing from
+     * {@link Class#isSealed() Class::isSealed}.
+     *
      * @return true if the package is sealed, false otherwise
      */
     public boolean isSealed() {
diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java
index 4bc6f30d473..b8ab97f008c 100644
--- a/src/java.base/share/classes/java/lang/System.java
+++ b/src/java.base/share/classes/java/lang/System.java
@@ -2248,6 +2248,9 @@ public boolean isReflectivelyOpened(Module m, String pn, Module other) {
             public ServicesCatalog getServicesCatalog(ModuleLayer layer) {
                 return layer.getServicesCatalog();
             }
+            public void bindToLoader(ModuleLayer layer, ClassLoader loader) {
+                layer.bindToLoader(loader);
+            }
             public Stream<ModuleLayer> layers(ModuleLayer layer) {
                 return layer.layers();
             }
diff --git a/src/java.base/share/classes/java/lang/runtime/PatternCarriers.java b/src/java.base/share/classes/java/lang/runtime/PatternCarriers.java
deleted file mode 100755
index d6231933031..00000000000
--- a/src/java.base/share/classes/java/lang/runtime/PatternCarriers.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.runtime;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * PatternCarriers
- */
-class PatternCarriers {
-
-    private static final CarrierFactory factory = CarrierFactories.DUMB;
-
-    interface CarrierFactory {
-        MethodHandle constructor(MethodType methodType);
-        MethodHandle component(MethodType methodType, int component);
-    }
-
-    static class DumbCarrier {
-        private final Object[] args;
-
-        DumbCarrier(Object... args) {
-            this.args = args.clone();
-        }
-
-        Object get(int i) {
-            return args[i];
-        }
-    }
-
-    enum CarrierFactories implements CarrierFactory {
-        DUMB {
-            private final MethodHandle CARRIER_CTOR;
-            private final MethodHandle CARRIER_GET;
-
-            {
-                try {
-                    CARRIER_CTOR = MethodHandles.lookup().findConstructor(DumbCarrier.class, MethodType.methodType(void.class, Object[].class));
-                    CARRIER_GET = MethodHandles.lookup().findVirtual(DumbCarrier.class, "get", MethodType.methodType(Object.class, int.class));
-                }
-                catch (ReflectiveOperationException e) {
-                    throw new ExceptionInInitializerError(e);
-                }
-            }
-
-            @Override
-            public MethodHandle constructor(MethodType methodType) {
-                return CARRIER_CTOR.asType(methodType.changeReturnType(Object.class));
-            }
-
-            @Override
-            public MethodHandle component(MethodType methodType, int component) {
-                return MethodHandles.insertArguments(CARRIER_GET, 1, component)
-                                    .asType(MethodType.methodType(methodType.parameterType(component), Object.class));
-            }
-        },
-        DUMB_SINGLE {
-            // An optimization of DUMB, where we use the value itself as carrier when there is only one value
-
-            @Override
-            public MethodHandle constructor(MethodType methodType) {
-                return methodType.parameterCount() == 1 ? MethodHandles.identity(methodType.parameterType(0)) : DUMB.constructor(methodType);
-            }
-
-            @Override
-            public MethodHandle component(MethodType methodType, int component) {
-                return methodType.parameterCount() == 1 ? MethodHandles.identity(methodType.parameterType(0)) : DUMB.component(methodType, component);
-            }
-        }
-    }
-
-    /**
-     * Returns a method handle with the given method type that instantiates
-     * a new carrier object.
-     *
-     * @param methodType the types of the carrier elements
-     * @return the carrier factory
-     */
-    public static MethodHandle carrierFactory(MethodType methodType) {
-        return factory.constructor(methodType);
-    }
-
-    /**
-     * Returns a method handle that accepts a carrier and returns the i'th component
-     *
-     * @param methodType the type of the carrier elements
-     * @param i the index of the component
-     * @return the component method handle
-     */
-    public static MethodHandle carrierComponent(MethodType methodType, int i) {
-        return factory.component(methodType, i);
-    }
-
-    /**
-     * Return all the components method handles for a carrier
-     * @param methodType the type of the carrier elements
-     * @return the component method handles
-     */
-    public static List<MethodHandle> carrierComponents(MethodType methodType) {
-        MethodHandle[] components = new MethodHandle[methodType.parameterCount()];
-        Arrays.setAll(components, i -> factory.component(methodType, i));
-        return List.of(components);
-    }
-}
diff --git a/src/java.base/share/classes/java/lang/runtime/PatternHandle.java b/src/java.base/share/classes/java/lang/runtime/PatternHandle.java
deleted file mode 100755
index 907b9ebd7aa..00000000000
--- a/src/java.base/share/classes/java/lang/runtime/PatternHandle.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.runtime;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodType;
-import java.util.List;
-
-/**
- * Runtime object for low-level implementation of <em>pattern matching</em>. A
- * {@linkplain PatternHandle} exposes functionality for determining if a target
- * matches the pattern, and if so, for conditionally extracting the resulting
- * bindings.
- *
- * <p>A {@linkplain PatternHandle} is parameterized by a <em>target type</em>
- * and zero or more <em>binding variable types</em>. The target type (denoted
- * {@code T}) is the type against which the pattern can be applied (often a
- * broad type such as {@link Object}, but need not be), and the binding variable
- * types (denoted {@code B*}) are the types of the binding variables that are
- * produced by a successful match.  These types are combined into a type
- * <em>descriptor</em>, accessed via {@link #descriptor()}, where the return
- * type of the descriptor is the target type, and the parameter types of the
- * descriptor are the binding variable types.
- *
- * <p>The behavior of a {@linkplain PatternHandle} is exposed via method
- * handles.  The method handle returned by {@link #tryMatch()} is applied to the
- * target to be tested, and returns an opaque result of type {@code Object}.  If
- * the result is {@code null}, the match has failed; if is non-null, it has
- * succeeded, and the result can be used as input to the method handles returned
- * by {@link #components()} or {@link #component(int)} to retrieve specific
- * binding variables.
- *
- * <p>The class {@link PatternHandles} contains numerous factories and
- * combinators for {@linkplain PatternHandle}s, including {@link
- * PatternHandles#adaptTarget(PatternHandle, Class)} which can be used to adapt
- * a pattern handle from one target type to another (such as widening the set of
- * types against which it can be applied.)
- *
- * <p>{@linkplain PatternHandle} implementations must be <a
- * href="{@docRoot}/java.base/java/lang/doc-files/ValueBased.html">value-based</a>
- * classes.
- */
-public interface PatternHandle {
-
-    /**
-     * Returns a method handle that attempts to perform the pattern match
-     * described by this pattern handle.  It will have type {@code (T)Object},
-     * where {@code T} is the target type of the extractor. It accepts the
-     * target to be matched, and returns a non-null opaque carrier of type
-     * {@link Object} if the match succeeds, or {@code null} if it fails.
-     *
-     * @return the {@code tryMatch} method handle
-     */
-    MethodHandle tryMatch();
-
-    /**
-     * Returns a method handle that extracts a component from a successful
-     * match.  It will have type {@code (Object)Bi}, where {@code Bi} is the
-     * type of the corresponding binding variable, and will take the match
-     * carrier and return the corresponding binding variable.
-     *
-     * @param i the index of the component
-     * @return the component method handle
-     * @throws IndexOutOfBoundsException if {@code i} does not correspond to the
-     *                                   index of a binding variable of this
-     *                                   pattern
-     */
-    MethodHandle component(int i);
-
-    /**
-     * Returns all the component method handles for this pattern as a {@link
-     * List}.
-     *
-     * @return the component method handles
-     */
-    List<MethodHandle> components();
-
-    /**
-     * Returns the descriptor for this pattern.  The parameter types of the
-     * descriptor are the types of the binding variables, and the return type is
-     * the target type.
-     *
-     * @return the pattern type descriptor
-     */
-    MethodType descriptor();
-}
diff --git a/src/java.base/share/classes/java/lang/runtime/PatternHandles.java b/src/java.base/share/classes/java/lang/runtime/PatternHandles.java
deleted file mode 100755
index ee028b390f5..00000000000
--- a/src/java.base/share/classes/java/lang/runtime/PatternHandles.java
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.runtime;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-
-import sun.invoke.util.BytecodeName;
-import sun.invoke.util.Wrapper;
-
-import static java.lang.invoke.MethodHandleInfo.REF_invokeInterface;
-import static java.lang.invoke.MethodHandleInfo.REF_invokeStatic;
-import static java.lang.invoke.MethodHandleInfo.REF_invokeVirtual;
-import static java.lang.invoke.MethodHandleInfo.REF_newInvokeSpecial;
-import static java.util.Objects.requireNonNull;
-
-/**
- * Factories and combinators for {@link PatternHandle}s.
- */
-public final class PatternHandles {
-    private static final MethodHandle[] EMPTY_MH_ARRAY = new MethodHandle[0];
-    private static final Object NULL_SENTINEL = new Object();
-
-    private PatternHandles() {
-    }
-
-    // Factories
-
-    /**
-     * Returns a {@linkplain PatternHandle} for a <em>type pattern</em>, which
-     * matches all non-null instances of the match type, with a single binding
-     * variable which is the target cast to the match type.  The target type of
-     * the resulting pattern is the match type; if a broader target type is
-     * desired, use {@link #ofType(Class, Class)} or adapt the resulting pattern
-     * handle with {@link #adaptTarget(PatternHandle, Class)}.
-     *
-     * @param matchType the type to match against
-     * @return a pattern handle for a type pattern
-     */
-    public static PatternHandle ofType(Class<?> matchType) {
-        requireNonNull(matchType);
-        MethodType descriptor = MethodType.methodType(matchType, matchType);
-        MethodHandle component = MethodHandles.identity(matchType);
-        MethodHandle tryMatch
-                = matchType.isPrimitive()
-                  ? MethodHandles.identity(matchType)
-                  : MH_OF_TYPE_TRY_MATCH.bindTo(matchType).asType(descriptor);
-
-        return new PatternHandleImpl(descriptor, tryMatch, List.of(component));
-    }
-
-    /**
-     * Returns a {@linkplain PatternHandle} for a <em>type pattern</em>, which
-     * matches all non-null instances of the match type, with a single binding
-     * variable which is the target cast to the match type.  The target type of
-     * the resulting pattern is the {@code targetType}.
-     *
-     * @param matchType  the type to match against
-     * @param targetType the desired target type for the resulting pattern
-     *                   handle
-     * @return a pattern handle for a type pattern
-     * @throws IllegalArgumentException if the provided match type and target
-     *                                  type are not compatible
-     */
-    public static PatternHandle ofType(Class<?> matchType, Class<?> targetType) {
-        return adaptTarget(ofType(matchType), targetType);
-    }
-
-    /**
-     * Returns a {@linkplain PatternHandle} for a <em>nullable type
-     * pattern</em>, which matches all instances of the match type, plus {@code
-     * null}, with a single binding variable which is the target cast to the
-     * match type.  The target type of the resulting pattern is the match type;
-     * if a broader target type is desired, use {@link #ofType(Class, Class)} or
-     * adapt the resulting pattern handle with {@link #adaptTarget(PatternHandle,
-     * Class)}.
-     *
-     * @param matchType the type to match against
-     * @return a pattern handle for a nullable type pattern
-     */
-    public static PatternHandle ofTypeNullable(Class<?> matchType) {
-        requireNonNull(matchType);
-        MethodType descriptor = MethodType.methodType(matchType, matchType);
-        MethodHandle component = MH_OF_TYPE_NULLABLE_COMPONENT
-                .asType(MethodType.methodType(matchType, Object.class));
-        MethodHandle tryMatch
-                = matchType.isPrimitive()
-                  ? MethodHandles.identity(matchType)
-                  : MH_OF_TYPE_NULLABLE_TRY_MATCH.bindTo(matchType)
-                                                 .asType(MethodType.methodType(Object.class, matchType));
-
-        return new PatternHandleImpl(descriptor, tryMatch, List.of(component));
-    }
-
-    /**
-     * Returns a {@linkplain PatternHandle} for a <em>nullable type
-     * pattern</em>, which matches all instances of the match type, plus {@code
-     * null}, with a single binding variable which is the target cast to the
-     * match type.  The target type of the resulting pattern is the {@code
-     * targetType}.
-     *
-     * @param matchType  the type to match against
-     * @param targetType the desired target type for the resulting pattern
-     *                   handle
-     * @return a pattern handle for a nullable type pattern
-     * @throws IllegalArgumentException if the provided match type and target
-     *                                  type are not compatible
-     */
-    public static PatternHandle ofTypeNullable(Class<?> matchType, Class<?> targetType) {
-        return adaptTarget(ofTypeNullable(matchType), targetType);
-    }
-
-    /**
-     * Returns a {@linkplain PatternHandle} for a <em>constant pattern</em>,
-     * which matches all instances that are {@link Object#equals(Object)} to
-     * the specified constant.  The resulting pattern has no binding variables.
-     * If the constant is {@code null}, the target type of the pattern is
-     * {@link Object}, otherwise it is the result of {@code Object::getClass}
-     * on the constant.
-     *
-     * <p>TODO: restrict type of constant to String, boxes, and enums?
-     *
-     * @param o the constant
-     * @return a pattern handle for a constant pattern
-     */
-    public static PatternHandle ofConstant(Object o) {
-        Class<?> type = o == null ? Object.class : o.getClass();
-        MethodHandle match = partialize(MethodHandles.dropArguments(MethodHandles.constant(Object.class, Boolean.TRUE), 0, type),
-                                        MethodHandles.insertArguments(MH_OBJECTS_EQUAL, 0, o)
-                                                     .asType(MethodType.methodType(boolean.class, type)));
-        return new PatternHandleImpl(MethodType.methodType(type), match, List.of());
-    }
-
-    /**
-     * Returns a {@linkplain PatternHandle} for a <em>constant pattern</em>,
-     * which matches all instances that are {@link Object#equals(Object)} to
-     * the specified constant.  The resulting pattern has no binding variables.
-     * The target type of the pattern is {@code targetType}.
-     *
-     * @param o the constant
-     * @param targetType the target type for the pattern
-     * @return a pattern handle for a constant pattern
-     * @throws IllegalArgumentException if the type of the constant and the
-     * target type are not compatible
-     */
-    public static PatternHandle ofConstant(Object o, Class<?> targetType) {
-        return adaptTarget(ofConstant(0), targetType);
-    }
-
-    // @@@ Primitive constant patterns
-
-    /**
-     * Returns a {@linkplain PatternHandle} for decomposing a target into its
-     * components.  It matches all non-null instances of the specified target
-     * type, and extracts one binding variable for each component specified in
-     * the {@code components} argument.  The method handles in {@code components}
-     * must be of type {@code (T)Bi} where T is the target type of the pattern
-     * and Bi is the i'th binding variable.  The components are extracted
-     * <em>lazily</em> -- when the component method handle is invoked by the
-     * client -- rather than when the {@code tryMatch} method handle is invoked.
-     *
-     * @param targetType The type of the match target
-     * @param components The component method handles
-     * @return a pattern handle for a decomposition pattern
-     */
-    public static PatternHandle ofLazyProjection(Class<?> targetType,
-                                                 MethodHandle... components) {
-        requireNonNull(targetType);
-        requireNonNull(components);
-        return new PatternHandleImpl(descriptor(targetType, components),
-                                     MethodHandles.identity(targetType),
-                                     List.of(components));
-    }
-
-    /**
-     * Returns a {@linkplain PatternHandle} for decomposing a target into its
-     * components.  It matches all non-null instances of the specified target
-     * type, and extracts one binding variable for each component specified in
-     * the {@code components} argument.  The method handles in {@code components}
-     * must be of type {@code (T)Bi} where T is the target type of the pattern
-     * and Bi is the i'th binding variable.  The components are extracted
-     * <em>eagerly</em> -- at the time the {@code tryMatch} method handle is
-     * invoked.
-     *
-     * @param targetType The type of the match target
-     * @param components The component method handles
-     * @return a pattern handle for a decomposition pattern
-     */
-    public static PatternHandle ofEagerProjection(Class<?> targetType,
-                                                  MethodHandle... components) {
-        requireNonNull(targetType);
-        requireNonNull(components);
-        MethodType descriptor = descriptor(targetType, components);
-        return new PatternHandleImpl(descriptor,
-                                     carrierTryExtract(descriptor, components),
-                                     PatternCarriers.carrierComponents(descriptor));
-    }
-
-    /**
-     * Returns a {@linkplain PatternHandle} that delegates matching and
-     * extraction to another method handle.  The target type of the pattern is
-     * the return type of the {@code descriptor}, and the binding variable types
-     * are the parameter types of the {@code descriptor}.  The {@code tryMatch}
-     * method handle will invoke the specified {@code digester} method handle
-     * with the target, as well as a method handle whose parameter types are
-     * the binding variable types and whose return type is some type {@code C}.
-     * For a successful match, the digester method should invoke this method
-     * handle with the extracted bindings, and return the result; for an
-     * unsuccessful match, it should return {@code null}.
-     *
-     * @param descriptor the type descriptor of the pattern
-     * @param digester   the digester method handle
-     * @return a pattern handle implementing the pattern
-     */
-    public static PatternHandle ofImperative(MethodType descriptor,
-                                             MethodHandle digester) {
-        Class<?> targetType = descriptor.returnType();
-        return new PatternHandleImpl(descriptor,
-                                     partialize(MethodHandles.insertArguments(digester,
-                                                                              1, PatternCarriers.carrierFactory(descriptor)),
-                                                MH_OBJECTS_NONNULL.asType(MH_OBJECTS_NONNULL.type().changeParameterType(0, targetType))),
-                                     PatternCarriers.carrierComponents(descriptor));
-    }
-
-    /**
-     * Compose a pattern handle with a method handle that receives the bindings. The
-     * argument types of the target method must match those of the binding
-     * types.  The resulting method handle accepts an argument which is the
-     * target type of the pattern, and which returns either {@code null}
-     * if the match fails or the result of the target method handle
-     * if the match succeeds.
-     *
-     * @param patternHandle the pattern handle
-     * @param target        a method handle that receives the bindings and
-     *                      produces a result
-     * @return the composed method handle
-     */
-    public static MethodHandle compose(PatternHandle patternHandle, MethodHandle target) {
-        int count = patternHandle.descriptor().parameterCount();
-        MethodHandle[] components = patternHandle.components().toArray(EMPTY_MH_ARRAY);
-        Class<?> carrierType = patternHandle.tryMatch().type().returnType();
-        Class<?> resultType = target.type().returnType();
-
-        MethodHandle mh = MethodHandles.filterArguments(target, 0, components);
-        mh = MethodHandles.permuteArguments(mh, MethodType.methodType(resultType, carrierType), new int[count]);
-        mh = MethodHandles.guardWithTest(MH_OBJECTS_NONNULL.asType(MethodType.methodType(boolean.class, carrierType)),
-                                         mh,
-                                         MethodHandles.dropArguments(MethodHandles.constant(resultType, null), 0, carrierType));
-        mh = MethodHandles.filterArguments(mh, 0, patternHandle.tryMatch());
-        return mh;
-    }
-
-    // Combinators
-
-    /**
-     * Adapts a {@linkplain PatternHandle} to a new target type.  If the
-     * pattern is of primitive type, it may be adapted to a supertype of its
-     * corresponding box type; if it is of reference type, it may be widened
-     * or narrowed to another reference type.
-     *
-     * @param pattern the pattern
-     * @param newTarget the new target type
-     * @return the adapted pattern
-     * @throws IllegalArgumentException if the new target type is not compatible
-     * with the target type of the pattern
-     */
-    public static PatternHandle adaptTarget(PatternHandle pattern, Class<?> newTarget) {
-        Class<?> oldTarget = pattern.descriptor().returnType();
-        if (oldTarget == newTarget)
-            return pattern;
-
-        Class<?> oldWrapperType = oldTarget.isPrimitive() ? Wrapper.forPrimitiveType(oldTarget).wrapperType() : null;
-        MethodType guardType = MethodType.methodType(boolean.class, newTarget);
-        MethodHandle guard;
-        if (oldWrapperType != null && newTarget.isAssignableFrom(oldWrapperType)) {
-            // Primitive boxing (with optional widening)
-            guard = MH_PRIMITIVE_ADAPT_HELPER.bindTo(oldWrapperType).asType(guardType);
-        }
-        else if (newTarget.isAssignableFrom(oldTarget) || oldTarget.isAssignableFrom(newTarget)) {
-            // reference narrowing or widening
-            guard = MH_REFERENCE_ADAPT_HELPER.bindTo(oldTarget).asType(guardType);
-        }
-        else {
-            throw new IllegalArgumentException(String.format("New target type %s not compatible with old target type %s",
-                                                             newTarget, oldTarget));
-        }
-
-        MethodType tryMatchType = pattern.tryMatch().type().changeParameterType(0, newTarget);
-        return new PatternHandleImpl(pattern.descriptor().changeReturnType(newTarget),
-                                     partialize(pattern.tryMatch().asType(tryMatchType),
-                                                guard),
-                                     pattern.components());
-    }
-
-    /**
-     * Returns a {@linkplain PatternHandle} that implements the same pattern
-     * as another {@linkplain PatternHandle}, but potentially with fewer binding
-     * variables.
-     *
-     * @param pattern the original pattern
-     * @param positions the indexes of the binding variables to drop
-     * @return the new pattern
-     * @throws IndexOutOfBoundsException if any of the indexes are out of range
-     * for the bindings of the original pattern
-     */
-    public static PatternHandle dropBindings(PatternHandle pattern, int... positions) {
-        MethodHandle[] mhs = pattern.components().toArray(EMPTY_MH_ARRAY);
-        for (int position : positions)
-            mhs[position] = null;
-        mhs = Stream.of(mhs).filter(Objects::nonNull).toArray(MethodHandle[]::new);
-        return new PatternHandleImpl(descriptor(pattern.descriptor().returnType(), mhs), pattern.tryMatch(), List.of(mhs));
-    }
-
-    /**
-     * Returns a {@linkplain PatternHandle} for a <em>nested</em> pattern.  A
-     * nested pattern first matches the target to the outer pattern, and if
-     * it matches successfully, then matches the resulting bindings to the inner
-     * patterns.  The resulting pattern matches if the outer pattern matches
-     * the target, and the bindings match the appropriate inner patterns.  The
-     * target type of the nested pattern is the same as the target type of
-     * the outer pattern.  The bindings are the bindings for the outer pattern,
-     * followed by the concatenation of the bindings for the inner patterns.
-     *
-     * @param outer  The outer pattern
-     * @param inners The inner patterns, which can be null if no nested pattern
-     *               for the corresponding binding is desired
-     * @return the nested pattern
-     */
-    public static PatternHandle nested(PatternHandle outer, PatternHandle... inners) {
-        PatternHandle[] patternHandles = inners.clone();
-        int outerCount = outer.descriptor().parameterCount();
-        Class<?> outerCarrierType = outer.tryMatch().type().returnType();
-
-        // Adapt inners to types of outer bindings
-        for (int i = 0; i < patternHandles.length; i++) {
-            PatternHandle patternHandle = patternHandles[i];
-            if (patternHandle.descriptor().returnType() != outer.descriptor().parameterType(i))
-                patternHandles[i] = adaptTarget(patternHandle, outer.descriptor().parameterType(i));
-        }
-
-        int[] innerPositions = IntStream.range(0, patternHandles.length)
-                                        .filter(i -> patternHandles[i] != null)
-                                        .toArray();
-        MethodHandle[] innerComponents = Stream.of(patternHandles)
-                                               .filter(Objects::nonNull)
-                                               .map(PatternHandle::components)
-                                               .flatMap(List::stream)
-                                               .toArray(MethodHandle[]::new);
-        MethodHandle[] innerTryMatches = Stream.of(patternHandles)
-                                               .filter(Objects::nonNull)
-                                               .map(PatternHandle::tryMatch)
-                                               .toArray(MethodHandle[]::new);
-        Class<?>[] innerCarriers = Stream.of(patternHandles)
-                                         .filter(Objects::nonNull)
-                                         .map(e -> e.tryMatch().type().returnType())
-                                         .toArray(Class[]::new);
-        Class<?>[] innerTypes = Stream.of(innerComponents)
-                                      .map(mh -> mh.type().returnType())
-                                      .toArray(Class[]::new);
-
-        MethodType descriptor = outer.descriptor().appendParameterTypes(innerTypes);
-
-        MethodHandle mh = PatternCarriers.carrierFactory(descriptor);
-        mh = MethodHandles.filterArguments(mh, outerCount, innerComponents);
-        int[] spreadInnerCarriers = new int[outerCount + innerComponents.length];
-        for (int i = 0; i < outerCount; i++)
-            spreadInnerCarriers[i] = i;
-        int k = outerCount;
-        int j = 0;
-        for (PatternHandle e : patternHandles) {
-            if (e == null)
-                continue;
-            for (int i = 0; i < e.descriptor().parameterCount(); i++)
-                spreadInnerCarriers[k++] = outerCount + j;
-            j++;
-        }
-        MethodType spreadInnerCarriersMT = outer.descriptor()
-                                                .appendParameterTypes(innerCarriers)
-                                                .changeReturnType(mh.type().returnType());
-        mh = MethodHandles.permuteArguments(mh, spreadInnerCarriersMT, spreadInnerCarriers);
-        for (int position : innerPositions)
-            mh = bailIfNthNull(mh, outerCount + position);
-        mh = MethodHandles.filterArguments(mh, outerCount, innerTryMatches);
-        int[] spreadNestedCarrier = new int[outerCount + innerPositions.length];
-        for (int i = 0; i < outerCount; i++)
-            spreadNestedCarrier[i] = i;
-        for (int i = 0; i < innerPositions.length; i++)
-            spreadNestedCarrier[outerCount + i] = innerPositions[i];
-        mh = MethodHandles.permuteArguments(mh, outer.descriptor().changeReturnType(mh.type().returnType()),
-                                            spreadNestedCarrier);
-        mh = MethodHandles.filterArguments(mh, 0, outer.components().toArray(EMPTY_MH_ARRAY));
-        mh = MethodHandles.permuteArguments(mh, MethodType.methodType(mh.type().returnType(), outerCarrierType),
-                                            new int[outerCount]);
-        mh = bailIfNthNull(mh, 0);
-        mh = MethodHandles.filterArguments(mh, 0, outer.tryMatch());
-
-        MethodHandle tryExtract = mh;
-
-        return new PatternHandleImpl(descriptor, tryExtract, PatternCarriers.carrierComponents(descriptor));
-    }
-
-    // @@@ AND combinator
-    // @@@ GUARDED combinator
-
-    // Bootstraps
-
-    /**
-     * Bootstrap method for creating a lazy projection pattern, as per
-     * {@link #ofLazyProjection(Class, MethodHandle...)},
-     * suitable for use as a {@code constantdynamic} bootstrap.  Suitable for use
-     * by compilers which are generating implementations of patterns whose bindings
-     * are independently derived from the target.
-     *
-     * @apiNote When the "bootstrap consolidation" project completes, this method
-     * can go away and {@link #ofLazyProjection(Class, MethodHandle...)}
-     * can be used directly as a condy bootstrap.
-     *
-     * @param lookup       ignored
-     * @param constantName ignored
-     * @param constantType Must be {@code PatternHandle.class}
-     * @param targetType   the target type of the pattern
-     * @param components   the pattern components
-     * @return a pattern handle
-     * @throws Throwable doc
-     */
-    public static PatternHandle ofLazyProjection(MethodHandles.Lookup lookup,
-                                                 String constantName,
-                                                 Class<?> constantType,
-                                                 Class<?> targetType,
-                                                 MethodHandle... components)
-            throws Throwable {
-        return ofLazyProjection(targetType, components);
-    }
-
-    /**
-     * Bootstrap method for finding named {@link PatternHandle}s that have been
-     * compiled according to the scheme outlined in JLS ?.?.
-     *
-     * @param lookup       the lookup context
-     * @param constantName ignored
-     * @param constantType must be {@code PatternHandle.class}
-     * @param owner        the class containing the pattern
-     * @param descriptor   the extractor descriptor
-     * @param name         the extractor name
-     * @param refKind      the kind of method
-     * @return the extractor
-     * @throws Throwable if something went wrong
-     */
-    public static PatternHandle ofNamed(MethodHandles.Lookup lookup,
-                                        String constantName,
-                                        Class<PatternHandle> constantType,
-                                        Class<?> owner,
-                                        MethodType descriptor,
-                                        String name,
-                                        int refKind) throws Throwable {
-        String dd = descriptor.toMethodDescriptorString();
-        String memberName = String.format("$pattern$%s$%s",
-                                      (refKind == REF_newInvokeSpecial ? owner.getSimpleName() : name),
-                                      dd.substring(0, dd.indexOf(')') + 1));
-        String patternMethodName = BytecodeName.toBytecodeName(memberName);
-        MethodType factoryDesc = MethodType.methodType(PatternHandle.class);
-        MethodHandle mh;
-        switch (refKind) {
-            case REF_invokeStatic:
-            case REF_newInvokeSpecial:
-                mh = lookup.findStatic(owner, patternMethodName, factoryDesc);
-                break;
-            case REF_invokeVirtual:
-            case REF_invokeInterface:
-                mh = lookup.findVirtual(owner, patternMethodName, factoryDesc);
-                break;
-            default:
-                throw new IllegalAccessException(Integer.toString(refKind));
-        }
-
-        return (PatternHandle) mh.invoke();
-    }
-
-    /**
-     * Bootstrap method for extracting the {@code tryMatch} method handle from a
-     * {@linkplain PatternHandle}.
-     *
-     * @apiNote When the "bootstrap consolidation" project completes, this method
-     * can go away and {@link PatternHandle#tryMatch()} can be used directly as
-     * a condy bootstrap.
-     *
-     * @param lookup        ignored
-     * @param constantName  ignored
-     * @param constantType  Must be {@code MethodHandle.class}
-     * @param patternHandle the pattern handle
-     * @return the {@code tryMatch} method handle
-     */
-    public static MethodHandle tryMatch(MethodHandles.Lookup lookup, String constantName, Class<MethodHandle> constantType,
-                                        PatternHandle patternHandle) {
-        return patternHandle.tryMatch();
-    }
-
-    /**
-     * Bootstrap method for extracting a {@code component} method handle from a
-     * {@linkplain PatternHandle}.
-     *
-     * @apiNote When the "bootstrap consolidation" project completes, this method
-     * can go away and {@link PatternHandle#component(int)} ()} can be used directly as
-     * a condy bootstrap.
-     *
-     * @param lookup        ignored
-     * @param constantName  ignored
-     * @param constantType  Must be {@code MethodHandle.class}
-     * @param patternHandle the pattern
-     * @param i the index of the desired component
-     * @return the component method handle
-     */
-    public static MethodHandle component(MethodHandles.Lookup lookup,
-                                         String constantName,
-                                         Class<MethodHandle> constantType,
-                                         PatternHandle patternHandle, int i) {
-        return patternHandle.component(i);
-    }
-
-    // Helpers
-
-    /**
-     * Construct a partial method handle that uses the predicate as
-     * guardWithTest, which applies the target if the test succeeds, and returns
-     * null if the test fails.  The resulting method handle is of the same type
-     * as the {@code target} method handle.
-     *
-     * @param target
-     * @param predicate
-     * @return
-     */
-    private static MethodHandle partialize(MethodHandle target,
-                                           MethodHandle predicate) {
-        Class<?> targetType = target.type().parameterType(0);
-        Class<?> carrierType = target.type().returnType();
-        return MethodHandles.guardWithTest(predicate,
-                                           target,
-                                           MethodHandles.dropArguments(MethodHandles.constant(carrierType, null),
-                                                                       0, targetType));
-    }
-
-    /**
-     * Construct a method handle that delegates to target, unless the nth
-     * argument is null, in which case it returns null
-     */
-    private static MethodHandle bailIfNthNull(MethodHandle target, int n) {
-        MethodHandle test = MH_OBJECTS_ISNULL
-                .asType(MH_OBJECTS_ISNULL.type()
-                                         .changeParameterType(0, target.type().parameterType(n)));
-        test = MethodHandles.permuteArguments(test, target.type().changeReturnType(boolean.class), n);
-        MethodHandle nullh = MethodHandles.dropArguments(MethodHandles.constant(target.type().returnType(), null),
-                                                         0, target.type().parameterArray());
-        return MethodHandles.guardWithTest(test, nullh, target);
-    }
-
-    private static MethodType descriptor(Class<?> targetType, MethodHandle[] components) {
-        Class<?>[] paramTypes = Stream.of(components)
-                                      .map(mh -> mh.type().returnType())
-                                      .toArray(Class[]::new);
-        return MethodType.methodType(targetType, paramTypes);
-    }
-
-    private static MethodHandle carrierTryExtract(MethodType descriptor, MethodHandle[] components) {
-        MethodHandle carrierFactory = PatternCarriers.carrierFactory(descriptor);
-        int[] reorder = new int[descriptor.parameterCount()]; // default value is what we want already
-
-        Class<?> targetType = descriptor.returnType();
-        return partialize(MethodHandles.permuteArguments(MethodHandles.filterArguments(carrierFactory, 0, components),
-                                                         MethodType.methodType(carrierFactory.type().returnType(), targetType),
-                                                         reorder),
-                          MH_OBJECTS_NONNULL.asType(MH_OBJECTS_NONNULL.type().changeParameterType(0, targetType)));
-    }
-
-    private static MethodHandle lookupStatic(Class<?> clazz,
-                                             String name,
-                                             Class<?> returnType,
-                                             Class<?>... paramTypes)
-            throws ExceptionInInitializerError {
-        try {
-            return MethodHandles.lookup().findStatic(clazz, name, MethodType.methodType(returnType, paramTypes));
-        }
-        catch (ReflectiveOperationException e) {
-            throw new ExceptionInInitializerError(e);
-        }
-    }
-
-    private static final MethodHandle MH_OF_TYPE_TRY_MATCH
-            = lookupStatic(PatternHandles.class, "ofTypeTryMatch",
-                           Object.class, Class.class, Object.class);
-    private static final MethodHandle MH_OF_TYPE_NULLABLE_TRY_MATCH
-            = lookupStatic(PatternHandles.class, "ofTypeNullableTryMatch",
-                           Object.class, Class.class, Object.class);
-    private static final MethodHandle MH_OF_TYPE_NULLABLE_COMPONENT
-            = lookupStatic(PatternHandles.class, "ofTypeNullableComponent",
-                           Object.class, Object.class);
-    private static final MethodHandle MH_PRIMITIVE_ADAPT_HELPER
-            = lookupStatic(PatternHandles.class, "primitiveAdaptHelper",
-                           boolean.class, Class.class, Object.class);
-    private static final MethodHandle MH_REFERENCE_ADAPT_HELPER
-            = lookupStatic(PatternHandles.class, "referenceAdaptHelper",
-                           boolean.class, Class.class, Object.class);
-    private static final MethodHandle MH_OBJECTS_ISNULL
-            = lookupStatic(Objects.class, "isNull",
-                           boolean.class, Object.class);
-    private static final MethodHandle MH_OBJECTS_NONNULL
-            = lookupStatic(Objects.class, "nonNull",
-                           boolean.class, Object.class);
-    private static final MethodHandle MH_OBJECTS_EQUAL
-            = lookupStatic(Objects.class, "equals",
-                           boolean.class, Object.class, Object.class);
-
-    private static Object ofTypeTryMatch(Class<?> type, Object o) {
-        return o != null && type.isAssignableFrom(o.getClass())
-               ? o
-               : null;
-    }
-
-    private static Object ofTypeNullableTryMatch(Class<?> type, Object o) {
-        if (o == null)
-            return NULL_SENTINEL;
-        else if (type.isAssignableFrom(o.getClass()))
-            return o;
-        else
-            return null;
-    }
-
-    private static Object ofTypeNullableComponent(Object o) {
-        return o == NULL_SENTINEL ? null : o;
-    }
-
-    private static boolean primitiveAdaptHelper(Class<?> type, Object o) {
-        return o != null && type.isAssignableFrom(o.getClass());
-    }
-
-    private static boolean referenceAdaptHelper(Class<?> type, Object o) {
-        return o == null || type.isAssignableFrom(o.getClass());
-    }
-
-    /**
-     * Non-public implementation of {@link PatternHandle}
-     */
-    private static class PatternHandleImpl implements PatternHandle {
-
-        private final MethodType descriptor;
-        private final MethodHandle tryMatch;
-        private final List<MethodHandle> components;
-
-
-        /**
-         * Construct an {@link PatternHandle} from components Constraints: -
-         * output of tryMatch must match input of components - input of tryMatch
-         * must match descriptor - output of components must match descriptor
-         *
-         * @param descriptor The {@code descriptor} method type
-         * @param tryMatch   The {@code tryMatch} method handle
-         * @param components The {@code component} method handles
-         */
-        PatternHandleImpl(MethodType descriptor, MethodHandle tryMatch,
-                          List<MethodHandle> components) {
-            MethodHandle[] componentsArray = components.toArray(new MethodHandle[0]);
-            Class<?> carrierType = tryMatch.type().returnType();
-            if (descriptor.parameterCount() != componentsArray.length)
-                throw new IllegalArgumentException(String.format("MethodType %s arity should match component count %d",
-                                                                 descriptor, componentsArray.length));
-            if (!descriptor.returnType().equals(tryMatch.type().parameterType(0)))
-                throw new IllegalArgumentException(String.format("Descriptor %s should match tryMatch input %s",
-                                                                 descriptor, tryMatch.type()));
-            for (int i = 0; i < componentsArray.length; i++) {
-                MethodType componentType = componentsArray[i].type();
-                if (componentType.parameterCount() != 1
-                    || componentType.returnType().equals(void.class)
-                    || !componentType.parameterType(0).equals(carrierType))
-                    throw new IllegalArgumentException("Invalid component descriptor " + componentType);
-                if (!componentType.returnType().equals(descriptor.parameterType(i)))
-                    throw new IllegalArgumentException(String.format("Descriptor %s should match %d'th component %s",
-                                                                     descriptor, i, componentsArray[i]));
-            }
-
-            if (!carrierType.equals(Object.class)) {
-                tryMatch = tryMatch.asType(tryMatch.type().changeReturnType(Object.class));
-                for (int i = 0; i < componentsArray.length; i++) {
-                    MethodHandle component = componentsArray[i];
-                    componentsArray[i] = component.asType(component.type().changeParameterType(0, Object.class));
-                }
-            }
-
-            this.descriptor = descriptor;
-            this.tryMatch = tryMatch;
-            this.components = List.of(componentsArray);
-        }
-
-        @Override
-        public MethodHandle tryMatch() {
-            return tryMatch;
-        }
-
-        @Override
-        public MethodHandle component(int i) {
-            return components.get(i);
-        }
-
-        @Override
-        public List<MethodHandle> components() {
-            return components;
-        }
-
-        @Override
-        public MethodType descriptor() {
-            return descriptor;
-        }
-
-    }
-}
diff --git a/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java b/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java
deleted file mode 100755
index f68d82f6495..00000000000
--- a/src/java.base/share/classes/java/lang/runtime/SwitchBootstraps.java
+++ /dev/null
@@ -1,882 +0,0 @@
-/*
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- * 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.runtime;
-
-import java.lang.invoke.CallSite;
-import java.lang.invoke.ConstantCallSite;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Function;
-import java.util.stream.IntStream;
-import java.util.stream.LongStream;
-import java.util.stream.Stream;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * Bootstrap methods for linking {@code invokedynamic} call sites that implement
- * the selection functionality of the {@code switch} statement.  The bootstraps
- * take additional static arguments corresponding to the {@code case} labels
- * of the {@code switch}, implicitly numbered sequentially from {@code [0..N)}.
- *
- * <p>The bootstrap call site accepts a single parameter of the type of the
- * operand of the {@code switch}, and return an {@code int} that is the index of
- * the matched {@code case} label, {@code -1} if the target is {@code null},
- * or {@code N} if the target is not null but matches no {@code case} label.
- */
-public class SwitchBootstraps {
-
-    // Shared INIT_HOOK for all switch call sites; looks the target method up in a map
-    private static final MethodHandle CONSTANT_INIT_HOOK;
-    private static final MethodHandle PATTERN_INIT_HOOK;
-    private static final MethodHandle TYPE_INIT_HOOK;
-    private static final MethodHandle PATTERN_SWITCH_METHOD;
-    private static final MethodHandle TYPE_SWITCH_METHOD;
-    private static final Map<Class<?>, MethodHandle> switchMethods = new ConcurrentHashMap<>();
-
-    private static final Set<Class<?>> BOOLEAN_TYPES
-            = Set.of(boolean.class, Boolean.class);
-    // Types that can be handled as int switches
-    private static final Set<Class<?>> INT_TYPES
-            = Set.of(int.class, short.class, byte.class, char.class,
-                     Integer.class, Short.class, Byte.class, Character.class);
-    private static final Set<Class<?>> FLOAT_TYPES
-            = Set.of(float.class, Float.class);
-    private static final Set<Class<?>> LONG_TYPES
-            = Set.of(long.class, Long.class);
-    private static final Set<Class<?>> DOUBLE_TYPES
-            = Set.of(double.class, Double.class);
-
-    private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
-    private static final Function<Class<?>, MethodHandle> lookupSwitchMethod =
-            new Function<>() {
-                @Override
-                public MethodHandle apply(Class<?> c) {
-                    try {
-                        Class<?> switchClass;
-                        if (c == Enum.class)
-                            switchClass = EnumSwitchCallSite.class;
-                        else if (c == String.class)
-                            switchClass = StringSwitchCallSite.class;
-                        else if (BOOLEAN_TYPES.contains(c) || INT_TYPES.contains(c) ||
-                                 FLOAT_TYPES.contains(c))
-                            switchClass = IntSwitchCallSite.class;
-                        else if (LONG_TYPES.contains(c) || DOUBLE_TYPES.contains(c))
-                            switchClass = LongSwitchCallSite.class;
-                        else if (c == Object.class)
-                            switchClass = TypeSwitchCallSite.class;
-                        else
-                            throw new BootstrapMethodError("Invalid switch type: " + c);
-
-                        return LOOKUP.findVirtual(switchClass, "doSwitch",
-                                                  MethodType.methodType(int.class, c));
-                    }
-                    catch (ReflectiveOperationException e) {
-                        throw new BootstrapMethodError("Invalid switch type: " + c);
-                    }
-                }
-            };
-
-    static {
-        try {
-            CONSTANT_INIT_HOOK = LOOKUP.findStatic(SwitchBootstraps.class, "constantInitHook",
-                                                   MethodType.methodType(MethodHandle.class, CallSite.class));
-            PATTERN_INIT_HOOK = LOOKUP.findStatic(SwitchBootstraps.class, "patternInitHook",
-                                                  MethodType.methodType(MethodHandle.class, CallSite.class));
-            TYPE_INIT_HOOK = LOOKUP.findStatic(SwitchBootstraps.class, "typeInitHook",
-                                                  MethodType.methodType(MethodHandle.class, CallSite.class));
-            PATTERN_SWITCH_METHOD = LOOKUP.findVirtual(PatternSwitchCallSite.class, "doSwitch",
-                                                       MethodType.methodType(PatternSwitchResult.class, Object.class));
-            TYPE_SWITCH_METHOD = LOOKUP.findVirtual(TypeSwitchCallSite.class, "doSwitch",
-                                                    MethodType.methodType(int.class, Object.class));
-        }
-        catch (ReflectiveOperationException e) {
-            throw new ExceptionInInitializerError(e);
-        }
-    }
-
-    private static<T extends CallSite> MethodHandle constantInitHook(T receiver) {
-        return switchMethods.computeIfAbsent(receiver.type().parameterType(0), lookupSwitchMethod)
-                            .bindTo(receiver);
-    }
-
-    private static<T extends CallSite> MethodHandle typeInitHook(T receiver) {
-        return TYPE_SWITCH_METHOD.bindTo(receiver);
-    }
-
-    private static<T extends CallSite> MethodHandle patternInitHook(T receiver) {
-        return PATTERN_SWITCH_METHOD.bindTo(receiver);
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on a {@code boolean} or {@code Boolean}.
-     * The static arguments are a varargs array of {@code boolean} labels,
-     *
-     * <p>The results are undefined if the labels array contains duplicates.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter which is
-     *                       {@code boolean} or {@code Boolean},and return {@code int}.
-     *                       When used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param booleanLabels boolean values corresponding to the case labels of the
-     *                  {@code switch} statement.
-     * @return the index into {@code booleanLabels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code booleanLabels.length} if the target value does
-     *         not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if the invocation type is not
-     * {@code (boolean)int} or {@code (Boolean)int}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite booleanSwitch(MethodHandles.Lookup lookup,
-                                         String invocationName,
-                                         MethodType invocationType,
-                                         boolean... booleanLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!BOOLEAN_TYPES.contains(invocationType.parameterType(0))))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(booleanLabels);
-
-        int[] intLabels = IntStream.range(0, booleanLabels.length)
-                                   .map(i -> booleanLabels[i] ? 1 : 0)
-                                   .toArray();
-
-        assert IntStream.of(intLabels).distinct().count() == intLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(booleanLabels);
-
-        return new IntSwitchCallSite(invocationType, intLabels);
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on an {@code int}, {@code short}, {@code byte},
-     * {@code char}, or one of their box types.  The static arguments are a
-     * varargs array of {@code int} labels.
-     *
-     * <p>The results are undefined if the labels array contains duplicates.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter which is
-     *                       one of the 32-bit or shorter primitive types, or
-     *                       one of their box types, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param intLabels integral values corresponding to the case labels of the
-     *                  {@code switch} statement.
-     * @return the index into {@code intLabels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code intLabels.length} if the target value does
-     *         not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if the invocation type is not
-     * {@code (T)int}, where {@code T} is one of the 32-bit or smaller integral
-     * primitive types, or one of their box types
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite intSwitch(MethodHandles.Lookup lookup,
-                                     String invocationName,
-                                     MethodType invocationType,
-                                     int... intLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!INT_TYPES.contains(invocationType.parameterType(0))))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(intLabels);
-
-        assert IntStream.of(intLabels).distinct().count() == intLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(intLabels);
-
-        return new IntSwitchCallSite(invocationType, intLabels);
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on an {@code float} or {@code Float}.
-     * The static arguments are a varargs array of {@code float} labels.
-     *
-     * <p>The results are undefined if the labels array contains duplicates
-     * according to {@link Float#floatToIntBits(float)}.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter which is
-     *                       one of the 32-bit or shorter primitive types, or
-     *                       one of their box types, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param floatLabels float values corresponding to the case labels of the
-     *                    {@code switch} statement.
-     * @return the index into {@code floatLabels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code floatLabels.length} if the target value does
-     *         not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if the invocation type is not
-     * {@code (float)int} or {@code (Float)int}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite floatSwitch(MethodHandles.Lookup lookup,
-                                       String invocationName,
-                                       MethodType invocationType,
-                                       float... floatLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!FLOAT_TYPES.contains(invocationType.parameterType(0))))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(floatLabels);
-
-        int[] intLabels = new int[floatLabels.length];
-        for (int i=0; i<floatLabels.length; i++)
-            intLabels[i] = Float.floatToIntBits(floatLabels[i]);
-
-        assert IntStream.of(intLabels).distinct().count() == intLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(floatLabels);
-
-        return new IntSwitchCallSite(invocationType, intLabels);
-    }
-
-    static class IntSwitchCallSite extends ConstantCallSite {
-        private final int[] labels;
-        private final int[] indexes;
-
-        IntSwitchCallSite(MethodType targetType,
-                          int[] intLabels) throws Throwable {
-            super(targetType, CONSTANT_INIT_HOOK);
-
-            // expensive way to index an array
-            indexes = IntStream.range(0, intLabels.length)
-                               .boxed()
-                               .sorted(Comparator.comparingInt(a -> intLabels[a]))
-                               .mapToInt(Integer::intValue)
-                               .toArray();
-            labels = new int[indexes.length];
-            for (int i=0; i<indexes.length; i++)
-                labels[i] = intLabels[indexes[i]];
-        }
-
-        int doSwitch(int target) {
-            int index = Arrays.binarySearch(labels, target);
-            return (index >= 0) ? indexes[index] : indexes.length;
-        }
-
-        int doSwitch(boolean target) {
-            return doSwitch(target ? 1 : 0);
-        }
-
-        int doSwitch(float target) {
-            return doSwitch(Float.floatToIntBits(target));
-        }
-
-        int doSwitch(short target) {
-            return doSwitch((int) target);
-        }
-
-        int doSwitch(byte target) {
-            return doSwitch((int) target);
-        }
-
-        int doSwitch(char target) {
-            return doSwitch((int) target);
-        }
-
-        int doSwitch(Boolean target) {
-            return (target == null) ? -1 : doSwitch((boolean) target);
-        }
-
-        int doSwitch(Integer target) {
-            return (target == null) ? -1 : doSwitch((int) target);
-        }
-
-        int doSwitch(Float target) {
-            return (target == null) ? -1 : doSwitch((float) target);
-        }
-
-        int doSwitch(Short target) {
-            return (target == null) ? -1 : doSwitch((int) target);
-        }
-
-        int doSwitch(Character target) {
-            return (target == null) ? -1 : doSwitch((int) target);
-        }
-
-        int doSwitch(Byte target) {
-            return (target == null) ? -1 : doSwitch((int) target);
-        }
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on a {@code long} or {@code Long}.
-     * The static arguments are a varargs array of {@code long} labels.
-     *
-     * <p>The results are undefined if the labels array contains duplicates.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter which is
-     *                       one of the 32-bit or shorter primitive types, or
-     *                       one of their box types, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param longLabels long values corresponding to the case labels of the
-     *                  {@code switch} statement.
-     * @return the index into {@code longLabels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code longLabels.length} if the target value does
-     *         not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if the invocation type is not
-     * {@code (long)int} or {@code (Long)int}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite longSwitch(MethodHandles.Lookup lookup,
-                                      String invocationName,
-                                      MethodType invocationType,
-                                      long... longLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!LONG_TYPES.contains(invocationType.parameterType(0))))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(longLabels);
-
-        assert LongStream.of(longLabels).distinct().count() == longLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(longLabels);
-
-        return new LongSwitchCallSite(invocationType, longLabels);
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on a {@code double} or {@code Double}.
-     * The static arguments are a varargs array of {@code double} labels.
-     *
-     * <p>The results are undefined if the labels array contains duplicates
-     * according to {@link Double#doubleToLongBits(double)}.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter which is
-     *                       one of the 32-bit or shorter primitive types, or
-     *                       one of their box types, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param doubleLabels long values corresponding to the case labels of the
-     *                  {@code switch} statement.
-     * @return the index into {@code doubleLabels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code doubleLabels.length} if the target value does
-     *         not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if the invocation type is not
-     * {@code (double)int} or {@code (Double)int}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite doubleSwitch(MethodHandles.Lookup lookup,
-                                        String invocationName,
-                                        MethodType invocationType,
-                                        double... doubleLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!DOUBLE_TYPES.contains(invocationType.parameterType(0))))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(doubleLabels);
-
-        long[] longLabels = new long[doubleLabels.length];
-        for (int i=0; i<doubleLabels.length; i++)
-            longLabels[i] = Double.doubleToLongBits(doubleLabels[i]);
-
-        assert LongStream.of(longLabels).distinct().count() == longLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(doubleLabels);
-
-        return new LongSwitchCallSite(invocationType, longLabels);
-    }
-
-    static class LongSwitchCallSite extends ConstantCallSite {
-        private final long[] labels;
-        private final int[] indexes;
-
-        LongSwitchCallSite(MethodType targetType,
-                           long[] longLabels) throws Throwable {
-            super(targetType, CONSTANT_INIT_HOOK);
-
-            // expensive way to index an array
-            indexes = IntStream.range(0, longLabels.length)
-                               .boxed()
-                               .sorted(Comparator.comparingLong(a -> longLabels[a]))
-                               .mapToInt(Integer::intValue)
-                               .toArray();
-            labels = new long[indexes.length];
-            for (int i=0; i<indexes.length; i++)
-                labels[i] = longLabels[indexes[i]];
-        }
-
-        int doSwitch(long target) {
-            int index = Arrays.binarySearch(labels, target);
-            return (index >= 0) ? indexes[index] : indexes.length;
-        }
-
-        int doSwitch(double target) {
-            return doSwitch(Double.doubleToLongBits(target));
-        }
-
-        int doSwitch(Long target) {
-            return (target == null) ? -1 : doSwitch((long) target);
-        }
-
-        int doSwitch(Double target) {
-            return (target == null) ? -1 : doSwitch((double) target);
-        }
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on a {@code String} target.  The static
-     * arguments are a varargs array of {@code String} labels.
-     *
-     * <p>The results are undefined if the labels array contains duplicates
-     * according to {@link String#equals(Object)}.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter of
-     *                       {@code String}, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param stringLabels non-null string values corresponding to the case
-     *                     labels of the {@code switch} statement.
-     * @return the index into {@code labels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code stringLabels.length} if the target value
-     *         does not match any of the labels.
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if any labels are null, or if the
-     * invocation type is not {@code (String)int}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite stringSwitch(MethodHandles.Lookup lookup,
-                                        String invocationName,
-                                        MethodType invocationType,
-                                        String... stringLabels) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!invocationType.parameterType(0).equals(String.class)))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(stringLabels);
-        if (Stream.of(stringLabels).anyMatch(Objects::isNull))
-            throw new IllegalArgumentException("null label found");
-
-        assert Stream.of(stringLabels).distinct().count() == stringLabels.length
-                : "switch labels are not distinct: " + Arrays.toString(stringLabels);
-
-        return new StringSwitchCallSite(invocationType, stringLabels);
-    }
-
-    static class StringSwitchCallSite extends ConstantCallSite {
-        private static final Comparator<String> STRING_BY_HASH
-                = Comparator.comparingInt(Objects::hashCode);
-
-        private final String[] sortedByHash;
-        private final int[] indexes;
-        private final boolean collisions;
-
-        StringSwitchCallSite(MethodType targetType,
-                             String[] stringLabels) throws Throwable {
-            super(targetType, CONSTANT_INIT_HOOK);
-
-            // expensive way to index an array
-            indexes = IntStream.range(0, stringLabels.length)
-                               .boxed()
-                               .sorted(Comparator.comparingInt(i -> stringLabels[i].hashCode()))
-                               .mapToInt(Integer::intValue)
-                               .toArray();
-            sortedByHash = new String[indexes.length];
-            for (int i=0; i<indexes.length; i++)
-                sortedByHash[i] = stringLabels[indexes[i]];
-
-            collisions = IntStream.range(0, sortedByHash.length-1)
-                                  .anyMatch(i -> sortedByHash[i].hashCode() == sortedByHash[i + 1].hashCode());
-        }
-
-        int doSwitch(String target) {
-            if (target == null)
-                return -1;
-
-            int index = Arrays.binarySearch(sortedByHash, target, STRING_BY_HASH);
-            if (index < 0)
-                return indexes.length;
-            else if (target.equals(sortedByHash[index])) {
-                return indexes[index];
-            }
-            else if (collisions) {
-                int hash = target.hashCode();
-                while (index > 0 && sortedByHash[index-1].hashCode() == hash)
-                    --index;
-                for (; index < sortedByHash.length && sortedByHash[index].hashCode() == hash; index++)
-                    if (target.equals(sortedByHash[index]))
-                        return indexes[index];
-            }
-
-            return indexes.length;
-        }
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on an {@code Enum} target.  The static
-     * arguments are the enum class, and a varargs arrays of {@code String}
-     * that are the names of the enum constants corresponding to the
-     * {@code case} labels.
-     *
-     * <p>The results are undefined if the names array contains duplicates.
-     *
-     * @implNote
-     *
-     * The implementation only enforces the requirement that the labels array
-     * be duplicate-free if system assertions are enabled.
-     *
-     * @param <E> the enum type
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter of
-     *                       {@code Enum}, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param enumClass the enum class
-     * @param enumNames names of the enum constants against which the target
-     *                  should be matched
-     * @return the index into {@code labels} of the target value, if the target
-     *         matches any of the labels, {@literal -1} if the target value is
-     *         {@code null}, or {@code stringLabels.length} if the target value
-     *         does not match any of the labels.
-     * @throws IllegalArgumentException if the specified class is not an
-     *                                  enum class, or any label name is null,
-     *                                  or if the invocation type is not
-     *                                  {@code (Enum)int}
-     * @throws NullPointerException if any required argument is null
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static<E extends Enum<E>> CallSite enumSwitch(MethodHandles.Lookup lookup,
-                                                         String invocationName,
-                                                         MethodType invocationType,
-                                                         Class<E> enumClass,
-                                                         String... enumNames) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || (!invocationType.parameterType(0).equals(Enum.class)))
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(enumClass);
-        requireNonNull(enumNames);
-        if (!enumClass.isEnum())
-            throw new IllegalArgumentException("not an enum class");
-        if (Stream.of(enumNames).anyMatch(Objects::isNull))
-            throw new IllegalArgumentException("null label found");
-
-        assert Stream.of(enumNames).distinct().count() == enumNames.length
-                : "switch labels are not distinct: " + Arrays.toString(enumNames);
-
-        return new EnumSwitchCallSite<>(invocationType, enumClass, enumNames);
-    }
-
-    static class EnumSwitchCallSite<E extends Enum<E>> extends ConstantCallSite {
-        private final int[] ordinalMap;
-
-        EnumSwitchCallSite(MethodType targetType,
-                           Class<E> enumClass,
-                           String... enumNames) throws Throwable {
-            super(targetType, CONSTANT_INIT_HOOK);
-
-            ordinalMap = new int[enumClass.getEnumConstants().length];
-            Arrays.fill(ordinalMap, enumNames.length);
-
-            for (int i=0; i<enumNames.length; i++) {
-                try {
-                    ordinalMap[E.valueOf(enumClass, enumNames[i]).ordinal()] = i;
-                }
-                catch (Exception e) {
-                    // allow non-existent labels, but never match them
-                    continue;
-                }
-            }
-        }
-
-        @SuppressWarnings("rawtypes")
-        int doSwitch(Enum target) {
-            return (target == null) ? -1 : ordinalMap[target.ordinal()];
-        }
-    }
-
-    /**
-     * Bootstrap method for linking an {@code invokedynamic} call site that
-     * implements a {@code switch} on a reference-typed target.  The static
-     * arguments are a varargs array of {@code Class} labels.
-     *
-     * @param lookup Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
-     * @param invocationName The invocation name, which is ignored.  When used with
-     *                       {@code invokedynamic}, this is provided by the
-     *                       {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param invocationType The invocation type of the {@code CallSite}.  This
-     *                       method type should have a single parameter of
-     *                       a reference type, and return {@code int}.  When
-     *                       used with {@code invokedynamic}, this is provided by
-     *                       the {@code NameAndType} of the {@code InvokeDynamic}
-     *                       structure and is stacked automatically by the VM.
-     * @param types non-null {@link Class} values
-     * @return the index into {@code labels} of the target value, if the target
-     *         is an instance of any of the types, {@literal -1} if the target
-     *         value is {@code null}, or {@code types.length} if the target value
-     *         is not an instance of any of the types
-     * @throws NullPointerException if any required argument is null
-     * @throws IllegalArgumentException if any labels are null, or if the
-     * invocation type is not {@code (T)int for some reference type {@code T}}
-     * @throws Throwable if there is any error linking the call site
-     */
-    public static CallSite typeSwitch(MethodHandles.Lookup lookup,
-                                      String invocationName,
-                                      MethodType invocationType,
-                                      Class<?>... types) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(int.class))
-            || invocationType.parameterType(0).isPrimitive())
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(types);
-
-        types = types.clone();
-        if (Stream.of(types).anyMatch(Objects::isNull))
-            throw new IllegalArgumentException("null label found");
-
-        assert Stream.of(types).distinct().count() == types.length
-                : "switch labels are not distinct: " + Arrays.toString(types);
-
-        return new TypeSwitchCallSite(invocationType, types);
-    }
-
-    static class TypeSwitchCallSite extends ConstantCallSite {
-        private final Class<?>[] types;
-
-        TypeSwitchCallSite(MethodType targetType,
-                           Class<?>[] types) throws Throwable {
-            super(targetType, TYPE_INIT_HOOK);
-            this.types = types;
-        }
-
-        int doSwitch(Object target) {
-            if (target == null)
-                return -1;
-
-            // Dumbest possible strategy
-            Class<?> targetClass = target.getClass();
-            for (int i = 0; i < types.length; i++) {
-                Class<?> c = types[i];
-                if (c.isAssignableFrom(targetClass))
-                    return i;
-            }
-
-            return types.length;
-        }
-    }
-
-    /**
-     * Result type for pattern switches
-     */
-    public static class PatternSwitchResult {
-        /**
-         * The selected index, -1 if input was null, or length if not matched
-         */
-        public final int index;
-
-        /**
-         * The carrier
-         */
-        public final Object carrier;
-
-        /**
-         * Construct a PatternSwitchResult
-         *
-         * @param index the index
-         * @param carrier the carrier
-         */
-        public PatternSwitchResult(int index, Object carrier) {
-            this.index = index;
-            this.carrier = carrier;
-        }
-    }
-
-    /**
-     * Bootstrap for pattern switches
-     *
-     * @param lookup the lookup (ignored)
-     * @param invocationName the invocation name (ignored)
-     * @param invocationType the invocation type (must return PatternSwitchResult)
-     * @param patterns the patterns
-     * @return the result
-     * @throws Throwable if something went wrong
-     */
-    public static CallSite patternSwitch(MethodHandles.Lookup lookup,
-                                         String invocationName,
-                                         MethodType invocationType,
-                                         PatternHandle... patterns) throws Throwable {
-        if (invocationType.parameterCount() != 1
-            || (!invocationType.returnType().equals(PatternSwitchResult.class))
-            || invocationType.parameterType(0).isPrimitive())
-            throw new IllegalArgumentException("Illegal invocation type " + invocationType);
-        requireNonNull(patterns);
-
-        patterns = patterns.clone();
-        Class<?> targetType = invocationType.parameterType(0);
-
-        for (int i = 0; i < patterns.length; i++) {
-            PatternHandle pattern = patterns[i];
-            if (pattern.descriptor().returnType() != targetType)
-                patterns[i] = PatternHandles.adaptTarget(pattern, targetType);
-        }
-
-        if (Stream.of(patterns).anyMatch(Objects::isNull))
-            throw new IllegalArgumentException("null pattern found");
-
-        return new PatternSwitchCallSite(invocationType, patterns);
-    }
-
-    static class PatternSwitchCallSite extends ConstantCallSite {
-        private final PatternHandle[] patterns;
-
-        PatternSwitchCallSite(MethodType targetType,
-                              PatternHandle[] patterns) throws Throwable {
-            super(targetType, PATTERN_INIT_HOOK);
-            this.patterns = patterns;
-        }
-
-        PatternSwitchResult doSwitch(Object target) throws Throwable {
-            if (target == null)
-                return new PatternSwitchResult(-1, null);
-
-            // Dumbest possible strategy
-            for (int i = 0; i < patterns.length; i++) {
-                PatternHandle e = patterns[i];
-                Object o = e.tryMatch().invoke(target);
-                if (o != null)
-                    return new PatternSwitchResult(i, o);
-            }
-
-            return new PatternSwitchResult(patterns.length, null);
-
-        }
-    }
-}
diff --git a/src/java.base/share/classes/java/net/ProxySelector.java b/src/java.base/share/classes/java/net/ProxySelector.java
index 94f236a1bfa..f31ef0aaa1d 100644
--- a/src/java.base/share/classes/java/net/ProxySelector.java
+++ b/src/java.base/share/classes/java/net/ProxySelector.java
@@ -65,7 +65,7 @@ public abstract class ProxySelector {
      *
      * @see #setDefault(ProxySelector)
      */
-    private static ProxySelector theProxySelector;
+    private static volatile ProxySelector theProxySelector;
 
     static {
         try {
diff --git a/src/java.base/share/classes/java/security/SecureClassLoader.java b/src/java.base/share/classes/java/security/SecureClassLoader.java
index 0f2983a40bd..8cb7bed527f 100644
--- a/src/java.base/share/classes/java/security/SecureClassLoader.java
+++ b/src/java.base/share/classes/java/security/SecureClassLoader.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -269,4 +269,11 @@ public boolean equals(Object obj) {
             return cs.matchCerts(csk.cs, true);
         }
     }
+
+    /**
+     * Called by the VM, during -Xshare:dump
+     */
+    private void resetArchivedStates() {
+        pdcache.clear();
+    }
 }
diff --git a/src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java b/src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java
index 109328d4549..2a09965cf3e 100644
--- a/src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java
+++ b/src/java.base/share/classes/java/security/spec/MGF1ParameterSpec.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -108,6 +108,34 @@ public class MGF1ParameterSpec implements AlgorithmParameterSpec {
     public static final MGF1ParameterSpec SHA512_256 =
         new MGF1ParameterSpec("SHA-512/256");
 
+    /**
+     * The MGF1ParameterSpec which uses SHA3-224 message digest
+     * @since 16
+     */
+    public static final MGF1ParameterSpec SHA3_224 =
+        new MGF1ParameterSpec("SHA3-224");
+
+    /**
+     * The MGF1ParameterSpec which uses SHA3-256 message digest
+     * @since 16
+     */
+    public static final MGF1ParameterSpec SHA3_256 =
+        new MGF1ParameterSpec("SHA3-256");
+
+    /**
+     * The MGF1ParameterSpec which uses SHA3-384 message digest
+     * @since 16
+     */
+    public static final MGF1ParameterSpec SHA3_384 =
+        new MGF1ParameterSpec("SHA3-384");
+
+    /**
+     * The MGF1ParameterSpec which uses SHA3-512 message digest
+     * @since 16
+     */
+    public static final MGF1ParameterSpec SHA3_512 =
+        new MGF1ParameterSpec("SHA3-512");
+
     private String mdName;
 
     /**
diff --git a/src/java.base/share/classes/java/util/Calendar.java b/src/java.base/share/classes/java/util/Calendar.java
index 0b0974843f3..5d3da1a1b50 100644
--- a/src/java.base/share/classes/java/util/Calendar.java
+++ b/src/java.base/share/classes/java/util/Calendar.java
@@ -1796,8 +1796,10 @@ public final Date getTime() {
      * @param date the given Date.
      * @see #getTime()
      * @see #setTimeInMillis(long)
+     * @throws NullPointerException if {@code date} is {@code null}
      */
     public final void setTime(Date date) {
+        Objects.requireNonNull(date, "date must not be null");
         setTimeInMillis(date.getTime());
     }
 
diff --git a/src/java.base/share/classes/java/util/jar/JarFile.java b/src/java.base/share/classes/java/util/jar/JarFile.java
index 43c56a86bb0..17f599d47c3 100644
--- a/src/java.base/share/classes/java/util/jar/JarFile.java
+++ b/src/java.base/share/classes/java/util/jar/JarFile.java
@@ -423,7 +423,9 @@ private Manifest getManifestFromReference() throws IOException {
                     }
                     man = new Manifest(jv, new ByteArrayInputStream(b), getName());
                 } else {
-                    man = new Manifest(super.getInputStream(manEntry), getName());
+                    try (InputStream is = super.getInputStream(manEntry)) {
+                        man = new Manifest(is, getName());
+                    }
                 }
                 manRef = new SoftReference<>(man);
             }
diff --git a/src/java.base/share/classes/java/util/stream/Stream.java b/src/java.base/share/classes/java/util/stream/Stream.java
index 742fa8d488e..d00740bb830 100644
--- a/src/java.base/share/classes/java/util/stream/Stream.java
+++ b/src/java.base/share/classes/java/util/stream/Stream.java
@@ -375,7 +375,7 @@ public interface Stream<T> extends BaseStream<T, Stream<T>> {
      * </ul>
      *
      * <p>If a lambda expression is provided as the mapper function argument, additional type
-     * information maybe be necessary for proper inference of the element type {@code <R>} of
+     * information may be necessary for proper inference of the element type {@code <R>} of
      * the returned stream. This can be provided in the form of explicit type declarations for
      * the lambda parameters or as an explicit type argument to the {@code mapMulti} call.
      *
diff --git a/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java b/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java
index 92beb7b8d92..db61ee2da23 100644
--- a/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java
+++ b/src/java.base/share/classes/java/util/zip/GZIPOutputStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,6 +52,9 @@ public class GZIPOutputStream extends DeflaterOutputStream {
      */
     private static final int TRAILER_SIZE = 8;
 
+    // Represents the default "unknown" value for OS header, per RFC-1952
+    private static final byte OS_UNKNOWN = (byte) 255;
+
     /**
      * Creates a new output stream with the specified buffer size.
      *
@@ -189,7 +192,7 @@ private void writeHeader() throws IOException {
                       0,                        // Modification time MTIME (int)
                       0,                        // Modification time MTIME (int)
                       0,                        // Extra flags (XFLG)
-                      0                         // Operating system (OS)
+                      OS_UNKNOWN                // Operating system (OS)
                   });
     }
 
diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java
index c89275a335c..edcc5ed5caf 100644
--- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java
+++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java
@@ -256,6 +256,12 @@ public interface JavaLangAccess {
      */
     ServicesCatalog getServicesCatalog(ModuleLayer layer);
 
+    /**
+     * Record that this layer has at least one module defined to the given
+     * class loader.
+     */
+    void bindToLoader(ModuleLayer layer, ClassLoader loader);
+
     /**
      * Returns an ordered stream of layers. The first element is the
      * given layer, the remaining elements are its parents, in DFS order.
diff --git a/src/java.base/share/classes/jdk/internal/loader/ArchivedClassLoaders.java b/src/java.base/share/classes/jdk/internal/loader/ArchivedClassLoaders.java
new file mode 100644
index 00000000000..48cd4e2e6dc
--- /dev/null
+++ b/src/java.base/share/classes/jdk/internal/loader/ArchivedClassLoaders.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.loader;
+
+import java.util.Map;
+import jdk.internal.misc.VM;
+import jdk.internal.module.ServicesCatalog;
+
+/**
+ * Used to archive the built-in class loaders, their services catalogs, and the
+ * package-to-module map used by the built-in class loaders.
+ */
+class ArchivedClassLoaders {
+    private static ArchivedClassLoaders archivedClassLoaders;
+
+    private final ClassLoader bootLoader;
+    private final ClassLoader platformLoader;
+    private final ClassLoader appLoader;
+    private final ServicesCatalog[] servicesCatalogs;
+    private final Map<String, ?> packageToModule;
+
+    private ArchivedClassLoaders() {
+        bootLoader = ClassLoaders.bootLoader();
+        platformLoader = ClassLoaders.platformClassLoader();
+        appLoader = ClassLoaders.appClassLoader();
+
+        servicesCatalogs = new ServicesCatalog[3];
+        servicesCatalogs[0] = BootLoader.getServicesCatalog();
+        servicesCatalogs[1] = ServicesCatalog.getServicesCatalog(platformLoader);
+        servicesCatalogs[2] = ServicesCatalog.getServicesCatalog(appLoader);
+
+        packageToModule = BuiltinClassLoader.packageToModule();
+    }
+
+    ClassLoader bootLoader() {
+        return bootLoader;
+    }
+
+    ClassLoader platformLoader() {
+        return platformLoader;
+    }
+
+    ClassLoader appLoader() {
+        return appLoader;
+    }
+
+    ServicesCatalog servicesCatalog(ClassLoader loader) {
+        if (loader == null) {
+            return servicesCatalogs[0];
+        } else if (loader == platformLoader) {
+            return servicesCatalogs[1];
+        } else if (loader == appLoader) {
+            return servicesCatalogs[2];
+        } else {
+            throw new InternalError();
+        }
+    }
+
+    Map<String, ?> packageToModule() {
+        return packageToModule;
+    }
+
+    static void archive() {
+        archivedClassLoaders = new ArchivedClassLoaders();
+    }
+
+    static ArchivedClassLoaders get() {
+        return archivedClassLoaders;
+    }
+
+    static {
+        VM.initializeFromArchive(ArchivedClassLoaders.class);
+    }
+}
diff --git a/src/java.base/share/classes/jdk/internal/loader/BootLoader.java b/src/java.base/share/classes/jdk/internal/loader/BootLoader.java
index 2a8d7c4e7b4..671917edad3 100644
--- a/src/java.base/share/classes/jdk/internal/loader/BootLoader.java
+++ b/src/java.base/share/classes/jdk/internal/loader/BootLoader.java
@@ -65,7 +65,15 @@ private BootLoader() { }
     }
 
     // ServiceCatalog for the boot class loader
-    private static final ServicesCatalog SERVICES_CATALOG = ServicesCatalog.create();
+    private static final ServicesCatalog SERVICES_CATALOG;
+    static {
+        ArchivedClassLoaders archivedClassLoaders = ArchivedClassLoaders.get();
+        if (archivedClassLoaders != null) {
+            SERVICES_CATALOG = archivedClassLoaders.servicesCatalog(null);
+        } else {
+            SERVICES_CATALOG = ServicesCatalog.create();
+        }
+    }
 
     // ClassLoaderValue map for the boot class loader
     private static final ConcurrentHashMap<?, ?> CLASS_LOADER_VALUE_MAP
diff --git a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java
index 21d44413060..39fe750c1e4 100644
--- a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java
+++ b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java
@@ -104,8 +104,7 @@ public class BuiltinClassLoader
     private final BuiltinClassLoader parent;
 
     // the URL class path, or null if there is no class path
-    private final URLClassPath ucp;
-
+    private @Stable URLClassPath ucp;
 
     /**
      * A module defined/loaded by a built-in class loader.
@@ -156,10 +155,26 @@ private URL createURL(URI uri) {
         }
     }
 
-
     // maps package name to loaded module for modules in the boot layer
-    private static final Map<String, LoadedModule> packageToModule
-        = new ConcurrentHashMap<>(1024);
+    private static final Map<String, LoadedModule> packageToModule;
+    static {
+        ArchivedClassLoaders archivedClassLoaders = ArchivedClassLoaders.get();
+        if (archivedClassLoaders != null) {
+            @SuppressWarnings("unchecked")
+            Map<String, LoadedModule> map
+                = (Map<String, LoadedModule>) archivedClassLoaders.packageToModule();
+            packageToModule = map;
+        } else {
+            packageToModule = new ConcurrentHashMap<>(1024);
+        }
+    }
+
+    /**
+     * Invoked by ArchivedClassLoaders to archive the package-to-module map.
+     */
+    static Map<String, ?> packageToModule() {
+        return packageToModule;
+    }
 
     // maps a module name to a module reference
     private final Map<String, ModuleReference> nameToModule;
@@ -185,6 +200,21 @@ private URL createURL(URI uri) {
         this.moduleToReader = new ConcurrentHashMap<>();
     }
 
+    /**
+     * Appends to the given file path to the class path.
+     */
+    void appendClassPath(String path) {
+        // assert ucp != null;
+        ucp.addFile(path);
+    }
+
+    /**
+     * Sets the class path, called to reset the class path during -Xshare:dump
+     */
+    void setClassPath(URLClassPath ucp) {
+        this.ucp = ucp;
+    }
+
     /**
      * Returns {@code true} if there is a class path associated with this
      * class loader.
@@ -1042,4 +1072,9 @@ private boolean isOpen(ModuleReference mref, String pn) {
     private static URL checkURL(URL url) {
         return URLClassPath.checkURL(url);
     }
+
+    // Called from VM only, during -Xshare:dump
+    private void resetArchivedStates() {
+        ucp = null;
+    }
 }
diff --git a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java
index f87d24f8dd5..ea9307aa148 100644
--- a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java
+++ b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java
@@ -36,6 +36,7 @@
 import jdk.internal.access.JavaLangAccess;
 import jdk.internal.access.SharedSecrets;
 import jdk.internal.misc.VM;
+import jdk.internal.module.ServicesCatalog;
 
 /**
  * Creates and provides access to the built-in platform and application class
@@ -56,14 +57,22 @@ private ClassLoaders() { }
 
     // Creates the built-in class loaders.
     static {
-        // -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute
-        String append = VM.getSavedProperty("jdk.boot.class.path.append");
-        BOOT_LOADER =
-            new BootClassLoader((append != null && !append.isEmpty())
-                ? new URLClassPath(append, true)
-                : null);
-        PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER);
-
+        ArchivedClassLoaders archivedClassLoaders = ArchivedClassLoaders.get();
+        if (archivedClassLoaders != null) {
+            // assert VM.getSavedProperty("jdk.boot.class.path.append") == null
+            BOOT_LOADER = (BootClassLoader) archivedClassLoaders.bootLoader();
+            PLATFORM_LOADER = (PlatformClassLoader) archivedClassLoaders.platformLoader();
+            ServicesCatalog catalog = archivedClassLoaders.servicesCatalog(PLATFORM_LOADER);
+            ServicesCatalog.putServicesCatalog(PLATFORM_LOADER, catalog);
+        } else {
+            // -Xbootclasspath/a or -javaagent with Boot-Class-Path attribute
+            String append = VM.getSavedProperty("jdk.boot.class.path.append");
+            URLClassPath ucp = (append != null && !append.isEmpty())
+                    ? new URLClassPath(append, true)
+                    : null;
+            BOOT_LOADER = new BootClassLoader(ucp);
+            PLATFORM_LOADER = new PlatformClassLoader(BOOT_LOADER);
+        }
         // A class path is required when no initial module is specified.
         // In this case the class path defaults to "", meaning the current
         // working directory.  When an initial module is specified, on the
@@ -75,7 +84,15 @@ private ClassLoaders() { }
             cp = (initialModuleName == null) ? "" : null;
         }
         URLClassPath ucp = new URLClassPath(cp, false);
-        APP_LOADER = new AppClassLoader(PLATFORM_LOADER, ucp);
+        if (archivedClassLoaders != null) {
+            APP_LOADER = (AppClassLoader) archivedClassLoaders.appLoader();
+            ServicesCatalog catalog = archivedClassLoaders.servicesCatalog(APP_LOADER);
+            ServicesCatalog.putServicesCatalog(APP_LOADER, catalog);
+            APP_LOADER.setClassPath(ucp);
+        } else {
+            APP_LOADER = new AppClassLoader(PLATFORM_LOADER, ucp);
+            ArchivedClassLoaders.archive();
+        }
     }
 
     /**
@@ -144,11 +161,8 @@ private static class AppClassLoader extends BuiltinClassLoader {
                 throw new InternalError();
         }
 
-        final URLClassPath ucp;
-
-        AppClassLoader(PlatformClassLoader parent, URLClassPath ucp) {
+        AppClassLoader(BuiltinClassLoader parent, URLClassPath ucp) {
             super("app", parent, ucp);
-            this.ucp = ucp;
         }
 
         @Override
@@ -181,7 +195,7 @@ protected PermissionCollection getPermissions(CodeSource cs) {
          * @see java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch
          */
         void appendToClassPathForInstrumentation(String path) {
-            ucp.addFile(path);
+            appendClassPath(path);
         }
 
         /**
@@ -190,6 +204,13 @@ void appendToClassPathForInstrumentation(String path) {
         protected Package defineOrCheckPackage(String pn, Manifest man, URL url) {
             return super.defineOrCheckPackage(pn, man, url);
         }
+
+        /**
+         * Called by the VM, during -Xshare:dump
+         */
+        private void resetArchivedStates() {
+            setClassPath(null);
+        }
     }
 
     /**
diff --git a/src/java.base/share/classes/jdk/internal/misc/VM.java b/src/java.base/share/classes/jdk/internal/misc/VM.java
index ed753a58ca2..5681a79558f 100644
--- a/src/java.base/share/classes/jdk/internal/misc/VM.java
+++ b/src/java.base/share/classes/jdk/internal/misc/VM.java
@@ -468,6 +468,8 @@ public static boolean isSetUID() {
      */
     public static native void initializeFromArchive(Class<?> c);
 
+    public static native void defineArchivedModules(ClassLoader platformLoader, ClassLoader systemLoader);
+
     public static native long getRandomSeedForCDSDump();
 
     /**
diff --git a/src/java.base/share/classes/jdk/internal/module/ArchivedBootLayer.java b/src/java.base/share/classes/jdk/internal/module/ArchivedBootLayer.java
new file mode 100644
index 00000000000..90bd5eaa51e
--- /dev/null
+++ b/src/java.base/share/classes/jdk/internal/module/ArchivedBootLayer.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.module;
+
+import jdk.internal.misc.VM;
+
+/**
+ * Used by ModuleBootstrap for archiving the boot layer and the builder needed to
+ * set the IllegalAccessLogger.
+ */
+class ArchivedBootLayer {
+    private static ArchivedBootLayer archivedBootLayer;
+
+    private final ModuleLayer bootLayer;
+    private final IllegalAccessLogger.Builder builder;
+
+    private ArchivedBootLayer(ModuleLayer bootLayer,
+                              IllegalAccessLogger.Builder builder) {
+        this.bootLayer = bootLayer;
+        this.builder = builder;
+    }
+
+    ModuleLayer bootLayer() {
+        return bootLayer;
+    }
+
+    IllegalAccessLogger.Builder illegalAccessLoggerBuilder() {
+        return builder;
+    }
+
+    static ArchivedBootLayer get() {
+        return archivedBootLayer;
+    }
+
+    static void archive(ModuleLayer layer, IllegalAccessLogger.Builder builder) {
+        archivedBootLayer = new ArchivedBootLayer(layer, builder);
+    }
+
+    static {
+        VM.initializeFromArchive(ArchivedBootLayer.class);
+    }
+}
diff --git a/src/java.base/share/classes/jdk/internal/module/ArchivedModuleGraph.java b/src/java.base/share/classes/jdk/internal/module/ArchivedModuleGraph.java
index 348d943106a..6b038238eb1 100644
--- a/src/java.base/share/classes/jdk/internal/module/ArchivedModuleGraph.java
+++ b/src/java.base/share/classes/jdk/internal/module/ArchivedModuleGraph.java
@@ -22,21 +22,20 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-
 package jdk.internal.module;
 
-import java.lang.module.Configuration;
-import java.lang.module.ModuleFinder;
 import java.util.Map;
 import java.util.Set;
 import java.util.function.Function;
-
+import java.lang.module.Configuration;
+import java.lang.module.ModuleFinder;
 import jdk.internal.misc.VM;
 
 /**
- * Used by ModuleBootstrap to obtain the archived system modules and finder.
+ * Used by ModuleBootstrap for archiving the configuration for the boot layer,
+ * the system module finder, and the maps used to create the IllegalAccessLogger.
  */
-final class ArchivedModuleGraph {
+class ArchivedModuleGraph {
     private static ArchivedModuleGraph archivedModuleGraph;
 
     private final boolean hasSplitPackages;
@@ -47,13 +46,13 @@ final class ArchivedModuleGraph {
     private final Map<String, Set<String>> concealedPackagesToOpen;
     private final Map<String, Set<String>> exportedPackagesToOpen;
 
-    public ArchivedModuleGraph(boolean hasSplitPackages,
-                               boolean hasIncubatorModules,
-                               ModuleFinder finder,
-                               Configuration configuration,
-                               Function<String, ClassLoader> classLoaderFunction,
-                               Map<String, Set<String>> concealedPackagesToOpen,
-                               Map<String, Set<String>> exportedPackagesToOpen) {
+    private ArchivedModuleGraph(boolean hasSplitPackages,
+                                boolean hasIncubatorModules,
+                                ModuleFinder finder,
+                                Configuration configuration,
+                                Function<String, ClassLoader> classLoaderFunction,
+                                Map<String, Set<String>> concealedPackagesToOpen,
+                                Map<String, Set<String>> exportedPackagesToOpen) {
         this.hasSplitPackages = hasSplitPackages;
         this.hasIncubatorModules = hasIncubatorModules;
         this.finder = finder;
@@ -107,8 +106,20 @@ static ArchivedModuleGraph get(String mainModule) {
     /**
      * Archive the module graph for the given initial module.
      */
-    static void archive(ArchivedModuleGraph graph) {
-        archivedModuleGraph = graph;
+    static void archive(boolean hasSplitPackages,
+                        boolean hasIncubatorModules,
+                        ModuleFinder finder,
+                        Configuration configuration,
+                        Function<String, ClassLoader> classLoaderFunction,
+                        Map<String, Set<String>> concealedPackagesToOpen,
+                        Map<String, Set<String>> exportedPackagesToOpen) {
+        archivedModuleGraph = new ArchivedModuleGraph(hasSplitPackages,
+                                                      hasIncubatorModules,
+                                                      finder,
+                                                      configuration,
+                                                      classLoaderFunction,
+                                                      concealedPackagesToOpen,
+                                                      exportedPackagesToOpen);
     }
 
     static {
diff --git a/src/java.base/share/classes/jdk/internal/module/IllegalAccessLogger.java b/src/java.base/share/classes/jdk/internal/module/IllegalAccessLogger.java
index 1368c17d8cd..2a67401d18b 100644
--- a/src/java.base/share/classes/jdk/internal/module/IllegalAccessLogger.java
+++ b/src/java.base/share/classes/jdk/internal/module/IllegalAccessLogger.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,7 +57,7 @@ public final class IllegalAccessLogger {
     /**
      * Logger modes
      */
-    public static enum Mode {
+    public enum Mode {
         /**
          * Prints a warning when an illegal access succeeds and then
          * discards the logger so that there is no further output.
@@ -118,7 +118,7 @@ public Builder logAccessToExportedPackages(Module m, Set<String> packages) {
         }
 
         /**
-         * Builds the IllegalAccessLogger and sets it as the system-wise logger.
+         * Builds the IllegalAccessLogger and sets it as the system-wide logger.
          */
         public void complete() {
             Map<Module, Set<String>> map1 = unmodifiableMap(moduleToConcealedPackages);
diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java
index ed6fb613310..bc872c44917 100644
--- a/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java
@@ -42,18 +42,19 @@
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
-import jdk.internal.loader.BootLoader;
-import jdk.internal.loader.BuiltinClassLoader;
 import jdk.internal.access.JavaLangAccess;
 import jdk.internal.access.JavaLangModuleAccess;
 import jdk.internal.access.SharedSecrets;
+import jdk.internal.loader.BootLoader;
+import jdk.internal.loader.BuiltinClassLoader;
+import jdk.internal.loader.ClassLoaders;
+import jdk.internal.misc.VM;
 import jdk.internal.perf.PerfCounter;
 
 /**
@@ -86,8 +87,8 @@ private ModuleBootstrap() { }
     private static final String ALL_MODULE_PATH = "ALL-MODULE-PATH";
 
     // access to java.lang/module
-    private static final JavaLangModuleAccess JLMA
-        = SharedSecrets.getJavaLangModuleAccess();
+    private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
+    private static final JavaLangModuleAccess JLMA = SharedSecrets.getJavaLangModuleAccess();
 
     // The ModulePatcher for the initial configuration
     private static final ModulePatcher patcher = initModulePatcher();
@@ -134,14 +135,58 @@ public static ModuleFinder limitedFinder() {
     }
 
     /**
-     * Initialize the module system, returning the boot layer.
+     * Returns true if the archived boot layer can be used. The system properties
+     * are checked in the order that they are used by boot2.
+     */
+    private static boolean canUseArchivedBootLayer() {
+        return getProperty("jdk.module.upgrade.path") == null &&
+               getProperty("jdk.module.path") == null &&
+               getProperty("jdk.module.patch.0") == null &&    // --patch-module
+               getProperty("jdk.module.main") == null &&
+               getProperty("jdk.module.addmods.0") == null  && // --add-modules
+               getProperty("jdk.module.limitmods") == null &&
+               getProperty("jdk.module.addreads.0") == null &&    // --add-reads
+               getProperty("jdk.module.addexports.0") == null &&  // --add-exports
+               getProperty("jdk.module.addopens.0") == null &&    // --add-opens
+               getProperty("jdk.module.illegalAccess") == null;
+    }
+
+    /**
+     * Initialize the module system, returning the boot layer. The boot layer
+     * is obtained from the CDS archive if possible, otherwise it is generated
+     * from the module graph.
      *
      * @see java.lang.System#initPhase2(boolean, boolean)
      */
-    public static ModuleLayer boot() throws Exception {
-
+    public static ModuleLayer boot() {
         Counters.start();
 
+        ModuleLayer bootLayer;
+        ArchivedBootLayer archivedBootLayer = ArchivedBootLayer.get();
+        if (archivedBootLayer != null) {
+            assert canUseArchivedBootLayer();
+            bootLayer = archivedBootLayer.bootLayer();
+            BootLoader.getUnnamedModule(); // trigger <clinit> of BootLoader.
+            VM.defineArchivedModules(ClassLoaders.platformClassLoader(), ClassLoaders.appClassLoader());
+
+            // assume boot layer has at least one module providing a service
+            // that is mapped to the application class loader.
+            JLA.bindToLoader(bootLayer, ClassLoaders.appClassLoader());
+
+            // IllegalAccessLogger needs to be set
+            var illegalAccessLoggerBuilder = archivedBootLayer.illegalAccessLoggerBuilder();
+            if (illegalAccessLoggerBuilder != null) {
+                illegalAccessLoggerBuilder.complete();
+            }
+        } else {
+            bootLayer = boot2();
+        }
+
+        Counters.publish("jdk.module.boot.totalTime");
+        return bootLayer;
+    }
+
+    private static ModuleLayer boot2() {
         // Step 0: Command line options
 
         ModuleFinder upgradeModulePath = finderFor("jdk.module.upgrade.path");
@@ -428,11 +473,12 @@ public static ModuleLayer boot() throws Exception {
             concealedPackagesToOpen = systemModules.concealedPackagesToOpen();
             exportedPackagesToOpen = systemModules.exportedPackagesToOpen();
         }
-        addIllegalAccess(upgradeModulePath,
-                         concealedPackagesToOpen,
-                         exportedPackagesToOpen,
-                         bootLayer,
-                         extraExportsOrOpens);
+        IllegalAccessLogger.Builder builder =
+            addIllegalAccess(upgradeModulePath,
+                             concealedPackagesToOpen,
+                             exportedPackagesToOpen,
+                             bootLayer,
+                             extraExportsOrOpens);
         Counters.add("jdk.module.boot.7.adjustModulesTime");
 
         // save module finders for later use
@@ -442,22 +488,22 @@ public static ModuleLayer boot() throws Exception {
                 limitedFinder = new SafeModuleFinder(finder);
         }
 
-        // Module graph can be archived at CDS dump time. Only allow the
-        // unnamed module case for now.
+        // Archive module graph and boot layer can be archived at CDS dump time.
+        // Only allow the unnamed module case for now.
         if (canArchive && (mainModule == null)) {
-            ArchivedModuleGraph.archive(
-                    new ArchivedModuleGraph(hasSplitPackages,
-                                            hasIncubatorModules,
-                                            systemModuleFinder,
-                                            cf,
-                                            clf,
-                                            concealedPackagesToOpen,
-                                            exportedPackagesToOpen));
+            ArchivedModuleGraph.archive(hasSplitPackages,
+                                        hasIncubatorModules,
+                                        systemModuleFinder,
+                                        cf,
+                                        clf,
+                                        concealedPackagesToOpen,
+                                        exportedPackagesToOpen);
+
+            if (!hasSplitPackages && !hasIncubatorModules) {
+                ArchivedBootLayer.archive(bootLayer, builder);
+            }
         }
 
-        // total time to initialize
-        Counters.publish("jdk.module.boot.totalTime");
-
         return bootLayer;
     }
 
@@ -751,17 +797,18 @@ private static void addExtraExportsOrOpens(ModuleLayer bootLayer,
      * Process the --illegal-access option (and its default) to open packages
      * of system modules in the boot layer to code in unnamed modules.
      */
-    private static void addIllegalAccess(ModuleFinder upgradeModulePath,
-                                         Map<String, Set<String>> concealedPackagesToOpen,
-                                         Map<String, Set<String>> exportedPackagesToOpen,
-                                         ModuleLayer bootLayer,
-                                         boolean extraExportsOrOpens) {
+    private static IllegalAccessLogger.Builder
+        addIllegalAccess(ModuleFinder upgradeModulePath,
+                         Map<String, Set<String>> concealedPackagesToOpen,
+                         Map<String, Set<String>> exportedPackagesToOpen,
+                         ModuleLayer bootLayer,
+                         boolean extraExportsOrOpens) {
         String value = getAndRemoveProperty("jdk.module.illegalAccess");
         IllegalAccessLogger.Mode mode = IllegalAccessLogger.Mode.ONESHOT;
         if (value != null) {
             switch (value) {
                 case "deny":
-                    return;
+                    return null;
                 case "permit":
                     break;
                 case "warn":
@@ -773,7 +820,7 @@ private static void addIllegalAccess(ModuleFinder upgradeModulePath,
                 default:
                     fail("Value specified to --illegal-access not recognized:"
                             + " '" + value + "'");
-                    return;
+                    return null;
             }
         }
         IllegalAccessLogger.Builder builder
@@ -836,11 +883,11 @@ private static void addIllegalAccess(ModuleFinder upgradeModulePath,
             builder.logAccessToExportedPackages(m, exportedPackages);
 
             // open the packages to unnamed modules
-            JavaLangAccess jla = SharedSecrets.getJavaLangAccess();
-            jla.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
+            JLA.addOpensToAllUnnamed(m, concealedPackages, exportedPackages);
         }
 
         builder.complete();
+        return builder;
     }
 
     /**
@@ -905,11 +952,19 @@ private static Map<String, List<String>> decode(String prefix) {
         return decode(prefix, ",", true);
     }
 
+
+    /**
+     * Gets the named system property
+     */
+    private static String getProperty(String key) {
+        return System.getProperty(key);
+    }
+
     /**
      * Gets and remove the named system property
      */
     private static String getAndRemoveProperty(String key) {
-        return (String)System.getProperties().remove(key);
+        return (String) System.getProperties().remove(key);
     }
 
     /**
diff --git a/src/java.base/share/classes/jdk/internal/module/ServicesCatalog.java b/src/java.base/share/classes/jdk/internal/module/ServicesCatalog.java
index 811fbccb852..3590cf7c430 100644
--- a/src/java.base/share/classes/jdk/internal/module/ServicesCatalog.java
+++ b/src/java.base/share/classes/jdk/internal/module/ServicesCatalog.java
@@ -171,6 +171,16 @@ public static ServicesCatalog getServicesCatalog(ClassLoader loader) {
         return catalog;
     }
 
+    /**
+     * Associates the given ServicesCatalog with the given class loader.
+     */
+    public static void putServicesCatalog(ClassLoader loader, ServicesCatalog catalog) {
+        ServicesCatalog previous = CLV.putIfAbsent(loader, catalog);
+        if (previous != null) {
+            throw new InternalError();
+        }
+    }
+
     // the ServicesCatalog registered to a class loader
     private static final ClassLoaderValue<ServicesCatalog> CLV = new ClassLoaderValue<>();
 }
diff --git a/src/java.base/share/classes/sun/net/www/ParseUtil.java b/src/java.base/share/classes/sun/net/www/ParseUtil.java
index f8963225348..c73c52e15d8 100644
--- a/src/java.base/share/classes/sun/net/www/ParseUtil.java
+++ b/src/java.base/share/classes/sun/net/www/ParseUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,10 +34,10 @@
 import java.nio.CharBuffer;
 import java.nio.charset.CharacterCodingException;
 import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
 
-import sun.nio.cs.ThreadLocalCoders;
 import sun.nio.cs.UTF_8;
 
 /**
@@ -177,9 +177,9 @@ public static String decode(String s) {
         StringBuilder sb = new StringBuilder(n);
         ByteBuffer bb = ByteBuffer.allocate(n);
         CharBuffer cb = CharBuffer.allocate(n);
-        CharsetDecoder dec = ThreadLocalCoders.decoderFor(UTF_8.INSTANCE)
-            .onMalformedInput(CodingErrorAction.REPORT)
-            .onUnmappableCharacter(CodingErrorAction.REPORT);
+        CharsetDecoder dec = UTF_8.INSTANCE.newDecoder()
+                .onMalformedInput(CodingErrorAction.REPORT)
+                .onUnmappableCharacter(CodingErrorAction.REPORT);
 
         char c = s.charAt(0);
         for (int i = 0; i < n;) {
@@ -451,6 +451,7 @@ private static void appendFragment(StringBuilder sb, String fragment) {
     private static String quote(String s, long lowMask, long highMask) {
         int n = s.length();
         StringBuilder sb = null;
+        CharsetEncoder encoder = null;
         boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0);
         for (int i = 0; i < s.length(); i++) {
             char c = s.charAt(i);
@@ -468,11 +469,14 @@ private static String quote(String s, long lowMask, long highMask) {
             } else if (allowNonASCII
                        && (Character.isSpaceChar(c)
                            || Character.isISOControl(c))) {
+                if (encoder == null) {
+                    encoder = UTF_8.INSTANCE.newEncoder();
+                }
                 if (sb == null) {
                     sb = new StringBuilder();
                     sb.append(s, 0, i);
                 }
-                appendEncoded(sb, c);
+                appendEncoded(encoder, sb, c);
             } else {
                 if (sb != null)
                     sb.append(c);
@@ -494,11 +498,11 @@ && match(s.charAt(pos + 1), L_HEX, H_HEX)
                && match(s.charAt(pos + 2), L_HEX, H_HEX);
     }
 
-    private static void appendEncoded(StringBuilder sb, char c) {
+    private static void appendEncoded(CharsetEncoder encoder,
+                                      StringBuilder sb, char c) {
         ByteBuffer bb = null;
         try {
-            bb = ThreadLocalCoders.encoderFor(UTF_8.INSTANCE)
-                .encode(CharBuffer.wrap("" + c));
+            bb = encoder.encode(CharBuffer.wrap("" + c));
         } catch (CharacterCodingException x) {
             assert false;
         }
diff --git a/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java b/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java
index 860d5ff12c9..5c7356fca81 100644
--- a/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java
+++ b/src/java.base/share/classes/sun/reflect/annotation/TypeAnnotationParser.java
@@ -301,11 +301,12 @@ private static <D extends GenericDeclaration> AnnotatedType[] parseAnnotatedBoun
                         l.add(t);
                     }
                 }
+                TypeAnnotation[] typeAnnotations = l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY);
                 res[i] = AnnotatedTypeFactory.buildAnnotatedType(bounds[i],
                         AnnotatedTypeFactory.nestingForType(bounds[i], loc),
-                        l.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
-                        candidates.toArray(EMPTY_TYPE_ANNOTATION_ARRAY),
-                        (AnnotatedElement)decl);
+                        typeAnnotations,
+                        typeAnnotations,
+                        decl);
             }
             return res;
         }
diff --git a/src/java.base/share/classes/sun/security/provider/DSA.java b/src/java.base/share/classes/sun/security/provider/DSA.java
index b0d06c55727..a7c42a1f35a 100644
--- a/src/java.base/share/classes/sun/security/provider/DSA.java
+++ b/src/java.base/share/classes/sun/security/provider/DSA.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,11 +47,16 @@
  * Standards and Technology (NIST), using SHA digest algorithms
  * from FIPS180-3.
  *
- * This file contains both the signature implementation for the
- * commonly used SHA1withDSA (DSS), SHA224withDSA, SHA256withDSA,
- * as well as RawDSA, used by TLS among others. RawDSA expects
- * the 20 byte SHA-1 digest as input via update rather than the
- * original data like other signature implementations.
+ * This file contains the signature implementation for the
+ * SHA1withDSA (DSS), SHA224withDSA, SHA256withDSA, SHA384withDSA,
+ * SHA512withDSA, SHA3-224withDSA, SHA3-256withDSA, SHA3-384withDSA,
+ * SHA3-512withDSA, as well as RawDSA, used by TLS among others.
+ * RawDSA expects the 20 byte SHA-1 digest as input via update rather
+ * than the original data like other signature implementations.
+ *
+ * In addition, IEEE P1363 signature format is supported. The
+ * corresponding implementation is registered under <sig>inP1363Format,
+ * e.g. SHA256withDSAinP1363Format.
  *
  * @author Benjamin Renaud
  *
@@ -504,6 +509,78 @@ public String toString() {
         return printable;
     }
 
+    /**
+     * SHA3-224withDSA implementation.
+     */
+    public static final class SHA3_224withDSA extends DSA {
+        public SHA3_224withDSA() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA3-224"));
+        }
+    }
+
+    /**
+     * SHA3-224withDSA implementation that uses the IEEE P1363 format.
+     */
+    public static final class SHA3_224withDSAinP1363Format extends DSA {
+        public SHA3_224withDSAinP1363Format() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA3-224"), true);
+        }
+    }
+
+    /**
+     * Standard SHA3-256withDSA implementation.
+     */
+    public static final class SHA3_256withDSA extends DSA {
+        public SHA3_256withDSA() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA3-256"));
+        }
+    }
+
+    /**
+     * Standard SHA3-256withDSA implementation that uses the IEEE P1363 format.
+     */
+    public static final class SHA3_256withDSAinP1363Format extends DSA {
+        public SHA3_256withDSAinP1363Format() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA3-256"), true);
+        }
+    }
+
+    /**
+     * Standard SHA3-384withDSA implementation.
+     */
+    public static final class SHA3_384withDSA extends DSA {
+        public SHA3_384withDSA() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA3-384"));
+        }
+    }
+
+    /**
+     * Standard SHA3-384withDSA implementation that uses the IEEE P1363 format.
+     */
+    public static final class SHA3_384withDSAinP1363Format extends DSA {
+        public SHA3_384withDSAinP1363Format() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA3-384"), true);
+        }
+    }
+
+    /**
+     * Standard SHA3-512withDSA implementation.
+     */
+    public static final class SHA3_512withDSA extends DSA {
+        public SHA3_512withDSA() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA3-512"));
+        }
+    }
+
+    /**
+     * Standard SHA3-512withDSA implementation that uses the IEEE P1363 format.
+     */
+    public static final class SHA3_512withDSAinP1363Format extends DSA {
+        public SHA3_512withDSAinP1363Format() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA3-512"), true);
+        }
+    }
+
     /**
      * Standard SHA224withDSA implementation as defined in FIPS186-3.
      */
@@ -540,6 +617,42 @@ public SHA256withDSAinP1363Format() throws NoSuchAlgorithmException {
         }
     }
 
+    /**
+     * Standard SHA384withDSA implementation as defined in FIPS186-3.
+     */
+    public static final class SHA384withDSA extends DSA {
+        public SHA384withDSA() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA-384"));
+        }
+    }
+
+    /**
+     * SHA384withDSA implementation that uses the IEEE P1363 format.
+     */
+    public static final class SHA384withDSAinP1363Format extends DSA {
+        public SHA384withDSAinP1363Format() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA-384"), true);
+        }
+    }
+
+    /**
+     * Standard SHA512withDSA implementation as defined in FIPS186-3.
+     */
+    public static final class SHA512withDSA extends DSA {
+        public SHA512withDSA() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA-512"));
+        }
+    }
+
+    /**
+     * SHA512withDSA implementation that uses the IEEE P1363 format.
+     */
+    public static final class SHA512withDSAinP1363Format extends DSA {
+        public SHA512withDSAinP1363Format() throws NoSuchAlgorithmException {
+            super(MessageDigest.getInstance("SHA-512"), true);
+        }
+    }
+
     /**
      * Standard SHA1withDSA implementation.
      */
diff --git a/src/java.base/share/classes/sun/security/provider/SunEntries.java b/src/java.base/share/classes/sun/security/provider/SunEntries.java
index 79007f4d8ef..076c6e04f4f 100644
--- a/src/java.base/share/classes/sun/security/provider/SunEntries.java
+++ b/src/java.base/share/classes/sun/security/provider/SunEntries.java
@@ -54,9 +54,13 @@
  *   SHA-2 family of hash functions includes SHA-224, SHA-256, SHA-384,
  *   and SHA-512.
  *
- * - SHA-224withDSA/SHA-256withDSA are the signature schemes
+ * - [SHA-224|SHA-256|SHA-384|SHA-512]withDSA are the signature schemes
  *   described in FIPS 186-3. The associated object identifiers are
- *   "OID.2.16.840.1.101.3.4.3.1", and "OID.2.16.840.1.101.3.4.3.2".
+ *   "OID.2.16.840.1.101.3.4.3.[1|2|3|4]" respectively.
+ *
+ * - [SHA3-224|SHA3-256|SHA3-384|SHA3-512]withDSA are the signature schemes
+ *   using SHA-3 family of digests with DSA. The associated object identifiers
+ *   are "OID.2.16.840.1.101.3.4.3.[5|6|7|8]" respectively.
  *
  * - DSA is the key generation scheme as described in FIPS 186.
  *   Aliases for DSA include the OID strings "OID.1.3.14.3.2.12"
@@ -127,13 +131,30 @@ public final class SunEntries {
         addWithAlias(p, "Signature", "NONEwithDSA",
                 "sun.security.provider.DSA$RawDSA", attrs);
 
-        attrs.put("KeySize", "2048"); // for SHA224 and SHA256 DSA signatures
+        // for DSA signatures with 224/256-bit digests
+        attrs.put("KeySize", "2048");
 
         addWithAlias(p, "Signature", "SHA224withDSA",
                 "sun.security.provider.DSA$SHA224withDSA", attrs);
         addWithAlias(p, "Signature", "SHA256withDSA",
                 "sun.security.provider.DSA$SHA256withDSA", attrs);
 
+        addWithAlias(p, "Signature", "SHA3-224withDSA",
+                "sun.security.provider.DSA$SHA3_224withDSA", attrs);
+        addWithAlias(p, "Signature", "SHA3-256withDSA",
+                "sun.security.provider.DSA$SHA3_256withDSA", attrs);
+
+        attrs.put("KeySize", "3072"); // for DSA sig using 384/512-bit digests
+
+        addWithAlias(p, "Signature", "SHA384withDSA",
+                "sun.security.provider.DSA$SHA384withDSA", attrs);
+        addWithAlias(p, "Signature", "SHA512withDSA",
+                "sun.security.provider.DSA$SHA512withDSA", attrs);
+        addWithAlias(p, "Signature", "SHA3-384withDSA",
+                "sun.security.provider.DSA$SHA3_384withDSA", attrs);
+        addWithAlias(p, "Signature", "SHA3-512withDSA",
+                "sun.security.provider.DSA$SHA3_512withDSA", attrs);
+
         attrs.remove("KeySize");
 
         add(p, "Signature", "SHA1withDSAinP1363Format",
@@ -144,7 +165,18 @@ public final class SunEntries {
                 "sun.security.provider.DSA$SHA224withDSAinP1363Format");
         add(p, "Signature", "SHA256withDSAinP1363Format",
                 "sun.security.provider.DSA$SHA256withDSAinP1363Format");
-
+        add(p, "Signature", "SHA384withDSAinP1363Format",
+                "sun.security.provider.DSA$SHA384withDSAinP1363Format");
+        add(p, "Signature", "SHA512withDSAinP1363Format",
+                "sun.security.provider.DSA$SHA512withDSAinP1363Format");
+        add(p, "Signature", "SHA3-224withDSAinP1363Format",
+                "sun.security.provider.DSA$SHA3_224withDSAinP1363Format");
+        add(p, "Signature", "SHA3-256withDSAinP1363Format",
+                "sun.security.provider.DSA$SHA3_256withDSAinP1363Format");
+        add(p, "Signature", "SHA3-384withDSAinP1363Format",
+                "sun.security.provider.DSA$SHA3_384withDSAinP1363Format");
+        add(p, "Signature", "SHA3-512withDSAinP1363Format",
+                "sun.security.provider.DSA$SHA3_512withDSAinP1363Format");
         /*
          *  Key Pair Generator engines
          */
diff --git a/src/java.base/share/classes/sun/security/rsa/PSSParameters.java b/src/java.base/share/classes/sun/security/rsa/PSSParameters.java
index a4bdd4b5dca..fef496ed50c 100644
--- a/src/java.base/share/classes/sun/security/rsa/PSSParameters.java
+++ b/src/java.base/share/classes/sun/security/rsa/PSSParameters.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -103,7 +103,7 @@ protected void engineInit(byte[] encoded) throws IOException {
                     throw new IOException("Only MGF1 mgf is supported");
                 }
                 AlgorithmId params = AlgorithmId.parse(
-                    new DerValue(val.getEncodedParams()));
+                        new DerValue(val.getEncodedParams()));
                 String mgfDigestName = params.getName();
                 switch (mgfDigestName) {
                 case "SHA-1":
@@ -127,6 +127,18 @@ protected void engineInit(byte[] encoded) throws IOException {
                 case "SHA-512/256":
                     mgfSpec = MGF1ParameterSpec.SHA512_256;
                     break;
+                case "SHA3-224":
+                    mgfSpec = MGF1ParameterSpec.SHA3_224;
+                    break;
+                case "SHA3-256":
+                    mgfSpec = MGF1ParameterSpec.SHA3_256;
+                    break;
+                case "SHA3-384":
+                    mgfSpec = MGF1ParameterSpec.SHA3_384;
+                    break;
+                case "SHA3-512":
+                    mgfSpec = MGF1ParameterSpec.SHA3_512;
+                    break;
                 default:
                     throw new IOException
                         ("Unrecognized message digest algorithm " +
diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java b/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java
index e95408b9f62..85eb219a7d9 100644
--- a/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java
+++ b/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java
@@ -45,8 +45,8 @@
  * PKCS#1 v2.2 RSASSA-PSS signatures with various message digest algorithms.
  * RSASSA-PSS implementation takes the message digest algorithm, MGF algorithm,
  * and salt length values through the required signature PSS parameters.
- * We support SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and
- * SHA-512/256 message digest algorithms and MGF1 mask generation function.
+ * We support SHA-1, SHA-2 family and SHA3 family of message digest algorithms,
+ * and MGF1 mask generation function.
  *
  * @since   11
  */
@@ -81,24 +81,20 @@ private boolean isDigestEqual(String stdAlg, String givenAlg) {
 
     private static final byte[] EIGHT_BYTES_OF_ZEROS = new byte[8];
 
-    private static final Hashtable<String, Integer> DIGEST_LENGTHS =
-        new Hashtable<String, Integer>();
+    private static final Hashtable<KnownOIDs, Integer> DIGEST_LENGTHS =
+        new Hashtable<KnownOIDs, Integer>();
     static {
-        DIGEST_LENGTHS.put("SHA-1", 20);
-        DIGEST_LENGTHS.put("SHA", 20);
-        DIGEST_LENGTHS.put("SHA1", 20);
-        DIGEST_LENGTHS.put("SHA-224", 28);
-        DIGEST_LENGTHS.put("SHA224", 28);
-        DIGEST_LENGTHS.put("SHA-256", 32);
-        DIGEST_LENGTHS.put("SHA256", 32);
-        DIGEST_LENGTHS.put("SHA-384", 48);
-        DIGEST_LENGTHS.put("SHA384", 48);
-        DIGEST_LENGTHS.put("SHA-512", 64);
-        DIGEST_LENGTHS.put("SHA512", 64);
-        DIGEST_LENGTHS.put("SHA-512/224", 28);
-        DIGEST_LENGTHS.put("SHA512/224", 28);
-        DIGEST_LENGTHS.put("SHA-512/256", 32);
-        DIGEST_LENGTHS.put("SHA512/256", 32);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA_1, 20);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA_224, 28);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA_256, 32);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA_384, 48);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA_512, 64);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA_512$224, 28);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA_512$256, 32);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA3_224, 28);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA3_256, 32);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA3_384, 48);
+        DIGEST_LENGTHS.put(KnownOIDs.SHA3_512, 64);
     }
 
     // message digest implementation we use for hashing the data
@@ -210,27 +206,33 @@ private static boolean isCompatible(AlgorithmParameterSpec keyParams,
      * internal signature parameters.
      */
     private RSAKey isValid(RSAKey rsaKey) throws InvalidKeyException {
-        try {
-            AlgorithmParameterSpec keyParams = rsaKey.getParams();
-            // validate key parameters
-            if (!isCompatible(rsaKey.getParams(), this.sigParams)) {
-                throw new InvalidKeyException
-                    ("Key contains incompatible PSS parameter values");
-            }
-            // validate key length
-            if (this.sigParams != null) {
-                Integer hLen =
-                    DIGEST_LENGTHS.get(this.sigParams.getDigestAlgorithm());
-                if (hLen == null) {
-                    throw new ProviderException("Unsupported digest algo: " +
-                        this.sigParams.getDigestAlgorithm());
+        AlgorithmParameterSpec keyParams = rsaKey.getParams();
+        // validate key parameters
+        if (!isCompatible(rsaKey.getParams(), this.sigParams)) {
+            throw new InvalidKeyException
+                ("Key contains incompatible PSS parameter values");
+        }
+        // validate key length
+        if (this.sigParams != null) {
+            String digestAlgo = this.sigParams.getDigestAlgorithm();
+            KnownOIDs ko = KnownOIDs.findMatch(digestAlgo);
+            if (ko != null) {
+                Integer hLen = DIGEST_LENGTHS.get(ko);
+                if (hLen != null) {
+                    checkKeyLength(rsaKey, hLen,
+                            this.sigParams.getSaltLength());
+                } else {
+                    // should never happen; checked in validateSigParams()
+                    throw new ProviderException
+                            ("Unsupported digest algo: " + digestAlgo);
                 }
-                checkKeyLength(rsaKey, hLen, this.sigParams.getSaltLength());
+            } else {
+                // should never happen; checked in validateSigParams()
+                throw new ProviderException
+                        ("Unrecognized digest algo: " + digestAlgo);
             }
-            return rsaKey;
-        } catch (SignatureException e) {
-            throw new InvalidKeyException(e);
         }
+        return rsaKey;
     }
 
     /**
@@ -268,14 +270,26 @@ private PSSParameterSpec validateSigParams(AlgorithmParameterSpec p)
                 ("Only supports TrailerFieldBC(1)");
 
         }
-        String digestAlgo = params.getDigestAlgorithm();
+
         // check key length again
         if (key != null) {
-            try {
-                int hLen = DIGEST_LENGTHS.get(digestAlgo);
-                checkKeyLength(key, hLen, params.getSaltLength());
-            } catch (SignatureException e) {
-                throw new InvalidAlgorithmParameterException(e);
+            String digestAlgo = params.getDigestAlgorithm();
+            KnownOIDs ko = KnownOIDs.findMatch(digestAlgo);
+            if (ko != null) {
+                Integer hLen = DIGEST_LENGTHS.get(ko);
+                if (hLen != null) {
+                    try {
+                        checkKeyLength(key, hLen, params.getSaltLength());
+                    } catch (InvalidKeyException e) {
+                        throw new InvalidAlgorithmParameterException(e);
+                    }
+                } else {
+                    throw new InvalidAlgorithmParameterException
+                            ("Unsupported digest algo: " + digestAlgo);
+                }
+            } else {
+                throw new InvalidAlgorithmParameterException
+                        ("Unrecognized digest algo: " + digestAlgo);
             }
         }
         return params;
@@ -302,12 +316,12 @@ private void ensureInit() throws SignatureException {
      * salt length
      */
     private static void checkKeyLength(RSAKey key, int digestLen,
-            int saltLen) throws SignatureException {
+            int saltLen) throws InvalidKeyException {
         if (key != null) {
             int keyLength = (getKeyLengthInBits(key) + 7) >> 3;
             int minLength = Math.addExact(Math.addExact(digestLen, saltLen), 2);
             if (keyLength < minLength) {
-                throw new SignatureException
+                throw new InvalidKeyException
                     ("Key is too short, need min " + minLength + " bytes");
             }
         }
diff --git a/src/java.base/share/classes/sun/security/rsa/RSASignature.java b/src/java.base/share/classes/sun/security/rsa/RSASignature.java
index ea2ef985082..795d5c59020 100644
--- a/src/java.base/share/classes/sun/security/rsa/RSASignature.java
+++ b/src/java.base/share/classes/sun/security/rsa/RSASignature.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,8 +40,9 @@
  * PKCS#1 v1.5 RSA signatures with the various message digest algorithms.
  * This file contains an abstract base class with all the logic plus
  * a nested static class for each of the message digest algorithms
- * (see end of the file). We support MD2, MD5, SHA-1, SHA-224, SHA-256,
- * SHA-384, SHA-512, SHA-512/224, and SHA-512/256.
+ * (see end of the file). We support MD2, MD5, SHA-1, SHA2 family (
+ * SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and SHA-512/256),
+ * and SHA3 family (SHA3-224, SHA3-256, SHA3-384, SHA3-512) of digests.
  *
  * @since   1.5
  * @author  Andreas Sterbenz
@@ -360,4 +361,32 @@ public SHA512_256withRSA() {
             super("SHA-512/256", AlgorithmId.SHA512_256_oid, 11);
         }
     }
+
+    // Nested class for SHA3-224withRSA signatures
+    public static final class SHA3_224withRSA extends RSASignature {
+        public SHA3_224withRSA() {
+            super("SHA3-224", AlgorithmId.SHA3_224_oid, 11);
+        }
+    }
+
+    // Nested class for SHA3-256withRSA signatures
+    public static final class SHA3_256withRSA extends RSASignature {
+        public SHA3_256withRSA() {
+            super("SHA3-256", AlgorithmId.SHA3_256_oid, 11);
+        }
+    }
+
+    // Nested class for SHA3-384withRSA signatures
+    public static final class SHA3_384withRSA extends RSASignature {
+        public SHA3_384withRSA() {
+            super("SHA3-384", AlgorithmId.SHA3_384_oid, 11);
+        }
+    }
+
+    // Nested class for SHA3-512withRSA signatures
+    public static final class SHA3_512withRSA extends RSASignature {
+        public SHA3_512withRSA() {
+            super("SHA3-512", AlgorithmId.SHA3_512_oid, 11);
+        }
+    }
 }
diff --git a/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java b/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java
index f3edf4f25e1..ca79f25cc44 100644
--- a/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java
+++ b/src/java.base/share/classes/sun/security/rsa/SunRsaSignEntries.java
@@ -84,6 +84,14 @@ public SunRsaSignEntries(Provider p) {
                 "sun.security.rsa.RSASignature$SHA512_224withRSA", attrs);
         addA(p, "Signature", "SHA512/256withRSA",
                 "sun.security.rsa.RSASignature$SHA512_256withRSA", attrs);
+        addA(p, "Signature", "SHA3-224withRSA",
+                "sun.security.rsa.RSASignature$SHA3_224withRSA", attrs);
+        addA(p, "Signature", "SHA3-256withRSA",
+                "sun.security.rsa.RSASignature$SHA3_256withRSA", attrs);
+        addA(p, "Signature", "SHA3-384withRSA",
+               "sun.security.rsa.RSASignature$SHA3_384withRSA", attrs);
+        addA(p, "Signature", "SHA3-512withRSA",
+                "sun.security.rsa.RSASignature$SHA3_512withRSA", attrs);
 
         addA(p, "KeyFactory", "RSASSA-PSS",
                 "sun.security.rsa.RSAKeyFactory$PSS", attrs);
@@ -92,7 +100,7 @@ public SunRsaSignEntries(Provider p) {
         addA(p, "Signature", "RSASSA-PSS",
                 "sun.security.rsa.RSAPSSSignature", attrs);
         addA(p, "AlgorithmParameters", "RSASSA-PSS",
-                "sun.security.rsa.PSSParameters", attrs);
+                "sun.security.rsa.PSSParameters", null);
     }
 
     public Iterator<Provider.Service> iterator() {
diff --git a/src/java.base/share/classes/sun/security/util/KnownOIDs.java b/src/java.base/share/classes/sun/security/util/KnownOIDs.java
index f7eff259c4b..ac519dc2886 100644
--- a/src/java.base/share/classes/sun/security/util/KnownOIDs.java
+++ b/src/java.base/share/classes/sun/security/util/KnownOIDs.java
@@ -154,6 +154,14 @@ public enum KnownOIDs {
     SHA256withDSA("2.16.840.1.101.3.4.3.2"),
     SHA384withDSA("2.16.840.1.101.3.4.3.3"),
     SHA512withDSA("2.16.840.1.101.3.4.3.4"),
+    SHA3_224withDSA("2.16.840.1.101.3.4.3.5", "SHA3-224withDSA"),
+    SHA3_256withDSA("2.16.840.1.101.3.4.3.6", "SHA3-256withDSA"),
+    SHA3_384withDSA("2.16.840.1.101.3.4.3.7", "SHA3-384withDSA"),
+    SHA3_512withDSA("2.16.840.1.101.3.4.3.8", "SHA3-512withDSA"),
+    SHA3_224withECDSA("2.16.840.1.101.3.4.3.9", "SHA3-224withECDSA"),
+    SHA3_256withECDSA("2.16.840.1.101.3.4.3.10", "SHA3-256withECDSA"),
+    SHA3_384withECDSA("2.16.840.1.101.3.4.3.11", "SHA3-384withECDSA"),
+    SHA3_512withECDSA("2.16.840.1.101.3.4.3.12", "SHA3-512withECDSA"),
     SHA3_224withRSA("2.16.840.1.101.3.4.3.13", "SHA3-224withRSA"),
     SHA3_256withRSA("2.16.840.1.101.3.4.3.14", "SHA3-256withRSA"),
     SHA3_384withRSA("2.16.840.1.101.3.4.3.15", "SHA3-384withRSA"),
@@ -429,9 +437,9 @@ public static KnownOIDs findMatch(String s) {
         if (debug != null) {
             debug.println("Setting up name2enum:");
         }
-        List.of(KnownOIDs.values()).forEach(o -> {
+        for (KnownOIDs o : KnownOIDs.values()) {
             register(o);
-        });
+        };
     }
 
     private static void register(KnownOIDs o) {
diff --git a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java
index 8351bfa8168..b9b96b31c91 100644
--- a/src/java.base/share/classes/sun/security/x509/AlgorithmId.java
+++ b/src/java.base/share/classes/sun/security/x509/AlgorithmId.java
@@ -196,6 +196,10 @@ public void derEncode (OutputStream out) throws IOException {
                 algid.equals((Object)SHA512_oid) ||
                 algid.equals((Object)SHA512_224_oid) ||
                 algid.equals((Object)SHA512_256_oid) ||
+                algid.equals((Object)SHA3_224_oid) ||
+                algid.equals((Object)SHA3_256_oid) ||
+                algid.equals((Object)SHA3_384_oid) ||
+                algid.equals((Object)SHA3_512_oid) ||
                 algid.equals((Object)DSA_oid) ||
                 algid.equals((Object)sha1WithDSA_oid)) {
                 ; // no parameter part encoded
@@ -608,6 +612,18 @@ private static ConcurrentHashMap<String, String> collectOIDAliases() {
     public static final ObjectIdentifier SHA512_256_oid =
             ObjectIdentifier.of(KnownOIDs.SHA_512$256);
 
+    public static final ObjectIdentifier SHA3_224_oid =
+            ObjectIdentifier.of(KnownOIDs.SHA3_224);
+
+    public static final ObjectIdentifier SHA3_256_oid =
+            ObjectIdentifier.of(KnownOIDs.SHA3_256);
+
+    public static final ObjectIdentifier SHA3_384_oid =
+            ObjectIdentifier.of(KnownOIDs.SHA3_384);
+
+    public static final ObjectIdentifier SHA3_512_oid =
+            ObjectIdentifier.of(KnownOIDs.SHA3_512);
+
     public static final ObjectIdentifier DSA_oid =
             ObjectIdentifier.of(KnownOIDs.DSA);
 
diff --git a/src/java.base/share/native/libjava/VM.c b/src/java.base/share/native/libjava/VM.c
index 1cf694475da..ffc7e680014 100644
--- a/src/java.base/share/native/libjava/VM.c
+++ b/src/java.base/share/native/libjava/VM.c
@@ -62,6 +62,13 @@ Java_jdk_internal_misc_VM_initializeFromArchive(JNIEnv *env, jclass ignore,
     JVM_InitializeFromArchive(env, c);
 }
 
+JNIEXPORT void JNICALL
+Java_jdk_internal_misc_VM_defineArchivedModules(JNIEnv *env, jclass ignore,
+                                                jobject platform_loader,
+                                                jobject system_loader) {
+    JVM_DefineArchivedModules(env, platform_loader, system_loader);
+}
+
 JNIEXPORT jlong JNICALL
 Java_jdk_internal_misc_VM_getRandomSeedForCDSDump(JNIEnv *env, jclass ignore) {
     return JVM_GetRandomSeedForCDSDump();
diff --git a/src/java.compiler/share/classes/javax/tools/ForwardingFileObject.java b/src/java.compiler/share/classes/javax/tools/ForwardingFileObject.java
index 9270df3745f..ac776f3f290 100644
--- a/src/java.compiler/share/classes/javax/tools/ForwardingFileObject.java
+++ b/src/java.compiler/share/classes/javax/tools/ForwardingFileObject.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -50,17 +50,19 @@ public class ForwardingFileObject<F extends FileObject> implements FileObject {
     protected final F fileObject;
 
     /**
-     * Creates a new instance of ForwardingFileObject.
+     * Creates a new instance of {@code ForwardingFileObject}.
      * @param fileObject delegate to this file object
      */
     protected ForwardingFileObject(F fileObject) {
         this.fileObject = Objects.requireNonNull(fileObject);
     }
 
+    @Override
     public URI toUri() {
         return fileObject.toUri();
     }
 
+    @Override
     public String getName() {
         return fileObject.getName();
     }
@@ -70,6 +72,7 @@ public String getName() {
      * @throws UnsupportedOperationException {@inheritDoc}
      * @throws IOException {@inheritDoc}
      */
+    @Override
     public InputStream openInputStream() throws IOException {
         return fileObject.openInputStream();
     }
@@ -79,6 +82,7 @@ public InputStream openInputStream() throws IOException {
      * @throws UnsupportedOperationException {@inheritDoc}
      * @throws IOException {@inheritDoc}
      */
+    @Override
     public OutputStream openOutputStream() throws IOException {
         return fileObject.openOutputStream();
     }
@@ -88,6 +92,7 @@ public OutputStream openOutputStream() throws IOException {
      * @throws UnsupportedOperationException {@inheritDoc}
      * @throws IOException {@inheritDoc}
      */
+    @Override
     public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
         return fileObject.openReader(ignoreEncodingErrors);
     }
@@ -97,6 +102,7 @@ public Reader openReader(boolean ignoreEncodingErrors) throws IOException {
      * @throws UnsupportedOperationException {@inheritDoc}
      * @throws IOException {@inheritDoc}
      */
+    @Override
     public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
         return fileObject.getCharContent(ignoreEncodingErrors);
     }
@@ -106,14 +112,17 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept
      * @throws UnsupportedOperationException {@inheritDoc}
      * @throws IOException {@inheritDoc}
      */
+    @Override
     public Writer openWriter() throws IOException {
         return fileObject.openWriter();
     }
 
+    @Override
     public long getLastModified() {
         return fileObject.getLastModified();
     }
 
+    @Override
     public boolean delete() {
         return fileObject.delete();
     }
diff --git a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java
index 1a15c88c032..479c90e9ba9 100644
--- a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java
+++ b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,7 +49,7 @@ public class ForwardingJavaFileManager<M extends JavaFileManager> implements Jav
     protected final M fileManager;
 
     /**
-     * Creates a new instance of ForwardingJavaFileManager.
+     * Creates a new instance of {@code ForwardingJavaFileManager}.
      * @param fileManager delegate to this file manager
      */
     protected ForwardingJavaFileManager(M fileManager) {
@@ -60,6 +60,7 @@ protected ForwardingJavaFileManager(M fileManager) {
      * @throws SecurityException {@inheritDoc}
      * @throws IllegalStateException {@inheritDoc}
      */
+    @Override
     public ClassLoader getClassLoader(Location location) {
         return fileManager.getClassLoader(location);
     }
@@ -68,6 +69,7 @@ public ClassLoader getClassLoader(Location location) {
      * @throws IOException {@inheritDoc}
      * @throws IllegalStateException {@inheritDoc}
      */
+    @Override
     public Iterable<JavaFileObject> list(Location location,
                                          String packageName,
                                          Set<Kind> kinds,
@@ -80,6 +82,7 @@ public Iterable<JavaFileObject> list(Location location,
     /**
      * @throws IllegalStateException {@inheritDoc}
      */
+    @Override
     public String inferBinaryName(Location location, JavaFileObject file) {
         return fileManager.inferBinaryName(location, file);
     }
@@ -87,6 +90,7 @@ public String inferBinaryName(Location location, JavaFileObject file) {
     /**
      * @throws IllegalArgumentException {@inheritDoc}
      */
+    @Override
     public boolean isSameFile(FileObject a, FileObject b) {
         return fileManager.isSameFile(a, b);
     }
@@ -95,14 +99,17 @@ public boolean isSameFile(FileObject a, FileObject b) {
      * @throws IllegalArgumentException {@inheritDoc}
      * @throws IllegalStateException {@inheritDoc}
      */
+    @Override
     public boolean handleOption(String current, Iterator<String> remaining) {
         return fileManager.handleOption(current, remaining);
     }
 
+    @Override
     public boolean hasLocation(Location location) {
         return fileManager.hasLocation(location);
     }
 
+    @Override
     public int isSupportedOption(String option) {
         return fileManager.isSupportedOption(option);
     }
@@ -111,6 +118,7 @@ public int isSupportedOption(String option) {
      * @throws IllegalArgumentException {@inheritDoc}
      * @throws IllegalStateException {@inheritDoc}
      */
+    @Override
     public JavaFileObject getJavaFileForInput(Location location,
                                               String className,
                                               Kind kind)
@@ -123,6 +131,7 @@ public JavaFileObject getJavaFileForInput(Location location,
      * @throws IllegalArgumentException {@inheritDoc}
      * @throws IllegalStateException {@inheritDoc}
      */
+    @Override
     public JavaFileObject getJavaFileForOutput(Location location,
                                                String className,
                                                Kind kind,
@@ -136,6 +145,7 @@ public JavaFileObject getJavaFileForOutput(Location location,
      * @throws IllegalArgumentException {@inheritDoc}
      * @throws IllegalStateException {@inheritDoc}
      */
+    @Override
     public FileObject getFileForInput(Location location,
                                       String packageName,
                                       String relativeName)
@@ -148,6 +158,7 @@ public FileObject getFileForInput(Location location,
      * @throws IllegalArgumentException {@inheritDoc}
      * @throws IllegalStateException {@inheritDoc}
      */
+    @Override
     public FileObject getFileForOutput(Location location,
                                        String packageName,
                                        String relativeName,
@@ -157,10 +168,12 @@ public FileObject getFileForOutput(Location location,
         return fileManager.getFileForOutput(location, packageName, relativeName, sibling);
     }
 
+    @Override
     public void flush() throws IOException {
         fileManager.flush();
     }
 
+    @Override
     public void close() throws IOException {
         fileManager.close();
     }
@@ -169,6 +182,7 @@ public void close() throws IOException {
      * @since 9
      * @spec JPMS
      */
+    @Override
     public Location getLocationForModule(Location location, String moduleName) throws IOException {
         return fileManager.getLocationForModule(location, moduleName);
     }
@@ -177,6 +191,7 @@ public Location getLocationForModule(Location location, String moduleName) throw
      * @since 9
      * @spec JPMS
      */
+    @Override
     public Location getLocationForModule(Location location, JavaFileObject fo) throws IOException {
         return fileManager.getLocationForModule(location, fo);
     }
@@ -185,6 +200,7 @@ public Location getLocationForModule(Location location, JavaFileObject fo) throw
      * @since 9
      * @spec JPMS
      */
+    @Override
     public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws  IOException {
         return fileManager.getServiceLoader(location, service);
     }
@@ -193,6 +209,7 @@ public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service
      * @since 9
      * @spec JPMS
      */
+    @Override
     public String inferModuleName(Location location) throws IOException {
         return fileManager.inferModuleName(location);
     }
@@ -201,6 +218,7 @@ public String inferModuleName(Location location) throws IOException {
      * @since 9
      * @spec JPMS
      */
+    @Override
     public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
         return fileManager.listLocationsForModules(location);
     }
@@ -208,6 +226,7 @@ public Iterable<Set<Location>> listLocationsForModules(Location location) throws
     /**
      * @since 9
      */
+    @Override
     public boolean contains(Location location, FileObject fo) throws IOException {
         return fileManager.contains(location, fo);
     }
diff --git a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileObject.java b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileObject.java
index b0b3e9d40fd..bf7ad8f70ad 100644
--- a/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileObject.java
+++ b/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileObject.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,23 +43,27 @@ public class ForwardingJavaFileObject<F extends JavaFileObject>
 {
 
     /**
-     * Creates a new instance of ForwardingJavaFileObject.
+     * Creates a new instance of {@code ForwardingJavaFileObject}.
      * @param fileObject delegate to this file object
      */
     protected ForwardingJavaFileObject(F fileObject) {
         super(fileObject);
     }
 
+    @Override
     public Kind getKind() {
         return fileObject.getKind();
     }
 
+    @Override
     public boolean isNameCompatible(String simpleName, Kind kind) {
         return fileObject.isNameCompatible(simpleName, kind);
     }
 
+    @Override
     public NestingKind getNestingKind() { return fileObject.getNestingKind(); }
 
+    @Override
     public Modifier getAccessLevel()  { return fileObject.getAccessLevel(); }
 
 }
diff --git a/src/java.compiler/share/classes/javax/tools/JavaFileObject.java b/src/java.compiler/share/classes/javax/tools/JavaFileObject.java
index 14a4fa9e698..48d6388df9e 100644
--- a/src/java.compiler/share/classes/javax/tools/JavaFileObject.java
+++ b/src/java.compiler/share/classes/javax/tools/JavaFileObject.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -63,8 +63,7 @@ enum Kind {
         CLASS(".class"),
 
         /**
-         * HTML files.  For example, regular files ending with {@code
-         * .html}.
+         * HTML files.  For example, regular files ending with {@code .html}.
          */
         HTML(".html"),
 
@@ -78,7 +77,7 @@ enum Kind {
          * empty string ({@code ""}) is used.
          */
         public final String extension;
-        private Kind(String extension) {
+        Kind(String extension) {
             this.extension = Objects.requireNonNull(extension);
         }
     }
@@ -94,12 +93,11 @@ private Kind(String extension) {
      * Checks if this file object is compatible with the specified
      * simple name and kind.  A simple name is a single identifier
      * (not qualified) as defined in
-     * <cite>The Java Language Specification</cite>,
-     * section 6.2 "Names and Identifiers".
+     * <cite>The Java Language Specification</cite>, section {@jls 6.2}.
      *
      * @param simpleName a simple name of a class
      * @param kind a kind
-     * @return {@code true} if this file object is compatible; false
+     * @return {@code true} if this file object is compatible; {@code false}
      * otherwise
      */
     boolean isNameCompatible(String simpleName, Kind kind);
@@ -119,7 +117,7 @@ private Kind(String extension) {
 
     /**
      * Provides a hint about the access level of the class represented
-     * by this file object.  If the access level is not known or if
+     * by this file object.  If the access level is not known or
      * this file object does not represent a class file this method
      * returns {@code null}.
      *
diff --git a/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java b/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java
index a2905b91356..9c8d491996a 100644
--- a/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java
+++ b/src/java.compiler/share/classes/javax/tools/SimpleJavaFileObject.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,7 +31,6 @@
 import java.util.Objects;
 import javax.lang.model.element.Modifier;
 import javax.lang.model.element.NestingKind;
-import javax.tools.JavaFileObject.Kind;
 
 /**
  * Provides simple implementations for most methods in JavaFileObject.
diff --git a/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java b/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java
index ab04e859795..2fee7e2673a 100644
--- a/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java
+++ b/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,7 @@
 import java.util.List;
 
 /**
- * File manager based on {@linkplain File java.io.File} and {@linkplain Path java.nio.file.Path}.
+ * File manager based on {@link File java.io.File} and {@link Path java.nio.file.Path}.
  *
  * A common way to obtain an instance of this class is using
  * {@linkplain JavaCompiler#getStandardFileManager getStandardFileManager}, for example:
@@ -363,7 +363,7 @@ default void setLocationFromPaths(Location location, Collection<? extends Path>
      *
      * All such module-specific associations will be cancelled if a
      * new search path is associated with the location by calling
-     * {@linkplain #setLocation setLocation } or
+     * {@linkplain #setLocation setLocation} or
      * {@linkplain #setLocationFromPaths setLocationFromPaths}.
      *
      * @throws IllegalStateException if the location is not a module-oriented
@@ -377,8 +377,8 @@ default void setLocationFromPaths(Location location, Collection<? extends Path>
      * @param moduleName the name of the module
      * @param paths the search path to associate with the location and module.
      *
-     * @see setLocation
-     * @see setLocationFromPaths
+     * @see #setLocation
+     * @see #setLocationFromPaths
      *
      * @since 9
      */
@@ -480,8 +480,8 @@ default void setPathFactory(PathFactory f) { }
 
 
     private static Iterable<Path> asPaths(final Iterable<? extends File> files) {
-        return () -> new Iterator<Path>() {
-            Iterator<? extends File> iter = files.iterator();
+        return () -> new Iterator<>() {
+            final Iterator<? extends File> iter = files.iterator();
 
             @Override
             public boolean hasNext() {
@@ -496,8 +496,8 @@ public Path next() {
     }
 
     private static Iterable<File> asFiles(final Iterable<? extends Path> paths) {
-        return () -> new Iterator<File>() {
-            Iterator<? extends Path> iter = paths.iterator();
+        return () -> new Iterator<>() {
+            final Iterator<? extends Path> iter = paths.iterator();
 
             @Override
             public boolean hasNext() {
diff --git a/src/java.compiler/share/classes/javax/tools/package-info.java b/src/java.compiler/share/classes/javax/tools/package-info.java
index e7883f9be74..c5ec54e7871 100644
--- a/src/java.compiler/share/classes/javax/tools/package-info.java
+++ b/src/java.compiler/share/classes/javax/tools/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,25 +32,25 @@
  * but there is no requirement to provide any tools implementing them.
  *
  * <p>Unless explicitly allowed, all methods in this package might
- * throw a {@linkplain java.lang.NullPointerException} if given a
+ * throw a {@link java.lang.NullPointerException} if given a
  * {@code null} argument or if given a
  * {@linkplain java.lang.Iterable list or collection} containing
  * {@code null} elements.  Similarly, no method may return
  * {@code null} unless explicitly allowed.
  *
- * <p>This package is the home of the Java programming language compiler framework.  This
- * framework allows clients of the framework to locate and run
+ * <p>This package is the home of the Java programming language compiler framework.
+ * This framework allows clients of the framework to locate and run
  * compilers from programs.  The framework also provides Service
  * Provider Interfaces (SPI) for structured access to diagnostics
- * ({@linkplain javax.tools.DiagnosticListener}) as well as a file
- * abstraction for overriding file access ({@linkplain
- * javax.tools.JavaFileManager} and {@linkplain
- * javax.tools.JavaFileObject}).  See {@linkplain
+ * ({@link javax.tools.DiagnosticListener}) as well as a file
+ * abstraction for overriding file access ({@link
+ * javax.tools.JavaFileManager} and {@link
+ * javax.tools.JavaFileObject}).  See {@link
  * javax.tools.JavaCompiler} for more details on using the SPI.
  *
  * <p>There is no requirement for a compiler at runtime.  However, if
  * a default compiler is provided, it can be located using the
- * {@linkplain javax.tools.ToolProvider}, for example:
+ * {@link javax.tools.ToolProvider}, for example:
  *
  * <p>{@code JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();}
  *
diff --git a/src/java.desktop/share/classes/javax/imageio/stream/MemoryCache.java b/src/java.desktop/share/classes/javax/imageio/stream/MemoryCache.java
index 04d32e6d959..2b0fdd98d60 100644
--- a/src/java.desktop/share/classes/javax/imageio/stream/MemoryCache.java
+++ b/src/java.desktop/share/classes/javax/imageio/stream/MemoryCache.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -333,7 +333,7 @@ public void read(byte[] b, int off, int len, long pos)
         }
 
         long index = pos/BUFFER_LENGTH;
-        int offset = (int)pos % BUFFER_LENGTH;
+        int offset = (int)(pos % BUFFER_LENGTH);
         while (len > 0) {
             int nbytes = Math.min(len, BUFFER_LENGTH - offset);
             byte[] buf = getCacheBlock(index++);
diff --git a/src/java.desktop/share/classes/javax/swing/Box.java b/src/java.desktop/share/classes/javax/swing/Box.java
index 9db52ce9a0e..85983abddc1 100644
--- a/src/java.desktop/share/classes/javax/swing/Box.java
+++ b/src/java.desktop/share/classes/javax/swing/Box.java
@@ -316,6 +316,7 @@ public Filler(Dimension min, Dimension pref, Dimension max) {
             setMinimumSize(min);
             setPreferredSize(pref);
             setMaximumSize(max);
+            setFocusable(false);
         }
 
         /**
diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java b/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java
index cdb77128357..ef587bca480 100644
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultLdapDnsProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,14 +25,14 @@
 
 package com.sun.jndi.ldap;
 
-import javax.naming.NamingException;
-import javax.naming.ldap.spi.LdapDnsProvider;
-import javax.naming.ldap.spi.LdapDnsProviderResult;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
+import javax.naming.NamingException;
+import javax.naming.ldap.spi.LdapDnsProviderResult;
+
 public class DefaultLdapDnsProvider {
 
     public Optional<LdapDnsProviderResult> lookupEndpoints(String url,
@@ -82,5 +82,4 @@ public Optional<LdapDnsProviderResult> lookupEndpoints(String url,
             return Optional.of(res);
         }
     }
-
 }
diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java
index 1d6ac817f0b..b5f6fd05c11 100644
--- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java
+++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -87,7 +87,7 @@ static LdapDnsProviderService getInstance() {
      * subclasses of {@code LdapDnsProvider} then this method will fall back
      * to the {@code DefaultLdapDnsProvider}.
      *
-     * @throws NamingException if the {@code url} in not valid or an error
+     * @throws NamingException if the {@code url} is not valid or an error
      *                         occurred while performing the lookup.
      */
     LdapDnsProviderResult lookupEndpoints(String url, Hashtable<?,?> env)
@@ -110,5 +110,4 @@ LdapDnsProviderResult lookupEndpoints(String url, Hashtable<?,?> env)
         }
         return result;
     }
-
 }
diff --git a/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java b/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java
index abafef64685..d89436f188a 100644
--- a/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java
+++ b/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -105,5 +105,4 @@ private static Void checkPermission() {
      */
     public abstract Optional<LdapDnsProviderResult> lookupEndpoints(
             String url, Map<?,?> env) throws NamingException;
-
 }
diff --git a/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProviderResult.java b/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProviderResult.java
index d28326bb7e7..9427c256c26 100644
--- a/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProviderResult.java
+++ b/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProviderResult.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,7 @@
  *
  * <p> This class is used by an {@link LdapDnsProvider} to return the result
  * of a DNS lookup for a given LDAP URL. The result consists of a domain name
- * and its associated ldap server endpoints.
+ * and its associated LDAP server endpoints.
  *
  * <p> A {@code null} {@code domainName} is equivalent to and represented
  * by an empty string.
@@ -46,10 +46,10 @@ public final class LdapDnsProviderResult {
 
     /**
      * Construct an LdapDnsProviderResult consisting of a resolved domain name
-     * and the ldap server endpoints that serve the domain.
+     * and the LDAP server endpoints that serve the domain.
      *
      * @param domainName    the resolved domain name; can be null.
-     * @param endpoints     the possibly empty list of resolved ldap server
+     * @param endpoints     the possibly empty list of resolved LDAP server
      *                      endpoints
      *
      * @throws NullPointerException   if {@code endpoints} contains {@code null}
@@ -63,7 +63,7 @@ public LdapDnsProviderResult(String domainName, List<String> endpoints) {
     }
 
     /**
-     * Returns the domain name resolved from the ldap URL. This method returns
+     * Returns the domain name resolved from the LDAP URL. This method returns
      * the empty string if the {@code LdapDnsProviderResult} is created with a
      * null domain name.
      *
@@ -75,13 +75,12 @@ public String getDomainName() {
 
     /**
      * Returns the possibly empty list of individual server endpoints resolved
-     * from the ldap URL.
+     * from the LDAP URL.
      *
      * @return  a possibly empty unmodifiable {@link List} containing the
-     *          resolved ldap server endpoints
+     *          resolved LDAP server endpoints
      */
     public List<String> getEndpoints() {
         return endpoints;
     }
-
 }
diff --git a/src/java.xml/share/classes/org/w3c/dom/package-info.java b/src/java.xml/share/classes/org/w3c/dom/package-info.java
index 8d08de006fd..10f081415ed 100644
--- a/src/java.xml/share/classes/org/w3c/dom/package-info.java
+++ b/src/java.xml/share/classes/org/w3c/dom/package-info.java
@@ -42,31 +42,6 @@
  * {@link org.w3c.dom.Node#setTextContent(String) setTextContent} shared the same
  * content that defined the TextContent property itself.
  *
- * @implNote
- * The JDK implementation of {@link org.w3c.dom.ls.LSSerializer LSSerializer}
- * follows the <a href="https://www.w3.org/TR/xml/#charsets">Characters</a> section
- * of the XML Specification in handling characters output. In particular, the
- * specification defined a character range that excluded the surrogate blocks.
- * As a result, the JDK LSSerializer writes characters in the surrogate blocks
- * as Character References. Character {@code 0xf0 0x9f 0x9a 0xa9}
- * (Unicode code point U+1F6A9) for example will be written as {@code &#128681;}.
- *
- * <p>
- * This behavior is different from what was in the class description of
- * {@link org.w3c.dom.ls.LSSerializer LSSerializer}. The relevant section is quoted
- * below:
- *
- * <p>
- * {@code Within the character data of a document (outside of markup), any characters
- * that cannot be represented directly are replaced with character references...
- * Any characters that cannot be represented directly in the output character encoding
- * are serialized as numeric character references }
- *
- * <p>
- * The JDK implementation does not follow this definition because it is not consistent
- * with the XML Specification that defined an explicit character range with no
- * association to the setting of the output character encoding.
- *
  *
  * @since 1.4
  */
diff --git a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocRootTree.java b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocRootTree.java
index 4565cefd70b..427425a526e 100644
--- a/src/jdk.compiler/share/classes/com/sun/source/doctree/DocRootTree.java
+++ b/src/jdk.compiler/share/classes/com/sun/source/doctree/DocRootTree.java
@@ -26,10 +26,10 @@
 package com.sun.source.doctree;
 
 /**
- * A tree node for an {@code @docroot} inline tag.
+ * A tree node for an {@code @docRoot} inline tag.
  *
  * <pre>
- *    {&#064;docroot}
+ *    {&#064;docRoot}
  * </pre>
  *
  * @since 1.8
diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/DeconstructionPatternTree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/DeconstructionPatternTree.java
new file mode 100644
index 00000000000..fac342afc11
--- /dev/null
+++ b/src/jdk.compiler/share/classes/com/sun/source/tree/DeconstructionPatternTree.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 com.sun.source.tree;
+
+import java.util.List;
+
+/**
+ * {@preview Associated with pattern matching for instanceof, a preview feature of
+ *           the Java language.
+ *
+ *           This interface is associated with <i>pattern matching for instanceof</i>, a preview
+ *           feature of the Java language. Preview features
+ *           may be removed in a future release, or upgraded to permanent
+ *           features of the Java language.}
+ *
+ * A deconstruction pattern tree
+ *
+ * @since 15
+ */
+public interface DeconstructionPatternTree extends PatternTree {
+
+    /**
+     * Returns the deconstructed type.
+     * @return the deconstructed type
+     */
+    Tree getDeconstructor();
+
+    /**
+     * Returns the nested patterns.
+     * @return the nested patterns.
+     */
+    List<? extends PatternTree> getNestedPatterns();
+
+}
+
diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java b/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java
index f368973b550..b3215244f2c 100644
--- a/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java
+++ b/src/jdk.compiler/share/classes/com/sun/source/tree/Tree.java
@@ -234,6 +234,21 @@ public enum Kind {
          */
         BINDING_PATTERN(BindingPatternTree.class),
 
+        /**
+         * {@preview Associated with pattern matching for instanceof, a preview feature of
+         *           the Java language.
+         *
+         *           This enum constant is associated with <i>pattern matching for instanceof</i>, a preview
+         *           feature of the Java language. Preview features
+         *           may be removed in a future release, or upgraded to permanent
+         *           features of the Java language.}
+         *
+         * Used for instances of {@link DeconstructionPatternTree}.
+         *
+         * @since 15
+         */
+        DECONSTRUCTION_PATTERN(DeconstructionPatternTree.class),
+
         /**
          * Used for instances of {@link PrimitiveTypeTree}.
          */
diff --git a/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java b/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java
index 1fb0b0a6aae..eb752d6982b 100644
--- a/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java
+++ b/src/jdk.compiler/share/classes/com/sun/source/tree/TreeVisitor.java
@@ -274,6 +274,23 @@ public interface TreeVisitor<R,P> {
      */
     R visitBindingPattern(BindingPatternTree node, P p);
 
+    /**
+     * {@preview Associated with pattern matching for instanceof, a preview feature of
+     *           the Java language.
+     *
+     *           This method is associated with <i>pattern matching for instanceof</i>, a preview
+     *           feature of the Java language. Preview features
+     *           may be removed in a future release, or upgraded to permanent
+     *           features of the Java language.}
+     *
+     * Visits an DeconstructionPatternTree node.
+     * @param node the node being visited
+     * @param p a parameter value
+     * @return a result value
+     * @since 15
+     */
+    R visitDeconstructionPattern(DeconstructionPatternTree node, P p);
+
     /**
      * Visits a MethodTree node.
      * @param node the node being visited
diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java
index 8878486b99d..54dc3d259bd 100644
--- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTreeFactory.java
@@ -137,7 +137,7 @@ DocCommentTree newDocCommentTree(List<? extends DocTree> fullBody,
                                      List<? extends DocTree> preamble,
                                      List<? extends DocTree> postamble);
     /**
-     * Creates a new {@code DocRootTree} object, to represent an {@code {@docroot}} tag.
+     * Creates a new {@code DocRootTree} object, to represent an {@code {@docRoot}} tag.
      * @return a {@code DocRootTree} object
      */
     DocRootTree newDocRootTree();
diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java b/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java
index 2c183e17d9a..60fd4b28675 100644
--- a/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/DocTrees.java
@@ -39,6 +39,8 @@
 
 import com.sun.source.doctree.DocCommentTree;
 import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.EntityTree;
+import com.sun.source.tree.CompilationUnitTree;
 
 /**
  * Provides access to syntax trees for doc comments.
@@ -202,19 +204,17 @@ public static DocTrees instance(ProcessingEnvironment env) {
      * @param root the compilation unit that contains tree
      */
     public abstract void printMessage(Diagnostic.Kind kind, CharSequence msg,
-            com.sun.source.doctree.DocTree t,
-            com.sun.source.doctree.DocCommentTree c,
-            com.sun.source.tree.CompilationUnitTree root);
+            DocTree t, DocCommentTree c, CompilationUnitTree root);
 
     /**
      * Sets the break iterator to compute the first sentence of
      * documentation comments.
-     * @param breakiterator a break iterator or {@code null} to specify the default
+     * @param breakIterator a break iterator or {@code null} to specify the default
      *                      sentence breaker
      *
      * @since 9
      */
-    public abstract void setBreakIterator(BreakIterator breakiterator);
+    public abstract void setBreakIterator(BreakIterator breakIterator);
 
     /**
      * Returns a utility object for creating {@code DocTree} objects.
@@ -223,4 +223,16 @@ public abstract void printMessage(Diagnostic.Kind kind, CharSequence msg,
      * @since 9
      */
     public abstract DocTreeFactory getDocTreeFactory();
+
+    /**
+     * Returns a string containing the characters for the entity in a given entity tree,
+     * or {@code null} if the tree does not represent a valid series of characters.
+     *
+     * <p>The interpretation of entities is based on section
+     * <a href="https://www.w3.org/TR/html52/syntax.html#character-references">8.1.4. Character references</a>
+     * in the HTML 5.2 specification.</p>
+     *
+     * @return a string containing the characters
+     */
+    public abstract String getCharacters(EntityTree tree);
 }
diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java
index 03ff696a980..47ecb1e2dc1 100644
--- a/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/SimpleTreeVisitor.java
@@ -564,6 +564,19 @@ public R visitBindingPattern(BindingPatternTree node, P p) {
         return defaultAction(node, p);
     }
 
+    /**
+     * {@inheritDoc} This implementation calls {@code defaultAction}.
+     *
+     * @param node {@inheritDoc}
+     * @param p {@inheritDoc}
+     * @return  the result of {@code defaultAction}
+     * @since 15
+     */
+    @Override
+    public R visitDeconstructionPattern(DeconstructionPatternTree node, P p) {
+        return defaultAction(node, p);
+    }
+
     /**
      * {@inheritDoc} This implementation calls {@code defaultAction}.
      *
diff --git a/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java b/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java
index e7cff68e384..e2a5a50ea2c 100644
--- a/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java
+++ b/src/jdk.compiler/share/classes/com/sun/source/util/TreeScanner.java
@@ -694,6 +694,20 @@ public R visitBindingPattern(BindingPatternTree node, P p) {
         return scan(node.getType(), p);
     }
 
+    /**
+     * {@inheritDoc} This implementation scans the children in left to right order.
+     *
+     * @param node  {@inheritDoc}
+     * @param p  {@inheritDoc}
+     * @return the result of scanning
+     * @since 15
+     */
+    @Override
+    public R visitDeconstructionPattern(DeconstructionPatternTree node, P p) {
+        R r = scan(node.getDeconstructor(), p);
+        return scanAndReduce(node.getNestedPatterns(), p, r);
+    }
+
     /**
      * {@inheritDoc} This implementation scans the children in left to right order.
      *
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java b/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java
index c40d4bb52e8..0754d0063d3 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -295,18 +295,12 @@ public Void visitText(TextTree tree, Void ignore) {
     public Void visitEntity(EntityTree tree, Void ignore) {
         checkAllowsText(tree);
         markEnclosingTag(Flag.HAS_TEXT);
-        String name = tree.getName().toString();
-        if (name.startsWith("#")) {
-            int v = StringUtils.toLowerCase(name).startsWith("#x")
-                    ? Integer.parseInt(name.substring(2), 16)
-                    : Integer.parseInt(name.substring(1), 10);
-            if (!Entity.isValid(v)) {
-                env.messages.error(HTML, tree, "dc.entity.invalid", name);
-            }
-        } else if (!Entity.isValid(name)) {
-            env.messages.error(HTML, tree, "dc.entity.invalid", name);
+        String s = env.trees.getCharacters(tree);
+        if (s == null) {
+            env.messages.error(HTML, tree, "dc.entity.invalid", tree.getName());
         }
         return null;
+
     }
 
     void checkAllowsText(DocTree tree) {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/doclint/Entity.java b/src/jdk.compiler/share/classes/com/sun/tools/doclint/Entity.java
deleted file mode 100644
index ca6368af592..00000000000
--- a/src/jdk.compiler/share/classes/com/sun/tools/doclint/Entity.java
+++ /dev/null
@@ -1,2188 +0,0 @@
-/*
- * 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
- * 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 com.sun.tools.doclint;
-
-import java.util.HashMap;
-
-/**
- * Table of entities defined in HTML 5.2.
- *
- * <p> Derived from the
- * <a href="https://www.w3.org/TR/html52/syntax.html#named-character-references">Named character references</a>
- * section of the HTML 5.2 specification.
- *
- * <p><b>This is NOT part of any supported API.
- * If you write code that depends on this, you do so at your own
- * risk.  This code and its internal interfaces are subject to change
- * or deletion without notice.</b></p>
- */
-public class Entity {
-
-    private static final HashMap<String,String> html5Entities = new HashMap<>();
-
-    static {
-        html5Entities.put("Aacute", "\u00C1");
-        html5Entities.put("aacute", "\u00E1");
-        html5Entities.put("Abreve", "\u0102");
-        html5Entities.put("abreve", "\u0103");
-        html5Entities.put("ac", "\u223E");
-        html5Entities.put("acd", "\u223F");
-        html5Entities.put("acE", "\u223E\u0333");
-        html5Entities.put("Acirc", "\u00C2");
-        html5Entities.put("acirc", "\u00E2");
-        html5Entities.put("acute", "\u00B4");
-        html5Entities.put("Acy", "\u0410");
-        html5Entities.put("acy", "\u0430");
-        html5Entities.put("AElig", "\u00C6");
-        html5Entities.put("aelig", "\u00E6");
-        html5Entities.put("af", "\u2061");
-        html5Entities.put("Afr", "\uD835\uDD04");
-        html5Entities.put("afr", "\uD835\uDD1E");
-        html5Entities.put("Agrave", "\u00C0");
-        html5Entities.put("agrave", "\u00E0");
-        html5Entities.put("alefsym", "\u2135");
-        html5Entities.put("aleph", "\u2135");
-        html5Entities.put("Alpha", "\u0391");
-        html5Entities.put("alpha", "\u03B1");
-        html5Entities.put("Amacr", "\u0100");
-        html5Entities.put("amacr", "\u0101");
-        html5Entities.put("amalg", "\u2A3F");
-        html5Entities.put("amp", "\u0026");
-        html5Entities.put("AMP", "\u0026");
-        html5Entities.put("andand", "\u2A55");
-        html5Entities.put("And", "\u2A53");
-        html5Entities.put("and", "\u2227");
-        html5Entities.put("andd", "\u2A5C");
-        html5Entities.put("andslope", "\u2A58");
-        html5Entities.put("andv", "\u2A5A");
-        html5Entities.put("ang", "\u2220");
-        html5Entities.put("ange", "\u29A4");
-        html5Entities.put("angle", "\u2220");
-        html5Entities.put("angmsdaa", "\u29A8");
-        html5Entities.put("angmsdab", "\u29A9");
-        html5Entities.put("angmsdac", "\u29AA");
-        html5Entities.put("angmsdad", "\u29AB");
-        html5Entities.put("angmsdae", "\u29AC");
-        html5Entities.put("angmsdaf", "\u29AD");
-        html5Entities.put("angmsdag", "\u29AE");
-        html5Entities.put("angmsdah", "\u29AF");
-        html5Entities.put("angmsd", "\u2221");
-        html5Entities.put("angrt", "\u221F");
-        html5Entities.put("angrtvb", "\u22BE");
-        html5Entities.put("angrtvbd", "\u299D");
-        html5Entities.put("angsph", "\u2222");
-        html5Entities.put("angst", "\u00C5");
-        html5Entities.put("angzarr", "\u237C");
-        html5Entities.put("Aogon", "\u0104");
-        html5Entities.put("aogon", "\u0105");
-        html5Entities.put("Aopf", "\uD835\uDD38");
-        html5Entities.put("aopf", "\uD835\uDD52");
-        html5Entities.put("apacir", "\u2A6F");
-        html5Entities.put("ap", "\u2248");
-        html5Entities.put("apE", "\u2A70");
-        html5Entities.put("ape", "\u224A");
-        html5Entities.put("apid", "\u224B");
-        html5Entities.put("apos", "\u0027");
-        html5Entities.put("ApplyFunction", "\u2061");
-        html5Entities.put("approx", "\u2248");
-        html5Entities.put("approxeq", "\u224A");
-        html5Entities.put("Aring", "\u00C5");
-        html5Entities.put("aring", "\u00E5");
-        html5Entities.put("Ascr", "\uD835\uDC9C");
-        html5Entities.put("ascr", "\uD835\uDCB6");
-        html5Entities.put("Assign", "\u2254");
-        html5Entities.put("ast", "\u002A");
-        html5Entities.put("asymp", "\u2248");
-        html5Entities.put("asympeq", "\u224D");
-        html5Entities.put("Atilde", "\u00C3");
-        html5Entities.put("atilde", "\u00E3");
-        html5Entities.put("Auml", "\u00C4");
-        html5Entities.put("auml", "\u00E4");
-        html5Entities.put("awconint", "\u2233");
-        html5Entities.put("awint", "\u2A11");
-        html5Entities.put("backcong", "\u224C");
-        html5Entities.put("backepsilon", "\u03F6");
-        html5Entities.put("backprime", "\u2035");
-        html5Entities.put("backsim", "\u223D");
-        html5Entities.put("backsimeq", "\u22CD");
-        html5Entities.put("Backslash", "\u2216");
-        html5Entities.put("Barv", "\u2AE7");
-        html5Entities.put("barvee", "\u22BD");
-        html5Entities.put("barwed", "\u2305");
-        html5Entities.put("Barwed", "\u2306");
-        html5Entities.put("barwedge", "\u2305");
-        html5Entities.put("bbrk", "\u23B5");
-        html5Entities.put("bbrktbrk", "\u23B6");
-        html5Entities.put("bcong", "\u224C");
-        html5Entities.put("Bcy", "\u0411");
-        html5Entities.put("bcy", "\u0431");
-        html5Entities.put("bdquo", "\u201E");
-        html5Entities.put("becaus", "\u2235");
-        html5Entities.put("because", "\u2235");
-        html5Entities.put("Because", "\u2235");
-        html5Entities.put("bemptyv", "\u29B0");
-        html5Entities.put("bepsi", "\u03F6");
-        html5Entities.put("bernou", "\u212C");
-        html5Entities.put("Bernoullis", "\u212C");
-        html5Entities.put("Beta", "\u0392");
-        html5Entities.put("beta", "\u03B2");
-        html5Entities.put("beth", "\u2136");
-        html5Entities.put("between", "\u226C");
-        html5Entities.put("Bfr", "\uD835\uDD05");
-        html5Entities.put("bfr", "\uD835\uDD1F");
-        html5Entities.put("bigcap", "\u22C2");
-        html5Entities.put("bigcirc", "\u25EF");
-        html5Entities.put("bigcup", "\u22C3");
-        html5Entities.put("bigodot", "\u2A00");
-        html5Entities.put("bigoplus", "\u2A01");
-        html5Entities.put("bigotimes", "\u2A02");
-        html5Entities.put("bigsqcup", "\u2A06");
-        html5Entities.put("bigstar", "\u2605");
-        html5Entities.put("bigtriangledown", "\u25BD");
-        html5Entities.put("bigtriangleup", "\u25B3");
-        html5Entities.put("biguplus", "\u2A04");
-        html5Entities.put("bigvee", "\u22C1");
-        html5Entities.put("bigwedge", "\u22C0");
-        html5Entities.put("bkarow", "\u290D");
-        html5Entities.put("blacklozenge", "\u29EB");
-        html5Entities.put("blacksquare", "\u25AA");
-        html5Entities.put("blacktriangle", "\u25B4");
-        html5Entities.put("blacktriangledown", "\u25BE");
-        html5Entities.put("blacktriangleleft", "\u25C2");
-        html5Entities.put("blacktriangleright", "\u25B8");
-        html5Entities.put("blank", "\u2423");
-        html5Entities.put("blk12", "\u2592");
-        html5Entities.put("blk14", "\u2591");
-        html5Entities.put("blk34", "\u2593");
-        html5Entities.put("block", "\u2588");
-        html5Entities.put("bne", "\u003D\u20E5");
-        html5Entities.put("bnequiv", "\u2261\u20E5");
-        html5Entities.put("bNot", "\u2AED");
-        html5Entities.put("bnot", "\u2310");
-        html5Entities.put("Bopf", "\uD835\uDD39");
-        html5Entities.put("bopf", "\uD835\uDD53");
-        html5Entities.put("bot", "\u22A5");
-        html5Entities.put("bottom", "\u22A5");
-        html5Entities.put("bowtie", "\u22C8");
-        html5Entities.put("boxbox", "\u29C9");
-        html5Entities.put("boxdl", "\u2510");
-        html5Entities.put("boxdL", "\u2555");
-        html5Entities.put("boxDl", "\u2556");
-        html5Entities.put("boxDL", "\u2557");
-        html5Entities.put("boxdr", "\u250C");
-        html5Entities.put("boxdR", "\u2552");
-        html5Entities.put("boxDr", "\u2553");
-        html5Entities.put("boxDR", "\u2554");
-        html5Entities.put("boxh", "\u2500");
-        html5Entities.put("boxH", "\u2550");
-        html5Entities.put("boxhd", "\u252C");
-        html5Entities.put("boxHd", "\u2564");
-        html5Entities.put("boxhD", "\u2565");
-        html5Entities.put("boxHD", "\u2566");
-        html5Entities.put("boxhu", "\u2534");
-        html5Entities.put("boxHu", "\u2567");
-        html5Entities.put("boxhU", "\u2568");
-        html5Entities.put("boxHU", "\u2569");
-        html5Entities.put("boxminus", "\u229F");
-        html5Entities.put("boxplus", "\u229E");
-        html5Entities.put("boxtimes", "\u22A0");
-        html5Entities.put("boxul", "\u2518");
-        html5Entities.put("boxuL", "\u255B");
-        html5Entities.put("boxUl", "\u255C");
-        html5Entities.put("boxUL", "\u255D");
-        html5Entities.put("boxur", "\u2514");
-        html5Entities.put("boxuR", "\u2558");
-        html5Entities.put("boxUr", "\u2559");
-        html5Entities.put("boxUR", "\u255A");
-        html5Entities.put("boxv", "\u2502");
-        html5Entities.put("boxV", "\u2551");
-        html5Entities.put("boxvh", "\u253C");
-        html5Entities.put("boxvH", "\u256A");
-        html5Entities.put("boxVh", "\u256B");
-        html5Entities.put("boxVH", "\u256C");
-        html5Entities.put("boxvl", "\u2524");
-        html5Entities.put("boxvL", "\u2561");
-        html5Entities.put("boxVl", "\u2562");
-        html5Entities.put("boxVL", "\u2563");
-        html5Entities.put("boxvr", "\u251C");
-        html5Entities.put("boxvR", "\u255E");
-        html5Entities.put("boxVr", "\u255F");
-        html5Entities.put("boxVR", "\u2560");
-        html5Entities.put("bprime", "\u2035");
-        html5Entities.put("breve", "\u02D8");
-        html5Entities.put("Breve", "\u02D8");
-        html5Entities.put("brvbar", "\u00A6");
-        html5Entities.put("bscr", "\uD835\uDCB7");
-        html5Entities.put("Bscr", "\u212C");
-        html5Entities.put("bsemi", "\u204F");
-        html5Entities.put("bsim", "\u223D");
-        html5Entities.put("bsime", "\u22CD");
-        html5Entities.put("bsolb", "\u29C5");
-        html5Entities.put("bsol", "\\");
-        html5Entities.put("bsolhsub", "\u27C8");
-        html5Entities.put("bull", "\u2022");
-        html5Entities.put("bullet", "\u2022");
-        html5Entities.put("bump", "\u224E");
-        html5Entities.put("bumpE", "\u2AAE");
-        html5Entities.put("bumpe", "\u224F");
-        html5Entities.put("Bumpeq", "\u224E");
-        html5Entities.put("bumpeq", "\u224F");
-        html5Entities.put("Cacute", "\u0106");
-        html5Entities.put("cacute", "\u0107");
-        html5Entities.put("capand", "\u2A44");
-        html5Entities.put("capbrcup", "\u2A49");
-        html5Entities.put("capcap", "\u2A4B");
-        html5Entities.put("cap", "\u2229");
-        html5Entities.put("Cap", "\u22D2");
-        html5Entities.put("capcup", "\u2A47");
-        html5Entities.put("capdot", "\u2A40");
-        html5Entities.put("CapitalDifferentialD", "\u2145");
-        html5Entities.put("caps", "\u2229\uFE00");
-        html5Entities.put("caret", "\u2041");
-        html5Entities.put("caron", "\u02C7");
-        html5Entities.put("Cayleys", "\u212D");
-        html5Entities.put("ccaps", "\u2A4D");
-        html5Entities.put("Ccaron", "\u010C");
-        html5Entities.put("ccaron", "\u010D");
-        html5Entities.put("Ccedil", "\u00C7");
-        html5Entities.put("ccedil", "\u00E7");
-        html5Entities.put("Ccirc", "\u0108");
-        html5Entities.put("ccirc", "\u0109");
-        html5Entities.put("Cconint", "\u2230");
-        html5Entities.put("ccups", "\u2A4C");
-        html5Entities.put("ccupssm", "\u2A50");
-        html5Entities.put("Cdot", "\u010A");
-        html5Entities.put("cdot", "\u010B");
-        html5Entities.put("cedil", "\u00B8");
-        html5Entities.put("Cedilla", "\u00B8");
-        html5Entities.put("cemptyv", "\u29B2");
-        html5Entities.put("cent", "\u00A2");
-        html5Entities.put("centerdot", "\u00B7");
-        html5Entities.put("CenterDot", "\u00B7");
-        html5Entities.put("cfr", "\uD835\uDD20");
-        html5Entities.put("Cfr", "\u212D");
-        html5Entities.put("CHcy", "\u0427");
-        html5Entities.put("chcy", "\u0447");
-        html5Entities.put("check", "\u2713");
-        html5Entities.put("checkmark", "\u2713");
-        html5Entities.put("Chi", "\u03A7");
-        html5Entities.put("chi", "\u03C7");
-        html5Entities.put("circ", "\u02C6");
-        html5Entities.put("circeq", "\u2257");
-        html5Entities.put("circlearrowleft", "\u21BA");
-        html5Entities.put("circlearrowright", "\u21BB");
-        html5Entities.put("circledast", "\u229B");
-        html5Entities.put("circledcirc", "\u229A");
-        html5Entities.put("circleddash", "\u229D");
-        html5Entities.put("CircleDot", "\u2299");
-        html5Entities.put("circledR", "\u00AE");
-        html5Entities.put("circledS", "\u24C8");
-        html5Entities.put("CircleMinus", "\u2296");
-        html5Entities.put("CirclePlus", "\u2295");
-        html5Entities.put("CircleTimes", "\u2297");
-        html5Entities.put("cir", "\u25CB");
-        html5Entities.put("cirE", "\u29C3");
-        html5Entities.put("cire", "\u2257");
-        html5Entities.put("cirfnint", "\u2A10");
-        html5Entities.put("cirmid", "\u2AEF");
-        html5Entities.put("cirscir", "\u29C2");
-        html5Entities.put("ClockwiseContourIntegral", "\u2232");
-        html5Entities.put("CloseCurlyDoubleQuote", "\u201D");
-        html5Entities.put("CloseCurlyQuote", "\u2019");
-        html5Entities.put("clubs", "\u2663");
-        html5Entities.put("clubsuit", "\u2663");
-        html5Entities.put("colon", "\u003A");
-        html5Entities.put("Colon", "\u2237");
-        html5Entities.put("Colone", "\u2A74");
-        html5Entities.put("colone", "\u2254");
-        html5Entities.put("coloneq", "\u2254");
-        html5Entities.put("comma", "\u002C");
-        html5Entities.put("commat", "\u0040");
-        html5Entities.put("comp", "\u2201");
-        html5Entities.put("compfn", "\u2218");
-        html5Entities.put("complement", "\u2201");
-        html5Entities.put("complexes", "\u2102");
-        html5Entities.put("cong", "\u2245");
-        html5Entities.put("congdot", "\u2A6D");
-        html5Entities.put("Congruent", "\u2261");
-        html5Entities.put("conint", "\u222E");
-        html5Entities.put("Conint", "\u222F");
-        html5Entities.put("ContourIntegral", "\u222E");
-        html5Entities.put("copf", "\uD835\uDD54");
-        html5Entities.put("Copf", "\u2102");
-        html5Entities.put("coprod", "\u2210");
-        html5Entities.put("Coproduct", "\u2210");
-        html5Entities.put("copy", "\u00A9");
-        html5Entities.put("COPY", "\u00A9");
-        html5Entities.put("copysr", "\u2117");
-        html5Entities.put("CounterClockwiseContourIntegral", "\u2233");
-        html5Entities.put("crarr", "\u21B5");
-        html5Entities.put("cross", "\u2717");
-        html5Entities.put("Cross", "\u2A2F");
-        html5Entities.put("Cscr", "\uD835\uDC9E");
-        html5Entities.put("cscr", "\uD835\uDCB8");
-        html5Entities.put("csub", "\u2ACF");
-        html5Entities.put("csube", "\u2AD1");
-        html5Entities.put("csup", "\u2AD0");
-        html5Entities.put("csupe", "\u2AD2");
-        html5Entities.put("ctdot", "\u22EF");
-        html5Entities.put("cudarrl", "\u2938");
-        html5Entities.put("cudarrr", "\u2935");
-        html5Entities.put("cuepr", "\u22DE");
-        html5Entities.put("cuesc", "\u22DF");
-        html5Entities.put("cularr", "\u21B6");
-        html5Entities.put("cularrp", "\u293D");
-        html5Entities.put("cupbrcap", "\u2A48");
-        html5Entities.put("cupcap", "\u2A46");
-        html5Entities.put("CupCap", "\u224D");
-        html5Entities.put("cup", "\u222A");
-        html5Entities.put("Cup", "\u22D3");
-        html5Entities.put("cupcup", "\u2A4A");
-        html5Entities.put("cupdot", "\u228D");
-        html5Entities.put("cupor", "\u2A45");
-        html5Entities.put("cups", "\u222A\uFE00");
-        html5Entities.put("curarr", "\u21B7");
-        html5Entities.put("curarrm", "\u293C");
-        html5Entities.put("curlyeqprec", "\u22DE");
-        html5Entities.put("curlyeqsucc", "\u22DF");
-        html5Entities.put("curlyvee", "\u22CE");
-        html5Entities.put("curlywedge", "\u22CF");
-        html5Entities.put("curren", "\u00A4");
-        html5Entities.put("curvearrowleft", "\u21B6");
-        html5Entities.put("curvearrowright", "\u21B7");
-        html5Entities.put("cuvee", "\u22CE");
-        html5Entities.put("cuwed", "\u22CF");
-        html5Entities.put("cwconint", "\u2232");
-        html5Entities.put("cwint", "\u2231");
-        html5Entities.put("cylcty", "\u232D");
-        html5Entities.put("dagger", "\u2020");
-        html5Entities.put("Dagger", "\u2021");
-        html5Entities.put("daleth", "\u2138");
-        html5Entities.put("darr", "\u2193");
-        html5Entities.put("Darr", "\u21A1");
-        html5Entities.put("dArr", "\u21D3");
-        html5Entities.put("dash", "\u2010");
-        html5Entities.put("Dashv", "\u2AE4");
-        html5Entities.put("dashv", "\u22A3");
-        html5Entities.put("dbkarow", "\u290F");
-        html5Entities.put("dblac", "\u02DD");
-        html5Entities.put("Dcaron", "\u010E");
-        html5Entities.put("dcaron", "\u010F");
-        html5Entities.put("Dcy", "\u0414");
-        html5Entities.put("dcy", "\u0434");
-        html5Entities.put("ddagger", "\u2021");
-        html5Entities.put("ddarr", "\u21CA");
-        html5Entities.put("DD", "\u2145");
-        html5Entities.put("dd", "\u2146");
-        html5Entities.put("DDotrahd", "\u2911");
-        html5Entities.put("ddotseq", "\u2A77");
-        html5Entities.put("deg", "\u00B0");
-        html5Entities.put("Del", "\u2207");
-        html5Entities.put("Delta", "\u0394");
-        html5Entities.put("delta", "\u03B4");
-        html5Entities.put("demptyv", "\u29B1");
-        html5Entities.put("dfisht", "\u297F");
-        html5Entities.put("Dfr", "\uD835\uDD07");
-        html5Entities.put("dfr", "\uD835\uDD21");
-        html5Entities.put("dHar", "\u2965");
-        html5Entities.put("dharl", "\u21C3");
-        html5Entities.put("dharr", "\u21C2");
-        html5Entities.put("DiacriticalAcute", "\u00B4");
-        html5Entities.put("DiacriticalDot", "\u02D9");
-        html5Entities.put("DiacriticalDoubleAcute", "\u02DD");
-        html5Entities.put("DiacriticalGrave", "\u0060");
-        html5Entities.put("DiacriticalTilde", "\u02DC");
-        html5Entities.put("diam", "\u22C4");
-        html5Entities.put("diamond", "\u22C4");
-        html5Entities.put("Diamond", "\u22C4");
-        html5Entities.put("diamondsuit", "\u2666");
-        html5Entities.put("diams", "\u2666");
-        html5Entities.put("die", "\u00A8");
-        html5Entities.put("DifferentialD", "\u2146");
-        html5Entities.put("digamma", "\u03DD");
-        html5Entities.put("disin", "\u22F2");
-        html5Entities.put("div", "\u00F7");
-        html5Entities.put("divide", "\u00F7");
-        html5Entities.put("divideontimes", "\u22C7");
-        html5Entities.put("divonx", "\u22C7");
-        html5Entities.put("DJcy", "\u0402");
-        html5Entities.put("djcy", "\u0452");
-        html5Entities.put("dlcorn", "\u231E");
-        html5Entities.put("dlcrop", "\u230D");
-        html5Entities.put("dollar", "\u0024");
-        html5Entities.put("Dopf", "\uD835\uDD3B");
-        html5Entities.put("dopf", "\uD835\uDD55");
-        html5Entities.put("Dot", "\u00A8");
-        html5Entities.put("dot", "\u02D9");
-        html5Entities.put("DotDot", "\u20DC");
-        html5Entities.put("doteq", "\u2250");
-        html5Entities.put("doteqdot", "\u2251");
-        html5Entities.put("DotEqual", "\u2250");
-        html5Entities.put("dotminus", "\u2238");
-        html5Entities.put("dotplus", "\u2214");
-        html5Entities.put("dotsquare", "\u22A1");
-        html5Entities.put("doublebarwedge", "\u2306");
-        html5Entities.put("DoubleContourIntegral", "\u222F");
-        html5Entities.put("DoubleDot", "\u00A8");
-        html5Entities.put("DoubleDownArrow", "\u21D3");
-        html5Entities.put("DoubleLeftArrow", "\u21D0");
-        html5Entities.put("DoubleLeftRightArrow", "\u21D4");
-        html5Entities.put("DoubleLeftTee", "\u2AE4");
-        html5Entities.put("DoubleLongLeftArrow", "\u27F8");
-        html5Entities.put("DoubleLongLeftRightArrow", "\u27FA");
-        html5Entities.put("DoubleLongRightArrow", "\u27F9");
-        html5Entities.put("DoubleRightArrow", "\u21D2");
-        html5Entities.put("DoubleRightTee", "\u22A8");
-        html5Entities.put("DoubleUpArrow", "\u21D1");
-        html5Entities.put("DoubleUpDownArrow", "\u21D5");
-        html5Entities.put("DoubleVerticalBar", "\u2225");
-        html5Entities.put("DownArrowBar", "\u2913");
-        html5Entities.put("downarrow", "\u2193");
-        html5Entities.put("DownArrow", "\u2193");
-        html5Entities.put("Downarrow", "\u21D3");
-        html5Entities.put("DownArrowUpArrow", "\u21F5");
-        html5Entities.put("DownBreve", "\u0311");
-        html5Entities.put("downdownarrows", "\u21CA");
-        html5Entities.put("downharpoonleft", "\u21C3");
-        html5Entities.put("downharpoonright", "\u21C2");
-        html5Entities.put("DownLeftRightVector", "\u2950");
-        html5Entities.put("DownLeftTeeVector", "\u295E");
-        html5Entities.put("DownLeftVectorBar", "\u2956");
-        html5Entities.put("DownLeftVector", "\u21BD");
-        html5Entities.put("DownRightTeeVector", "\u295F");
-        html5Entities.put("DownRightVectorBar", "\u2957");
-        html5Entities.put("DownRightVector", "\u21C1");
-        html5Entities.put("DownTeeArrow", "\u21A7");
-        html5Entities.put("DownTee", "\u22A4");
-        html5Entities.put("drbkarow", "\u2910");
-        html5Entities.put("drcorn", "\u231F");
-        html5Entities.put("drcrop", "\u230C");
-        html5Entities.put("Dscr", "\uD835\uDC9F");
-        html5Entities.put("dscr", "\uD835\uDCB9");
-        html5Entities.put("DScy", "\u0405");
-        html5Entities.put("dscy", "\u0455");
-        html5Entities.put("dsol", "\u29F6");
-        html5Entities.put("Dstrok", "\u0110");
-        html5Entities.put("dstrok", "\u0111");
-        html5Entities.put("dtdot", "\u22F1");
-        html5Entities.put("dtri", "\u25BF");
-        html5Entities.put("dtrif", "\u25BE");
-        html5Entities.put("duarr", "\u21F5");
-        html5Entities.put("duhar", "\u296F");
-        html5Entities.put("dwangle", "\u29A6");
-        html5Entities.put("DZcy", "\u040F");
-        html5Entities.put("dzcy", "\u045F");
-        html5Entities.put("dzigrarr", "\u27FF");
-        html5Entities.put("Eacute", "\u00C9");
-        html5Entities.put("eacute", "\u00E9");
-        html5Entities.put("easter", "\u2A6E");
-        html5Entities.put("Ecaron", "\u011A");
-        html5Entities.put("ecaron", "\u011B");
-        html5Entities.put("Ecirc", "\u00CA");
-        html5Entities.put("ecirc", "\u00EA");
-        html5Entities.put("ecir", "\u2256");
-        html5Entities.put("ecolon", "\u2255");
-        html5Entities.put("Ecy", "\u042D");
-        html5Entities.put("ecy", "\u044D");
-        html5Entities.put("eDDot", "\u2A77");
-        html5Entities.put("Edot", "\u0116");
-        html5Entities.put("edot", "\u0117");
-        html5Entities.put("eDot", "\u2251");
-        html5Entities.put("ee", "\u2147");
-        html5Entities.put("efDot", "\u2252");
-        html5Entities.put("Efr", "\uD835\uDD08");
-        html5Entities.put("efr", "\uD835\uDD22");
-        html5Entities.put("eg", "\u2A9A");
-        html5Entities.put("Egrave", "\u00C8");
-        html5Entities.put("egrave", "\u00E8");
-        html5Entities.put("egs", "\u2A96");
-        html5Entities.put("egsdot", "\u2A98");
-        html5Entities.put("el", "\u2A99");
-        html5Entities.put("Element", "\u2208");
-        html5Entities.put("elinters", "\u23E7");
-        html5Entities.put("ell", "\u2113");
-        html5Entities.put("els", "\u2A95");
-        html5Entities.put("elsdot", "\u2A97");
-        html5Entities.put("Emacr", "\u0112");
-        html5Entities.put("emacr", "\u0113");
-        html5Entities.put("empty", "\u2205");
-        html5Entities.put("emptyset", "\u2205");
-        html5Entities.put("EmptySmallSquare", "\u25FB");
-        html5Entities.put("emptyv", "\u2205");
-        html5Entities.put("EmptyVerySmallSquare", "\u25AB");
-        html5Entities.put("emsp13", "\u2004");
-        html5Entities.put("emsp14", "\u2005");
-        html5Entities.put("emsp", "\u2003");
-        html5Entities.put("ENG", "\u014A");
-        html5Entities.put("eng", "\u014B");
-        html5Entities.put("ensp", "\u2002");
-        html5Entities.put("Eogon", "\u0118");
-        html5Entities.put("eogon", "\u0119");
-        html5Entities.put("Eopf", "\uD835\uDD3C");
-        html5Entities.put("eopf", "\uD835\uDD56");
-        html5Entities.put("epar", "\u22D5");
-        html5Entities.put("eparsl", "\u29E3");
-        html5Entities.put("eplus", "\u2A71");
-        html5Entities.put("epsi", "\u03B5");
-        html5Entities.put("Epsilon", "\u0395");
-        html5Entities.put("epsilon", "\u03B5");
-        html5Entities.put("epsiv", "\u03F5");
-        html5Entities.put("eqcirc", "\u2256");
-        html5Entities.put("eqcolon", "\u2255");
-        html5Entities.put("eqsim", "\u2242");
-        html5Entities.put("eqslantgtr", "\u2A96");
-        html5Entities.put("eqslantless", "\u2A95");
-        html5Entities.put("Equal", "\u2A75");
-        html5Entities.put("equals", "\u003D");
-        html5Entities.put("EqualTilde", "\u2242");
-        html5Entities.put("equest", "\u225F");
-        html5Entities.put("Equilibrium", "\u21CC");
-        html5Entities.put("equiv", "\u2261");
-        html5Entities.put("equivDD", "\u2A78");
-        html5Entities.put("eqvparsl", "\u29E5");
-        html5Entities.put("erarr", "\u2971");
-        html5Entities.put("erDot", "\u2253");
-        html5Entities.put("escr", "\u212F");
-        html5Entities.put("Escr", "\u2130");
-        html5Entities.put("esdot", "\u2250");
-        html5Entities.put("Esim", "\u2A73");
-        html5Entities.put("esim", "\u2242");
-        html5Entities.put("Eta", "\u0397");
-        html5Entities.put("eta", "\u03B7");
-        html5Entities.put("ETH", "\u00D0");
-        html5Entities.put("eth", "\u00F0");
-        html5Entities.put("Euml", "\u00CB");
-        html5Entities.put("euml", "\u00EB");
-        html5Entities.put("euro", "\u20AC");
-        html5Entities.put("excl", "\u0021");
-        html5Entities.put("exist", "\u2203");
-        html5Entities.put("Exists", "\u2203");
-        html5Entities.put("expectation", "\u2130");
-        html5Entities.put("exponentiale", "\u2147");
-        html5Entities.put("ExponentialE", "\u2147");
-        html5Entities.put("fallingdotseq", "\u2252");
-        html5Entities.put("Fcy", "\u0424");
-        html5Entities.put("fcy", "\u0444");
-        html5Entities.put("female", "\u2640");
-        html5Entities.put("ffilig", "\uFB03");
-        html5Entities.put("fflig", "\uFB00");
-        html5Entities.put("ffllig", "\uFB04");
-        html5Entities.put("Ffr", "\uD835\uDD09");
-        html5Entities.put("ffr", "\uD835\uDD23");
-        html5Entities.put("filig", "\uFB01");
-        html5Entities.put("FilledSmallSquare", "\u25FC");
-        html5Entities.put("FilledVerySmallSquare", "\u25AA");
-        html5Entities.put("fjlig", "\u0066\u006A");
-        html5Entities.put("flat", "\u266D");
-        html5Entities.put("fllig", "\uFB02");
-        html5Entities.put("fltns", "\u25B1");
-        html5Entities.put("fnof", "\u0192");
-        html5Entities.put("Fopf", "\uD835\uDD3D");
-        html5Entities.put("fopf", "\uD835\uDD57");
-        html5Entities.put("forall", "\u2200");
-        html5Entities.put("ForAll", "\u2200");
-        html5Entities.put("fork", "\u22D4");
-        html5Entities.put("forkv", "\u2AD9");
-        html5Entities.put("Fouriertrf", "\u2131");
-        html5Entities.put("fpartint", "\u2A0D");
-        html5Entities.put("frac12", "\u00BD");
-        html5Entities.put("frac13", "\u2153");
-        html5Entities.put("frac14", "\u00BC");
-        html5Entities.put("frac15", "\u2155");
-        html5Entities.put("frac16", "\u2159");
-        html5Entities.put("frac18", "\u215B");
-        html5Entities.put("frac23", "\u2154");
-        html5Entities.put("frac25", "\u2156");
-        html5Entities.put("frac34", "\u00BE");
-        html5Entities.put("frac35", "\u2157");
-        html5Entities.put("frac38", "\u215C");
-        html5Entities.put("frac45", "\u2158");
-        html5Entities.put("frac56", "\u215A");
-        html5Entities.put("frac58", "\u215D");
-        html5Entities.put("frac78", "\u215E");
-        html5Entities.put("frasl", "\u2044");
-        html5Entities.put("frown", "\u2322");
-        html5Entities.put("fscr", "\uD835\uDCBB");
-        html5Entities.put("Fscr", "\u2131");
-        html5Entities.put("gacute", "\u01F5");
-        html5Entities.put("Gamma", "\u0393");
-        html5Entities.put("gamma", "\u03B3");
-        html5Entities.put("Gammad", "\u03DC");
-        html5Entities.put("gammad", "\u03DD");
-        html5Entities.put("gap", "\u2A86");
-        html5Entities.put("Gbreve", "\u011E");
-        html5Entities.put("gbreve", "\u011F");
-        html5Entities.put("Gcedil", "\u0122");
-        html5Entities.put("Gcirc", "\u011C");
-        html5Entities.put("gcirc", "\u011D");
-        html5Entities.put("Gcy", "\u0413");
-        html5Entities.put("gcy", "\u0433");
-        html5Entities.put("Gdot", "\u0120");
-        html5Entities.put("gdot", "\u0121");
-        html5Entities.put("ge", "\u2265");
-        html5Entities.put("gE", "\u2267");
-        html5Entities.put("gEl", "\u2A8C");
-        html5Entities.put("gel", "\u22DB");
-        html5Entities.put("geq", "\u2265");
-        html5Entities.put("geqq", "\u2267");
-        html5Entities.put("geqslant", "\u2A7E");
-        html5Entities.put("gescc", "\u2AA9");
-        html5Entities.put("ges", "\u2A7E");
-        html5Entities.put("gesdot", "\u2A80");
-        html5Entities.put("gesdoto", "\u2A82");
-        html5Entities.put("gesdotol", "\u2A84");
-        html5Entities.put("gesl", "\u22DB\uFE00");
-        html5Entities.put("gesles", "\u2A94");
-        html5Entities.put("Gfr", "\uD835\uDD0A");
-        html5Entities.put("gfr", "\uD835\uDD24");
-        html5Entities.put("gg", "\u226B");
-        html5Entities.put("Gg", "\u22D9");
-        html5Entities.put("ggg", "\u22D9");
-        html5Entities.put("gimel", "\u2137");
-        html5Entities.put("GJcy", "\u0403");
-        html5Entities.put("gjcy", "\u0453");
-        html5Entities.put("gla", "\u2AA5");
-        html5Entities.put("gl", "\u2277");
-        html5Entities.put("glE", "\u2A92");
-        html5Entities.put("glj", "\u2AA4");
-        html5Entities.put("gnap", "\u2A8A");
-        html5Entities.put("gnapprox", "\u2A8A");
-        html5Entities.put("gne", "\u2A88");
-        html5Entities.put("gnE", "\u2269");
-        html5Entities.put("gneq", "\u2A88");
-        html5Entities.put("gneqq", "\u2269");
-        html5Entities.put("gnsim", "\u22E7");
-        html5Entities.put("Gopf", "\uD835\uDD3E");
-        html5Entities.put("gopf", "\uD835\uDD58");
-        html5Entities.put("grave", "\u0060");
-        html5Entities.put("GreaterEqual", "\u2265");
-        html5Entities.put("GreaterEqualLess", "\u22DB");
-        html5Entities.put("GreaterFullEqual", "\u2267");
-        html5Entities.put("GreaterGreater", "\u2AA2");
-        html5Entities.put("GreaterLess", "\u2277");
-        html5Entities.put("GreaterSlantEqual", "\u2A7E");
-        html5Entities.put("GreaterTilde", "\u2273");
-        html5Entities.put("Gscr", "\uD835\uDCA2");
-        html5Entities.put("gscr", "\u210A");
-        html5Entities.put("gsim", "\u2273");
-        html5Entities.put("gsime", "\u2A8E");
-        html5Entities.put("gsiml", "\u2A90");
-        html5Entities.put("gtcc", "\u2AA7");
-        html5Entities.put("gtcir", "\u2A7A");
-        html5Entities.put("gt", "\u003E");
-        html5Entities.put("GT", "\u003E");
-        html5Entities.put("Gt", "\u226B");
-        html5Entities.put("gtdot", "\u22D7");
-        html5Entities.put("gtlPar", "\u2995");
-        html5Entities.put("gtquest", "\u2A7C");
-        html5Entities.put("gtrapprox", "\u2A86");
-        html5Entities.put("gtrarr", "\u2978");
-        html5Entities.put("gtrdot", "\u22D7");
-        html5Entities.put("gtreqless", "\u22DB");
-        html5Entities.put("gtreqqless", "\u2A8C");
-        html5Entities.put("gtrless", "\u2277");
-        html5Entities.put("gtrsim", "\u2273");
-        html5Entities.put("gvertneqq", "\u2269\uFE00");
-        html5Entities.put("gvnE", "\u2269\uFE00");
-        html5Entities.put("Hacek", "\u02C7");
-        html5Entities.put("hairsp", "\u200A");
-        html5Entities.put("half", "\u00BD");
-        html5Entities.put("hamilt", "\u210B");
-        html5Entities.put("HARDcy", "\u042A");
-        html5Entities.put("hardcy", "\u044A");
-        html5Entities.put("harrcir", "\u2948");
-        html5Entities.put("harr", "\u2194");
-        html5Entities.put("hArr", "\u21D4");
-        html5Entities.put("harrw", "\u21AD");
-        html5Entities.put("Hat", "\u005E");
-        html5Entities.put("hbar", "\u210F");
-        html5Entities.put("Hcirc", "\u0124");
-        html5Entities.put("hcirc", "\u0125");
-        html5Entities.put("hearts", "\u2665");
-        html5Entities.put("heartsuit", "\u2665");
-        html5Entities.put("hellip", "\u2026");
-        html5Entities.put("hercon", "\u22B9");
-        html5Entities.put("hfr", "\uD835\uDD25");
-        html5Entities.put("Hfr", "\u210C");
-        html5Entities.put("HilbertSpace", "\u210B");
-        html5Entities.put("hksearow", "\u2925");
-        html5Entities.put("hkswarow", "\u2926");
-        html5Entities.put("hoarr", "\u21FF");
-        html5Entities.put("homtht", "\u223B");
-        html5Entities.put("hookleftarrow", "\u21A9");
-        html5Entities.put("hookrightarrow", "\u21AA");
-        html5Entities.put("hopf", "\uD835\uDD59");
-        html5Entities.put("Hopf", "\u210D");
-        html5Entities.put("horbar", "\u2015");
-        html5Entities.put("HorizontalLine", "\u2500");
-        html5Entities.put("hscr", "\uD835\uDCBD");
-        html5Entities.put("Hscr", "\u210B");
-        html5Entities.put("hslash", "\u210F");
-        html5Entities.put("Hstrok", "\u0126");
-        html5Entities.put("hstrok", "\u0127");
-        html5Entities.put("HumpDownHump", "\u224E");
-        html5Entities.put("HumpEqual", "\u224F");
-        html5Entities.put("hybull", "\u2043");
-        html5Entities.put("hyphen", "\u2010");
-        html5Entities.put("Iacute", "\u00CD");
-        html5Entities.put("iacute", "\u00ED");
-        html5Entities.put("ic", "\u2063");
-        html5Entities.put("Icirc", "\u00CE");
-        html5Entities.put("icirc", "\u00EE");
-        html5Entities.put("Icy", "\u0418");
-        html5Entities.put("icy", "\u0438");
-        html5Entities.put("Idot", "\u0130");
-        html5Entities.put("IEcy", "\u0415");
-        html5Entities.put("iecy", "\u0435");
-        html5Entities.put("iexcl", "\u00A1");
-        html5Entities.put("iff", "\u21D4");
-        html5Entities.put("ifr", "\uD835\uDD26");
-        html5Entities.put("Ifr", "\u2111");
-        html5Entities.put("Igrave", "\u00CC");
-        html5Entities.put("igrave", "\u00EC");
-        html5Entities.put("ii", "\u2148");
-        html5Entities.put("iiiint", "\u2A0C");
-        html5Entities.put("iiint", "\u222D");
-        html5Entities.put("iinfin", "\u29DC");
-        html5Entities.put("iiota", "\u2129");
-        html5Entities.put("IJlig", "\u0132");
-        html5Entities.put("ijlig", "\u0133");
-        html5Entities.put("Imacr", "\u012A");
-        html5Entities.put("imacr", "\u012B");
-        html5Entities.put("image", "\u2111");
-        html5Entities.put("ImaginaryI", "\u2148");
-        html5Entities.put("imagline", "\u2110");
-        html5Entities.put("imagpart", "\u2111");
-        html5Entities.put("imath", "\u0131");
-        html5Entities.put("Im", "\u2111");
-        html5Entities.put("imof", "\u22B7");
-        html5Entities.put("imped", "\u01B5");
-        html5Entities.put("Implies", "\u21D2");
-        html5Entities.put("incare", "\u2105");
-        html5Entities.put("in", "\u2208");
-        html5Entities.put("infin", "\u221E");
-        html5Entities.put("infintie", "\u29DD");
-        html5Entities.put("inodot", "\u0131");
-        html5Entities.put("intcal", "\u22BA");
-        html5Entities.put("int", "\u222B");
-        html5Entities.put("Int", "\u222C");
-        html5Entities.put("integers", "\u2124");
-        html5Entities.put("Integral", "\u222B");
-        html5Entities.put("intercal", "\u22BA");
-        html5Entities.put("Intersection", "\u22C2");
-        html5Entities.put("intlarhk", "\u2A17");
-        html5Entities.put("intprod", "\u2A3C");
-        html5Entities.put("InvisibleComma", "\u2063");
-        html5Entities.put("InvisibleTimes", "\u2062");
-        html5Entities.put("IOcy", "\u0401");
-        html5Entities.put("iocy", "\u0451");
-        html5Entities.put("Iogon", "\u012E");
-        html5Entities.put("iogon", "\u012F");
-        html5Entities.put("Iopf", "\uD835\uDD40");
-        html5Entities.put("iopf", "\uD835\uDD5A");
-        html5Entities.put("Iota", "\u0399");
-        html5Entities.put("iota", "\u03B9");
-        html5Entities.put("iprod", "\u2A3C");
-        html5Entities.put("iquest", "\u00BF");
-        html5Entities.put("iscr", "\uD835\uDCBE");
-        html5Entities.put("Iscr", "\u2110");
-        html5Entities.put("isin", "\u2208");
-        html5Entities.put("isindot", "\u22F5");
-        html5Entities.put("isinE", "\u22F9");
-        html5Entities.put("isins", "\u22F4");
-        html5Entities.put("isinsv", "\u22F3");
-        html5Entities.put("isinv", "\u2208");
-        html5Entities.put("it", "\u2062");
-        html5Entities.put("Itilde", "\u0128");
-        html5Entities.put("itilde", "\u0129");
-        html5Entities.put("Iukcy", "\u0406");
-        html5Entities.put("iukcy", "\u0456");
-        html5Entities.put("Iuml", "\u00CF");
-        html5Entities.put("iuml", "\u00EF");
-        html5Entities.put("Jcirc", "\u0134");
-        html5Entities.put("jcirc", "\u0135");
-        html5Entities.put("Jcy", "\u0419");
-        html5Entities.put("jcy", "\u0439");
-        html5Entities.put("Jfr", "\uD835\uDD0D");
-        html5Entities.put("jfr", "\uD835\uDD27");
-        html5Entities.put("jmath", "\u0237");
-        html5Entities.put("Jopf", "\uD835\uDD41");
-        html5Entities.put("jopf", "\uD835\uDD5B");
-        html5Entities.put("Jscr", "\uD835\uDCA5");
-        html5Entities.put("jscr", "\uD835\uDCBF");
-        html5Entities.put("Jsercy", "\u0408");
-        html5Entities.put("jsercy", "\u0458");
-        html5Entities.put("Jukcy", "\u0404");
-        html5Entities.put("jukcy", "\u0454");
-        html5Entities.put("Kappa", "\u039A");
-        html5Entities.put("kappa", "\u03BA");
-        html5Entities.put("kappav", "\u03F0");
-        html5Entities.put("Kcedil", "\u0136");
-        html5Entities.put("kcedil", "\u0137");
-        html5Entities.put("Kcy", "\u041A");
-        html5Entities.put("kcy", "\u043A");
-        html5Entities.put("Kfr", "\uD835\uDD0E");
-        html5Entities.put("kfr", "\uD835\uDD28");
-        html5Entities.put("kgreen", "\u0138");
-        html5Entities.put("KHcy", "\u0425");
-        html5Entities.put("khcy", "\u0445");
-        html5Entities.put("KJcy", "\u040C");
-        html5Entities.put("kjcy", "\u045C");
-        html5Entities.put("Kopf", "\uD835\uDD42");
-        html5Entities.put("kopf", "\uD835\uDD5C");
-        html5Entities.put("Kscr", "\uD835\uDCA6");
-        html5Entities.put("kscr", "\uD835\uDCC0");
-        html5Entities.put("lAarr", "\u21DA");
-        html5Entities.put("Lacute", "\u0139");
-        html5Entities.put("lacute", "\u013A");
-        html5Entities.put("laemptyv", "\u29B4");
-        html5Entities.put("lagran", "\u2112");
-        html5Entities.put("Lambda", "\u039B");
-        html5Entities.put("lambda", "\u03BB");
-        html5Entities.put("lang", "\u27E8");
-        html5Entities.put("Lang", "\u27EA");
-        html5Entities.put("langd", "\u2991");
-        html5Entities.put("langle", "\u27E8");
-        html5Entities.put("lap", "\u2A85");
-        html5Entities.put("Laplacetrf", "\u2112");
-        html5Entities.put("laquo", "\u00AB");
-        html5Entities.put("larrb", "\u21E4");
-        html5Entities.put("larrbfs", "\u291F");
-        html5Entities.put("larr", "\u2190");
-        html5Entities.put("Larr", "\u219E");
-        html5Entities.put("lArr", "\u21D0");
-        html5Entities.put("larrfs", "\u291D");
-        html5Entities.put("larrhk", "\u21A9");
-        html5Entities.put("larrlp", "\u21AB");
-        html5Entities.put("larrpl", "\u2939");
-        html5Entities.put("larrsim", "\u2973");
-        html5Entities.put("larrtl", "\u21A2");
-        html5Entities.put("latail", "\u2919");
-        html5Entities.put("lAtail", "\u291B");
-        html5Entities.put("lat", "\u2AAB");
-        html5Entities.put("late", "\u2AAD");
-        html5Entities.put("lates", "\u2AAD\uFE00");
-        html5Entities.put("lbarr", "\u290C");
-        html5Entities.put("lBarr", "\u290E");
-        html5Entities.put("lbbrk", "\u2772");
-        html5Entities.put("lbrace", "\u007B");
-        html5Entities.put("lbrack", "\u005B");
-        html5Entities.put("lbrke", "\u298B");
-        html5Entities.put("lbrksld", "\u298F");
-        html5Entities.put("lbrkslu", "\u298D");
-        html5Entities.put("Lcaron", "\u013D");
-        html5Entities.put("lcaron", "\u013E");
-        html5Entities.put("Lcedil", "\u013B");
-        html5Entities.put("lcedil", "\u013C");
-        html5Entities.put("lceil", "\u2308");
-        html5Entities.put("lcub", "\u007B");
-        html5Entities.put("Lcy", "\u041B");
-        html5Entities.put("lcy", "\u043B");
-        html5Entities.put("ldca", "\u2936");
-        html5Entities.put("ldquo", "\u201C");
-        html5Entities.put("ldquor", "\u201E");
-        html5Entities.put("ldrdhar", "\u2967");
-        html5Entities.put("ldrushar", "\u294B");
-        html5Entities.put("ldsh", "\u21B2");
-        html5Entities.put("le", "\u2264");
-        html5Entities.put("lE", "\u2266");
-        html5Entities.put("LeftAngleBracket", "\u27E8");
-        html5Entities.put("LeftArrowBar", "\u21E4");
-        html5Entities.put("leftarrow", "\u2190");
-        html5Entities.put("LeftArrow", "\u2190");
-        html5Entities.put("Leftarrow", "\u21D0");
-        html5Entities.put("LeftArrowRightArrow", "\u21C6");
-        html5Entities.put("leftarrowtail", "\u21A2");
-        html5Entities.put("LeftCeiling", "\u2308");
-        html5Entities.put("LeftDoubleBracket", "\u27E6");
-        html5Entities.put("LeftDownTeeVector", "\u2961");
-        html5Entities.put("LeftDownVectorBar", "\u2959");
-        html5Entities.put("LeftDownVector", "\u21C3");
-        html5Entities.put("LeftFloor", "\u230A");
-        html5Entities.put("leftharpoondown", "\u21BD");
-        html5Entities.put("leftharpoonup", "\u21BC");
-        html5Entities.put("leftleftarrows", "\u21C7");
-        html5Entities.put("leftrightarrow", "\u2194");
-        html5Entities.put("LeftRightArrow", "\u2194");
-        html5Entities.put("Leftrightarrow", "\u21D4");
-        html5Entities.put("leftrightarrows", "\u21C6");
-        html5Entities.put("leftrightharpoons", "\u21CB");
-        html5Entities.put("leftrightsquigarrow", "\u21AD");
-        html5Entities.put("LeftRightVector", "\u294E");
-        html5Entities.put("LeftTeeArrow", "\u21A4");
-        html5Entities.put("LeftTee", "\u22A3");
-        html5Entities.put("LeftTeeVector", "\u295A");
-        html5Entities.put("leftthreetimes", "\u22CB");
-        html5Entities.put("LeftTriangleBar", "\u29CF");
-        html5Entities.put("LeftTriangle", "\u22B2");
-        html5Entities.put("LeftTriangleEqual", "\u22B4");
-        html5Entities.put("LeftUpDownVector", "\u2951");
-        html5Entities.put("LeftUpTeeVector", "\u2960");
-        html5Entities.put("LeftUpVectorBar", "\u2958");
-        html5Entities.put("LeftUpVector", "\u21BF");
-        html5Entities.put("LeftVectorBar", "\u2952");
-        html5Entities.put("LeftVector", "\u21BC");
-        html5Entities.put("lEg", "\u2A8B");
-        html5Entities.put("leg", "\u22DA");
-        html5Entities.put("leq", "\u2264");
-        html5Entities.put("leqq", "\u2266");
-        html5Entities.put("leqslant", "\u2A7D");
-        html5Entities.put("lescc", "\u2AA8");
-        html5Entities.put("les", "\u2A7D");
-        html5Entities.put("lesdot", "\u2A7F");
-        html5Entities.put("lesdoto", "\u2A81");
-        html5Entities.put("lesdotor", "\u2A83");
-        html5Entities.put("lesg", "\u22DA\uFE00");
-        html5Entities.put("lesges", "\u2A93");
-        html5Entities.put("lessapprox", "\u2A85");
-        html5Entities.put("lessdot", "\u22D6");
-        html5Entities.put("lesseqgtr", "\u22DA");
-        html5Entities.put("lesseqqgtr", "\u2A8B");
-        html5Entities.put("LessEqualGreater", "\u22DA");
-        html5Entities.put("LessFullEqual", "\u2266");
-        html5Entities.put("LessGreater", "\u2276");
-        html5Entities.put("lessgtr", "\u2276");
-        html5Entities.put("LessLess", "\u2AA1");
-        html5Entities.put("lesssim", "\u2272");
-        html5Entities.put("LessSlantEqual", "\u2A7D");
-        html5Entities.put("LessTilde", "\u2272");
-        html5Entities.put("lfisht", "\u297C");
-        html5Entities.put("lfloor", "\u230A");
-        html5Entities.put("Lfr", "\uD835\uDD0F");
-        html5Entities.put("lfr", "\uD835\uDD29");
-        html5Entities.put("lg", "\u2276");
-        html5Entities.put("lgE", "\u2A91");
-        html5Entities.put("lHar", "\u2962");
-        html5Entities.put("lhard", "\u21BD");
-        html5Entities.put("lharu", "\u21BC");
-        html5Entities.put("lharul", "\u296A");
-        html5Entities.put("lhblk", "\u2584");
-        html5Entities.put("LJcy", "\u0409");
-        html5Entities.put("ljcy", "\u0459");
-        html5Entities.put("llarr", "\u21C7");
-        html5Entities.put("ll", "\u226A");
-        html5Entities.put("Ll", "\u22D8");
-        html5Entities.put("llcorner", "\u231E");
-        html5Entities.put("Lleftarrow", "\u21DA");
-        html5Entities.put("llhard", "\u296B");
-        html5Entities.put("lltri", "\u25FA");
-        html5Entities.put("Lmidot", "\u013F");
-        html5Entities.put("lmidot", "\u0140");
-        html5Entities.put("lmoustache", "\u23B0");
-        html5Entities.put("lmoust", "\u23B0");
-        html5Entities.put("lnap", "\u2A89");
-        html5Entities.put("lnapprox", "\u2A89");
-        html5Entities.put("lne", "\u2A87");
-        html5Entities.put("lnE", "\u2268");
-        html5Entities.put("lneq", "\u2A87");
-        html5Entities.put("lneqq", "\u2268");
-        html5Entities.put("lnsim", "\u22E6");
-        html5Entities.put("loang", "\u27EC");
-        html5Entities.put("loarr", "\u21FD");
-        html5Entities.put("lobrk", "\u27E6");
-        html5Entities.put("longleftarrow", "\u27F5");
-        html5Entities.put("LongLeftArrow", "\u27F5");
-        html5Entities.put("Longleftarrow", "\u27F8");
-        html5Entities.put("longleftrightarrow", "\u27F7");
-        html5Entities.put("LongLeftRightArrow", "\u27F7");
-        html5Entities.put("Longleftrightarrow", "\u27FA");
-        html5Entities.put("longmapsto", "\u27FC");
-        html5Entities.put("longrightarrow", "\u27F6");
-        html5Entities.put("LongRightArrow", "\u27F6");
-        html5Entities.put("Longrightarrow", "\u27F9");
-        html5Entities.put("looparrowleft", "\u21AB");
-        html5Entities.put("looparrowright", "\u21AC");
-        html5Entities.put("lopar", "\u2985");
-        html5Entities.put("Lopf", "\uD835\uDD43");
-        html5Entities.put("lopf", "\uD835\uDD5D");
-        html5Entities.put("loplus", "\u2A2D");
-        html5Entities.put("lotimes", "\u2A34");
-        html5Entities.put("lowast", "\u2217");
-        html5Entities.put("lowbar", "\u005F");
-        html5Entities.put("LowerLeftArrow", "\u2199");
-        html5Entities.put("LowerRightArrow", "\u2198");
-        html5Entities.put("loz", "\u25CA");
-        html5Entities.put("lozenge", "\u25CA");
-        html5Entities.put("lozf", "\u29EB");
-        html5Entities.put("lpar", "\u0028");
-        html5Entities.put("lparlt", "\u2993");
-        html5Entities.put("lrarr", "\u21C6");
-        html5Entities.put("lrcorner", "\u231F");
-        html5Entities.put("lrhar", "\u21CB");
-        html5Entities.put("lrhard", "\u296D");
-        html5Entities.put("lrm", "\u200E");
-        html5Entities.put("lrtri", "\u22BF");
-        html5Entities.put("lsaquo", "\u2039");
-        html5Entities.put("lscr", "\uD835\uDCC1");
-        html5Entities.put("Lscr", "\u2112");
-        html5Entities.put("lsh", "\u21B0");
-        html5Entities.put("Lsh", "\u21B0");
-        html5Entities.put("lsim", "\u2272");
-        html5Entities.put("lsime", "\u2A8D");
-        html5Entities.put("lsimg", "\u2A8F");
-        html5Entities.put("lsqb", "\u005B");
-        html5Entities.put("lsquo", "\u2018");
-        html5Entities.put("lsquor", "\u201A");
-        html5Entities.put("Lstrok", "\u0141");
-        html5Entities.put("lstrok", "\u0142");
-        html5Entities.put("ltcc", "\u2AA6");
-        html5Entities.put("ltcir", "\u2A79");
-        html5Entities.put("lt", "\u003C");
-        html5Entities.put("LT", "\u003C");
-        html5Entities.put("Lt", "\u226A");
-        html5Entities.put("ltdot", "\u22D6");
-        html5Entities.put("lthree", "\u22CB");
-        html5Entities.put("ltimes", "\u22C9");
-        html5Entities.put("ltlarr", "\u2976");
-        html5Entities.put("ltquest", "\u2A7B");
-        html5Entities.put("ltri", "\u25C3");
-        html5Entities.put("ltrie", "\u22B4");
-        html5Entities.put("ltrif", "\u25C2");
-        html5Entities.put("ltrPar", "\u2996");
-        html5Entities.put("lurdshar", "\u294A");
-        html5Entities.put("luruhar", "\u2966");
-        html5Entities.put("lvertneqq", "\u2268\uFE00");
-        html5Entities.put("lvnE", "\u2268\uFE00");
-        html5Entities.put("macr", "\u00AF");
-        html5Entities.put("male", "\u2642");
-        html5Entities.put("malt", "\u2720");
-        html5Entities.put("maltese", "\u2720");
-        html5Entities.put("Map", "\u2905");
-        html5Entities.put("map", "\u21A6");
-        html5Entities.put("mapsto", "\u21A6");
-        html5Entities.put("mapstodown", "\u21A7");
-        html5Entities.put("mapstoleft", "\u21A4");
-        html5Entities.put("mapstoup", "\u21A5");
-        html5Entities.put("marker", "\u25AE");
-        html5Entities.put("mcomma", "\u2A29");
-        html5Entities.put("Mcy", "\u041C");
-        html5Entities.put("mcy", "\u043C");
-        html5Entities.put("mdash", "\u2014");
-        html5Entities.put("mDDot", "\u223A");
-        html5Entities.put("measuredangle", "\u2221");
-        html5Entities.put("MediumSpace", "\u205F");
-        html5Entities.put("Mellintrf", "\u2133");
-        html5Entities.put("Mfr", "\uD835\uDD10");
-        html5Entities.put("mfr", "\uD835\uDD2A");
-        html5Entities.put("mho", "\u2127");
-        html5Entities.put("micro", "\u00B5");
-        html5Entities.put("midast", "\u002A");
-        html5Entities.put("midcir", "\u2AF0");
-        html5Entities.put("mid", "\u2223");
-        html5Entities.put("middot", "\u00B7");
-        html5Entities.put("minusb", "\u229F");
-        html5Entities.put("minus", "\u2212");
-        html5Entities.put("minusd", "\u2238");
-        html5Entities.put("minusdu", "\u2A2A");
-        html5Entities.put("MinusPlus", "\u2213");
-        html5Entities.put("mlcp", "\u2ADB");
-        html5Entities.put("mldr", "\u2026");
-        html5Entities.put("mnplus", "\u2213");
-        html5Entities.put("models", "\u22A7");
-        html5Entities.put("Mopf", "\uD835\uDD44");
-        html5Entities.put("mopf", "\uD835\uDD5E");
-        html5Entities.put("mp", "\u2213");
-        html5Entities.put("mscr", "\uD835\uDCC2");
-        html5Entities.put("Mscr", "\u2133");
-        html5Entities.put("mstpos", "\u223E");
-        html5Entities.put("Mu", "\u039C");
-        html5Entities.put("mu", "\u03BC");
-        html5Entities.put("multimap", "\u22B8");
-        html5Entities.put("mumap", "\u22B8");
-        html5Entities.put("nabla", "\u2207");
-        html5Entities.put("Nacute", "\u0143");
-        html5Entities.put("nacute", "\u0144");
-        html5Entities.put("nang", "\u2220\u20D2");
-        html5Entities.put("nap", "\u2249");
-        html5Entities.put("napE", "\u2A70\u0338");
-        html5Entities.put("napid", "\u224B\u0338");
-        html5Entities.put("napos", "\u0149");
-        html5Entities.put("napprox", "\u2249");
-        html5Entities.put("natural", "\u266E");
-        html5Entities.put("naturals", "\u2115");
-        html5Entities.put("natur", "\u266E");
-        html5Entities.put("nbsp", "\u00A0");
-        html5Entities.put("nbump", "\u224E\u0338");
-        html5Entities.put("nbumpe", "\u224F\u0338");
-        html5Entities.put("ncap", "\u2A43");
-        html5Entities.put("Ncaron", "\u0147");
-        html5Entities.put("ncaron", "\u0148");
-        html5Entities.put("Ncedil", "\u0145");
-        html5Entities.put("ncedil", "\u0146");
-        html5Entities.put("ncong", "\u2247");
-        html5Entities.put("ncongdot", "\u2A6D\u0338");
-        html5Entities.put("ncup", "\u2A42");
-        html5Entities.put("Ncy", "\u041D");
-        html5Entities.put("ncy", "\u043D");
-        html5Entities.put("ndash", "\u2013");
-        html5Entities.put("nearhk", "\u2924");
-        html5Entities.put("nearr", "\u2197");
-        html5Entities.put("neArr", "\u21D7");
-        html5Entities.put("nearrow", "\u2197");
-        html5Entities.put("ne", "\u2260");
-        html5Entities.put("nedot", "\u2250\u0338");
-        html5Entities.put("NegativeMediumSpace", "\u200B");
-        html5Entities.put("NegativeThickSpace", "\u200B");
-        html5Entities.put("NegativeThinSpace", "\u200B");
-        html5Entities.put("NegativeVeryThinSpace", "\u200B");
-        html5Entities.put("nequiv", "\u2262");
-        html5Entities.put("nesear", "\u2928");
-        html5Entities.put("nesim", "\u2242\u0338");
-        html5Entities.put("NestedGreaterGreater", "\u226B");
-        html5Entities.put("NestedLessLess", "\u226A");
-        html5Entities.put("NewLine", "\n");
-        html5Entities.put("nexist", "\u2204");
-        html5Entities.put("nexists", "\u2204");
-        html5Entities.put("Nfr", "\uD835\uDD11");
-        html5Entities.put("nfr", "\uD835\uDD2B");
-        html5Entities.put("ngE", "\u2267\u0338");
-        html5Entities.put("nge", "\u2271");
-        html5Entities.put("ngeq", "\u2271");
-        html5Entities.put("ngeqq", "\u2267\u0338");
-        html5Entities.put("ngeqslant", "\u2A7E\u0338");
-        html5Entities.put("nges", "\u2A7E\u0338");
-        html5Entities.put("nGg", "\u22D9\u0338");
-        html5Entities.put("ngsim", "\u2275");
-        html5Entities.put("nGt", "\u226B\u20D2");
-        html5Entities.put("ngt", "\u226F");
-        html5Entities.put("ngtr", "\u226F");
-        html5Entities.put("nGtv", "\u226B\u0338");
-        html5Entities.put("nharr", "\u21AE");
-        html5Entities.put("nhArr", "\u21CE");
-        html5Entities.put("nhpar", "\u2AF2");
-        html5Entities.put("ni", "\u220B");
-        html5Entities.put("nis", "\u22FC");
-        html5Entities.put("nisd", "\u22FA");
-        html5Entities.put("niv", "\u220B");
-        html5Entities.put("NJcy", "\u040A");
-        html5Entities.put("njcy", "\u045A");
-        html5Entities.put("nlarr", "\u219A");
-        html5Entities.put("nlArr", "\u21CD");
-        html5Entities.put("nldr", "\u2025");
-        html5Entities.put("nlE", "\u2266\u0338");
-        html5Entities.put("nle", "\u2270");
-        html5Entities.put("nleftarrow", "\u219A");
-        html5Entities.put("nLeftarrow", "\u21CD");
-        html5Entities.put("nleftrightarrow", "\u21AE");
-        html5Entities.put("nLeftrightarrow", "\u21CE");
-        html5Entities.put("nleq", "\u2270");
-        html5Entities.put("nleqq", "\u2266\u0338");
-        html5Entities.put("nleqslant", "\u2A7D\u0338");
-        html5Entities.put("nles", "\u2A7D\u0338");
-        html5Entities.put("nless", "\u226E");
-        html5Entities.put("nLl", "\u22D8\u0338");
-        html5Entities.put("nlsim", "\u2274");
-        html5Entities.put("nLt", "\u226A\u20D2");
-        html5Entities.put("nlt", "\u226E");
-        html5Entities.put("nltri", "\u22EA");
-        html5Entities.put("nltrie", "\u22EC");
-        html5Entities.put("nLtv", "\u226A\u0338");
-        html5Entities.put("nmid", "\u2224");
-        html5Entities.put("NoBreak", "\u2060");
-        html5Entities.put("NonBreakingSpace", "\u00A0");
-        html5Entities.put("nopf", "\uD835\uDD5F");
-        html5Entities.put("Nopf", "\u2115");
-        html5Entities.put("Not", "\u2AEC");
-        html5Entities.put("not", "\u00AC");
-        html5Entities.put("NotCongruent", "\u2262");
-        html5Entities.put("NotCupCap", "\u226D");
-        html5Entities.put("NotDoubleVerticalBar", "\u2226");
-        html5Entities.put("NotElement", "\u2209");
-        html5Entities.put("NotEqual", "\u2260");
-        html5Entities.put("NotEqualTilde", "\u2242\u0338");
-        html5Entities.put("NotExists", "\u2204");
-        html5Entities.put("NotGreater", "\u226F");
-        html5Entities.put("NotGreaterEqual", "\u2271");
-        html5Entities.put("NotGreaterFullEqual", "\u2267\u0338");
-        html5Entities.put("NotGreaterGreater", "\u226B\u0338");
-        html5Entities.put("NotGreaterLess", "\u2279");
-        html5Entities.put("NotGreaterSlantEqual", "\u2A7E\u0338");
-        html5Entities.put("NotGreaterTilde", "\u2275");
-        html5Entities.put("NotHumpDownHump", "\u224E\u0338");
-        html5Entities.put("NotHumpEqual", "\u224F\u0338");
-        html5Entities.put("notin", "\u2209");
-        html5Entities.put("notindot", "\u22F5\u0338");
-        html5Entities.put("notinE", "\u22F9\u0338");
-        html5Entities.put("notinva", "\u2209");
-        html5Entities.put("notinvb", "\u22F7");
-        html5Entities.put("notinvc", "\u22F6");
-        html5Entities.put("NotLeftTriangleBar", "\u29CF\u0338");
-        html5Entities.put("NotLeftTriangle", "\u22EA");
-        html5Entities.put("NotLeftTriangleEqual", "\u22EC");
-        html5Entities.put("NotLess", "\u226E");
-        html5Entities.put("NotLessEqual", "\u2270");
-        html5Entities.put("NotLessGreater", "\u2278");
-        html5Entities.put("NotLessLess", "\u226A\u0338");
-        html5Entities.put("NotLessSlantEqual", "\u2A7D\u0338");
-        html5Entities.put("NotLessTilde", "\u2274");
-        html5Entities.put("NotNestedGreaterGreater", "\u2AA2\u0338");
-        html5Entities.put("NotNestedLessLess", "\u2AA1\u0338");
-        html5Entities.put("notni", "\u220C");
-        html5Entities.put("notniva", "\u220C");
-        html5Entities.put("notnivb", "\u22FE");
-        html5Entities.put("notnivc", "\u22FD");
-        html5Entities.put("NotPrecedes", "\u2280");
-        html5Entities.put("NotPrecedesEqual", "\u2AAF\u0338");
-        html5Entities.put("NotPrecedesSlantEqual", "\u22E0");
-        html5Entities.put("NotReverseElement", "\u220C");
-        html5Entities.put("NotRightTriangleBar", "\u29D0\u0338");
-        html5Entities.put("NotRightTriangle", "\u22EB");
-        html5Entities.put("NotRightTriangleEqual", "\u22ED");
-        html5Entities.put("NotSquareSubset", "\u228F\u0338");
-        html5Entities.put("NotSquareSubsetEqual", "\u22E2");
-        html5Entities.put("NotSquareSuperset", "\u2290\u0338");
-        html5Entities.put("NotSquareSupersetEqual", "\u22E3");
-        html5Entities.put("NotSubset", "\u2282\u20D2");
-        html5Entities.put("NotSubsetEqual", "\u2288");
-        html5Entities.put("NotSucceeds", "\u2281");
-        html5Entities.put("NotSucceedsEqual", "\u2AB0\u0338");
-        html5Entities.put("NotSucceedsSlantEqual", "\u22E1");
-        html5Entities.put("NotSucceedsTilde", "\u227F\u0338");
-        html5Entities.put("NotSuperset", "\u2283\u20D2");
-        html5Entities.put("NotSupersetEqual", "\u2289");
-        html5Entities.put("NotTilde", "\u2241");
-        html5Entities.put("NotTildeEqual", "\u2244");
-        html5Entities.put("NotTildeFullEqual", "\u2247");
-        html5Entities.put("NotTildeTilde", "\u2249");
-        html5Entities.put("NotVerticalBar", "\u2224");
-        html5Entities.put("nparallel", "\u2226");
-        html5Entities.put("npar", "\u2226");
-        html5Entities.put("nparsl", "\u2AFD\u20E5");
-        html5Entities.put("npart", "\u2202\u0338");
-        html5Entities.put("npolint", "\u2A14");
-        html5Entities.put("npr", "\u2280");
-        html5Entities.put("nprcue", "\u22E0");
-        html5Entities.put("nprec", "\u2280");
-        html5Entities.put("npreceq", "\u2AAF\u0338");
-        html5Entities.put("npre", "\u2AAF\u0338");
-        html5Entities.put("nrarrc", "\u2933\u0338");
-        html5Entities.put("nrarr", "\u219B");
-        html5Entities.put("nrArr", "\u21CF");
-        html5Entities.put("nrarrw", "\u219D\u0338");
-        html5Entities.put("nrightarrow", "\u219B");
-        html5Entities.put("nRightarrow", "\u21CF");
-        html5Entities.put("nrtri", "\u22EB");
-        html5Entities.put("nrtrie", "\u22ED");
-        html5Entities.put("nsc", "\u2281");
-        html5Entities.put("nsccue", "\u22E1");
-        html5Entities.put("nsce", "\u2AB0\u0338");
-        html5Entities.put("Nscr", "\uD835\uDCA9");
-        html5Entities.put("nscr", "\uD835\uDCC3");
-        html5Entities.put("nshortmid", "\u2224");
-        html5Entities.put("nshortparallel", "\u2226");
-        html5Entities.put("nsim", "\u2241");
-        html5Entities.put("nsime", "\u2244");
-        html5Entities.put("nsimeq", "\u2244");
-        html5Entities.put("nsmid", "\u2224");
-        html5Entities.put("nspar", "\u2226");
-        html5Entities.put("nsqsube", "\u22E2");
-        html5Entities.put("nsqsupe", "\u22E3");
-        html5Entities.put("nsub", "\u2284");
-        html5Entities.put("nsubE", "\u2AC5\u0338");
-        html5Entities.put("nsube", "\u2288");
-        html5Entities.put("nsubset", "\u2282\u20D2");
-        html5Entities.put("nsubseteq", "\u2288");
-        html5Entities.put("nsubseteqq", "\u2AC5\u0338");
-        html5Entities.put("nsucc", "\u2281");
-        html5Entities.put("nsucceq", "\u2AB0\u0338");
-        html5Entities.put("nsup", "\u2285");
-        html5Entities.put("nsupE", "\u2AC6\u0338");
-        html5Entities.put("nsupe", "\u2289");
-        html5Entities.put("nsupset", "\u2283\u20D2");
-        html5Entities.put("nsupseteq", "\u2289");
-        html5Entities.put("nsupseteqq", "\u2AC6\u0338");
-        html5Entities.put("ntgl", "\u2279");
-        html5Entities.put("Ntilde", "\u00D1");
-        html5Entities.put("ntilde", "\u00F1");
-        html5Entities.put("ntlg", "\u2278");
-        html5Entities.put("ntriangleleft", "\u22EA");
-        html5Entities.put("ntrianglelefteq", "\u22EC");
-        html5Entities.put("ntriangleright", "\u22EB");
-        html5Entities.put("ntrianglerighteq", "\u22ED");
-        html5Entities.put("Nu", "\u039D");
-        html5Entities.put("nu", "\u03BD");
-        html5Entities.put("num", "\u0023");
-        html5Entities.put("numero", "\u2116");
-        html5Entities.put("numsp", "\u2007");
-        html5Entities.put("nvap", "\u224D\u20D2");
-        html5Entities.put("nvdash", "\u22AC");
-        html5Entities.put("nvDash", "\u22AD");
-        html5Entities.put("nVdash", "\u22AE");
-        html5Entities.put("nVDash", "\u22AF");
-        html5Entities.put("nvge", "\u2265\u20D2");
-        html5Entities.put("nvgt", "\u003E\u20D2");
-        html5Entities.put("nvHarr", "\u2904");
-        html5Entities.put("nvinfin", "\u29DE");
-        html5Entities.put("nvlArr", "\u2902");
-        html5Entities.put("nvle", "\u2264\u20D2");
-        html5Entities.put("nvlt", "\u003C\u20D2");
-        html5Entities.put("nvltrie", "\u22B4\u20D2");
-        html5Entities.put("nvrArr", "\u2903");
-        html5Entities.put("nvrtrie", "\u22B5\u20D2");
-        html5Entities.put("nvsim", "\u223C\u20D2");
-        html5Entities.put("nwarhk", "\u2923");
-        html5Entities.put("nwarr", "\u2196");
-        html5Entities.put("nwArr", "\u21D6");
-        html5Entities.put("nwarrow", "\u2196");
-        html5Entities.put("nwnear", "\u2927");
-        html5Entities.put("Oacute", "\u00D3");
-        html5Entities.put("oacute", "\u00F3");
-        html5Entities.put("oast", "\u229B");
-        html5Entities.put("Ocirc", "\u00D4");
-        html5Entities.put("ocirc", "\u00F4");
-        html5Entities.put("ocir", "\u229A");
-        html5Entities.put("Ocy", "\u041E");
-        html5Entities.put("ocy", "\u043E");
-        html5Entities.put("odash", "\u229D");
-        html5Entities.put("Odblac", "\u0150");
-        html5Entities.put("odblac", "\u0151");
-        html5Entities.put("odiv", "\u2A38");
-        html5Entities.put("odot", "\u2299");
-        html5Entities.put("odsold", "\u29BC");
-        html5Entities.put("OElig", "\u0152");
-        html5Entities.put("oelig", "\u0153");
-        html5Entities.put("ofcir", "\u29BF");
-        html5Entities.put("Ofr", "\uD835\uDD12");
-        html5Entities.put("ofr", "\uD835\uDD2C");
-        html5Entities.put("ogon", "\u02DB");
-        html5Entities.put("Ograve", "\u00D2");
-        html5Entities.put("ograve", "\u00F2");
-        html5Entities.put("ogt", "\u29C1");
-        html5Entities.put("ohbar", "\u29B5");
-        html5Entities.put("ohm", "\u03A9");
-        html5Entities.put("oint", "\u222E");
-        html5Entities.put("olarr", "\u21BA");
-        html5Entities.put("olcir", "\u29BE");
-        html5Entities.put("olcross", "\u29BB");
-        html5Entities.put("oline", "\u203E");
-        html5Entities.put("olt", "\u29C0");
-        html5Entities.put("Omacr", "\u014C");
-        html5Entities.put("omacr", "\u014D");
-        html5Entities.put("Omega", "\u03A9");
-        html5Entities.put("omega", "\u03C9");
-        html5Entities.put("Omicron", "\u039F");
-        html5Entities.put("omicron", "\u03BF");
-        html5Entities.put("omid", "\u29B6");
-        html5Entities.put("ominus", "\u2296");
-        html5Entities.put("Oopf", "\uD835\uDD46");
-        html5Entities.put("oopf", "\uD835\uDD60");
-        html5Entities.put("opar", "\u29B7");
-        html5Entities.put("OpenCurlyDoubleQuote", "\u201C");
-        html5Entities.put("OpenCurlyQuote", "\u2018");
-        html5Entities.put("operp", "\u29B9");
-        html5Entities.put("oplus", "\u2295");
-        html5Entities.put("orarr", "\u21BB");
-        html5Entities.put("Or", "\u2A54");
-        html5Entities.put("or", "\u2228");
-        html5Entities.put("ord", "\u2A5D");
-        html5Entities.put("order", "\u2134");
-        html5Entities.put("orderof", "\u2134");
-        html5Entities.put("ordf", "\u00AA");
-        html5Entities.put("ordm", "\u00BA");
-        html5Entities.put("origof", "\u22B6");
-        html5Entities.put("oror", "\u2A56");
-        html5Entities.put("orslope", "\u2A57");
-        html5Entities.put("orv", "\u2A5B");
-        html5Entities.put("oS", "\u24C8");
-        html5Entities.put("Oscr", "\uD835\uDCAA");
-        html5Entities.put("oscr", "\u2134");
-        html5Entities.put("Oslash", "\u00D8");
-        html5Entities.put("oslash", "\u00F8");
-        html5Entities.put("osol", "\u2298");
-        html5Entities.put("Otilde", "\u00D5");
-        html5Entities.put("otilde", "\u00F5");
-        html5Entities.put("otimesas", "\u2A36");
-        html5Entities.put("Otimes", "\u2A37");
-        html5Entities.put("otimes", "\u2297");
-        html5Entities.put("Ouml", "\u00D6");
-        html5Entities.put("ouml", "\u00F6");
-        html5Entities.put("ovbar", "\u233D");
-        html5Entities.put("OverBar", "\u203E");
-        html5Entities.put("OverBrace", "\u23DE");
-        html5Entities.put("OverBracket", "\u23B4");
-        html5Entities.put("OverParenthesis", "\u23DC");
-        html5Entities.put("para", "\u00B6");
-        html5Entities.put("parallel", "\u2225");
-        html5Entities.put("par", "\u2225");
-        html5Entities.put("parsim", "\u2AF3");
-        html5Entities.put("parsl", "\u2AFD");
-        html5Entities.put("part", "\u2202");
-        html5Entities.put("PartialD", "\u2202");
-        html5Entities.put("Pcy", "\u041F");
-        html5Entities.put("pcy", "\u043F");
-        html5Entities.put("percnt", "\u0025");
-        html5Entities.put("period", "\u002E");
-        html5Entities.put("permil", "\u2030");
-        html5Entities.put("perp", "\u22A5");
-        html5Entities.put("pertenk", "\u2031");
-        html5Entities.put("Pfr", "\uD835\uDD13");
-        html5Entities.put("pfr", "\uD835\uDD2D");
-        html5Entities.put("Phi", "\u03A6");
-        html5Entities.put("phi", "\u03C6");
-        html5Entities.put("phiv", "\u03D5");
-        html5Entities.put("phmmat", "\u2133");
-        html5Entities.put("phone", "\u260E");
-        html5Entities.put("Pi", "\u03A0");
-        html5Entities.put("pi", "\u03C0");
-        html5Entities.put("pitchfork", "\u22D4");
-        html5Entities.put("piv", "\u03D6");
-        html5Entities.put("planck", "\u210F");
-        html5Entities.put("planckh", "\u210E");
-        html5Entities.put("plankv", "\u210F");
-        html5Entities.put("plusacir", "\u2A23");
-        html5Entities.put("plusb", "\u229E");
-        html5Entities.put("pluscir", "\u2A22");
-        html5Entities.put("plus", "\u002B");
-        html5Entities.put("plusdo", "\u2214");
-        html5Entities.put("plusdu", "\u2A25");
-        html5Entities.put("pluse", "\u2A72");
-        html5Entities.put("PlusMinus", "\u00B1");
-        html5Entities.put("plusmn", "\u00B1");
-        html5Entities.put("plussim", "\u2A26");
-        html5Entities.put("plustwo", "\u2A27");
-        html5Entities.put("pm", "\u00B1");
-        html5Entities.put("Poincareplane", "\u210C");
-        html5Entities.put("pointint", "\u2A15");
-        html5Entities.put("popf", "\uD835\uDD61");
-        html5Entities.put("Popf", "\u2119");
-        html5Entities.put("pound", "\u00A3");
-        html5Entities.put("prap", "\u2AB7");
-        html5Entities.put("Pr", "\u2ABB");
-        html5Entities.put("pr", "\u227A");
-        html5Entities.put("prcue", "\u227C");
-        html5Entities.put("precapprox", "\u2AB7");
-        html5Entities.put("prec", "\u227A");
-        html5Entities.put("preccurlyeq", "\u227C");
-        html5Entities.put("Precedes", "\u227A");
-        html5Entities.put("PrecedesEqual", "\u2AAF");
-        html5Entities.put("PrecedesSlantEqual", "\u227C");
-        html5Entities.put("PrecedesTilde", "\u227E");
-        html5Entities.put("preceq", "\u2AAF");
-        html5Entities.put("precnapprox", "\u2AB9");
-        html5Entities.put("precneqq", "\u2AB5");
-        html5Entities.put("precnsim", "\u22E8");
-        html5Entities.put("pre", "\u2AAF");
-        html5Entities.put("prE", "\u2AB3");
-        html5Entities.put("precsim", "\u227E");
-        html5Entities.put("prime", "\u2032");
-        html5Entities.put("Prime", "\u2033");
-        html5Entities.put("primes", "\u2119");
-        html5Entities.put("prnap", "\u2AB9");
-        html5Entities.put("prnE", "\u2AB5");
-        html5Entities.put("prnsim", "\u22E8");
-        html5Entities.put("prod", "\u220F");
-        html5Entities.put("Product", "\u220F");
-        html5Entities.put("profalar", "\u232E");
-        html5Entities.put("profline", "\u2312");
-        html5Entities.put("profsurf", "\u2313");
-        html5Entities.put("prop", "\u221D");
-        html5Entities.put("Proportional", "\u221D");
-        html5Entities.put("Proportion", "\u2237");
-        html5Entities.put("propto", "\u221D");
-        html5Entities.put("prsim", "\u227E");
-        html5Entities.put("prurel", "\u22B0");
-        html5Entities.put("Pscr", "\uD835\uDCAB");
-        html5Entities.put("pscr", "\uD835\uDCC5");
-        html5Entities.put("Psi", "\u03A8");
-        html5Entities.put("psi", "\u03C8");
-        html5Entities.put("puncsp", "\u2008");
-        html5Entities.put("Qfr", "\uD835\uDD14");
-        html5Entities.put("qfr", "\uD835\uDD2E");
-        html5Entities.put("qint", "\u2A0C");
-        html5Entities.put("qopf", "\uD835\uDD62");
-        html5Entities.put("Qopf", "\u211A");
-        html5Entities.put("qprime", "\u2057");
-        html5Entities.put("Qscr", "\uD835\uDCAC");
-        html5Entities.put("qscr", "\uD835\uDCC6");
-        html5Entities.put("quaternions", "\u210D");
-        html5Entities.put("quatint", "\u2A16");
-        html5Entities.put("quest", "\u003F");
-        html5Entities.put("questeq", "\u225F");
-        html5Entities.put("quot", "\"");
-        html5Entities.put("QUOT", "\"");
-        html5Entities.put("rAarr", "\u21DB");
-        html5Entities.put("race", "\u223D\u0331");
-        html5Entities.put("Racute", "\u0154");
-        html5Entities.put("racute", "\u0155");
-        html5Entities.put("radic", "\u221A");
-        html5Entities.put("raemptyv", "\u29B3");
-        html5Entities.put("rang", "\u27E9");
-        html5Entities.put("Rang", "\u27EB");
-        html5Entities.put("rangd", "\u2992");
-        html5Entities.put("range", "\u29A5");
-        html5Entities.put("rangle", "\u27E9");
-        html5Entities.put("raquo", "\u00BB");
-        html5Entities.put("rarrap", "\u2975");
-        html5Entities.put("rarrb", "\u21E5");
-        html5Entities.put("rarrbfs", "\u2920");
-        html5Entities.put("rarrc", "\u2933");
-        html5Entities.put("rarr", "\u2192");
-        html5Entities.put("Rarr", "\u21A0");
-        html5Entities.put("rArr", "\u21D2");
-        html5Entities.put("rarrfs", "\u291E");
-        html5Entities.put("rarrhk", "\u21AA");
-        html5Entities.put("rarrlp", "\u21AC");
-        html5Entities.put("rarrpl", "\u2945");
-        html5Entities.put("rarrsim", "\u2974");
-        html5Entities.put("Rarrtl", "\u2916");
-        html5Entities.put("rarrtl", "\u21A3");
-        html5Entities.put("rarrw", "\u219D");
-        html5Entities.put("ratail", "\u291A");
-        html5Entities.put("rAtail", "\u291C");
-        html5Entities.put("ratio", "\u2236");
-        html5Entities.put("rationals", "\u211A");
-        html5Entities.put("rbarr", "\u290D");
-        html5Entities.put("rBarr", "\u290F");
-        html5Entities.put("RBarr", "\u2910");
-        html5Entities.put("rbbrk", "\u2773");
-        html5Entities.put("rbrace", "\u007D");
-        html5Entities.put("rbrack", "\u005D");
-        html5Entities.put("rbrke", "\u298C");
-        html5Entities.put("rbrksld", "\u298E");
-        html5Entities.put("rbrkslu", "\u2990");
-        html5Entities.put("Rcaron", "\u0158");
-        html5Entities.put("rcaron", "\u0159");
-        html5Entities.put("Rcedil", "\u0156");
-        html5Entities.put("rcedil", "\u0157");
-        html5Entities.put("rceil", "\u2309");
-        html5Entities.put("rcub", "\u007D");
-        html5Entities.put("Rcy", "\u0420");
-        html5Entities.put("rcy", "\u0440");
-        html5Entities.put("rdca", "\u2937");
-        html5Entities.put("rdldhar", "\u2969");
-        html5Entities.put("rdquo", "\u201D");
-        html5Entities.put("rdquor", "\u201D");
-        html5Entities.put("rdsh", "\u21B3");
-        html5Entities.put("real", "\u211C");
-        html5Entities.put("realine", "\u211B");
-        html5Entities.put("realpart", "\u211C");
-        html5Entities.put("reals", "\u211D");
-        html5Entities.put("Re", "\u211C");
-        html5Entities.put("rect", "\u25AD");
-        html5Entities.put("reg", "\u00AE");
-        html5Entities.put("REG", "\u00AE");
-        html5Entities.put("ReverseElement", "\u220B");
-        html5Entities.put("ReverseEquilibrium", "\u21CB");
-        html5Entities.put("ReverseUpEquilibrium", "\u296F");
-        html5Entities.put("rfisht", "\u297D");
-        html5Entities.put("rfloor", "\u230B");
-        html5Entities.put("rfr", "\uD835\uDD2F");
-        html5Entities.put("Rfr", "\u211C");
-        html5Entities.put("rHar", "\u2964");
-        html5Entities.put("rhard", "\u21C1");
-        html5Entities.put("rharu", "\u21C0");
-        html5Entities.put("rharul", "\u296C");
-        html5Entities.put("Rho", "\u03A1");
-        html5Entities.put("rho", "\u03C1");
-        html5Entities.put("rhov", "\u03F1");
-        html5Entities.put("RightAngleBracket", "\u27E9");
-        html5Entities.put("RightArrowBar", "\u21E5");
-        html5Entities.put("rightarrow", "\u2192");
-        html5Entities.put("RightArrow", "\u2192");
-        html5Entities.put("Rightarrow", "\u21D2");
-        html5Entities.put("RightArrowLeftArrow", "\u21C4");
-        html5Entities.put("rightarrowtail", "\u21A3");
-        html5Entities.put("RightCeiling", "\u2309");
-        html5Entities.put("RightDoubleBracket", "\u27E7");
-        html5Entities.put("RightDownTeeVector", "\u295D");
-        html5Entities.put("RightDownVectorBar", "\u2955");
-        html5Entities.put("RightDownVector", "\u21C2");
-        html5Entities.put("RightFloor", "\u230B");
-        html5Entities.put("rightharpoondown", "\u21C1");
-        html5Entities.put("rightharpoonup", "\u21C0");
-        html5Entities.put("rightleftarrows", "\u21C4");
-        html5Entities.put("rightleftharpoons", "\u21CC");
-        html5Entities.put("rightrightarrows", "\u21C9");
-        html5Entities.put("rightsquigarrow", "\u219D");
-        html5Entities.put("RightTeeArrow", "\u21A6");
-        html5Entities.put("RightTee", "\u22A2");
-        html5Entities.put("RightTeeVector", "\u295B");
-        html5Entities.put("rightthreetimes", "\u22CC");
-        html5Entities.put("RightTriangleBar", "\u29D0");
-        html5Entities.put("RightTriangle", "\u22B3");
-        html5Entities.put("RightTriangleEqual", "\u22B5");
-        html5Entities.put("RightUpDownVector", "\u294F");
-        html5Entities.put("RightUpTeeVector", "\u295C");
-        html5Entities.put("RightUpVectorBar", "\u2954");
-        html5Entities.put("RightUpVector", "\u21BE");
-        html5Entities.put("RightVectorBar", "\u2953");
-        html5Entities.put("RightVector", "\u21C0");
-        html5Entities.put("ring", "\u02DA");
-        html5Entities.put("risingdotseq", "\u2253");
-        html5Entities.put("rlarr", "\u21C4");
-        html5Entities.put("rlhar", "\u21CC");
-        html5Entities.put("rlm", "\u200F");
-        html5Entities.put("rmoustache", "\u23B1");
-        html5Entities.put("rmoust", "\u23B1");
-        html5Entities.put("rnmid", "\u2AEE");
-        html5Entities.put("roang", "\u27ED");
-        html5Entities.put("roarr", "\u21FE");
-        html5Entities.put("robrk", "\u27E7");
-        html5Entities.put("ropar", "\u2986");
-        html5Entities.put("ropf", "\uD835\uDD63");
-        html5Entities.put("Ropf", "\u211D");
-        html5Entities.put("roplus", "\u2A2E");
-        html5Entities.put("rotimes", "\u2A35");
-        html5Entities.put("RoundImplies", "\u2970");
-        html5Entities.put("rpar", "\u0029");
-        html5Entities.put("rpargt", "\u2994");
-        html5Entities.put("rppolint", "\u2A12");
-        html5Entities.put("rrarr", "\u21C9");
-        html5Entities.put("Rrightarrow", "\u21DB");
-        html5Entities.put("rsaquo", "\u203A");
-        html5Entities.put("rscr", "\uD835\uDCC7");
-        html5Entities.put("Rscr", "\u211B");
-        html5Entities.put("rsh", "\u21B1");
-        html5Entities.put("Rsh", "\u21B1");
-        html5Entities.put("rsqb", "\u005D");
-        html5Entities.put("rsquo", "\u2019");
-        html5Entities.put("rsquor", "\u2019");
-        html5Entities.put("rthree", "\u22CC");
-        html5Entities.put("rtimes", "\u22CA");
-        html5Entities.put("rtri", "\u25B9");
-        html5Entities.put("rtrie", "\u22B5");
-        html5Entities.put("rtrif", "\u25B8");
-        html5Entities.put("rtriltri", "\u29CE");
-        html5Entities.put("RuleDelayed", "\u29F4");
-        html5Entities.put("ruluhar", "\u2968");
-        html5Entities.put("rx", "\u211E");
-        html5Entities.put("Sacute", "\u015A");
-        html5Entities.put("sacute", "\u015B");
-        html5Entities.put("sbquo", "\u201A");
-        html5Entities.put("scap", "\u2AB8");
-        html5Entities.put("Scaron", "\u0160");
-        html5Entities.put("scaron", "\u0161");
-        html5Entities.put("Sc", "\u2ABC");
-        html5Entities.put("sc", "\u227B");
-        html5Entities.put("sccue", "\u227D");
-        html5Entities.put("sce", "\u2AB0");
-        html5Entities.put("scE", "\u2AB4");
-        html5Entities.put("Scedil", "\u015E");
-        html5Entities.put("scedil", "\u015F");
-        html5Entities.put("Scirc", "\u015C");
-        html5Entities.put("scirc", "\u015D");
-        html5Entities.put("scnap", "\u2ABA");
-        html5Entities.put("scnE", "\u2AB6");
-        html5Entities.put("scnsim", "\u22E9");
-        html5Entities.put("scpolint", "\u2A13");
-        html5Entities.put("scsim", "\u227F");
-        html5Entities.put("Scy", "\u0421");
-        html5Entities.put("scy", "\u0441");
-        html5Entities.put("sdotb", "\u22A1");
-        html5Entities.put("sdot", "\u22C5");
-        html5Entities.put("sdote", "\u2A66");
-        html5Entities.put("searhk", "\u2925");
-        html5Entities.put("searr", "\u2198");
-        html5Entities.put("seArr", "\u21D8");
-        html5Entities.put("searrow", "\u2198");
-        html5Entities.put("sect", "\u00A7");
-        html5Entities.put("semi", "\u003B");
-        html5Entities.put("seswar", "\u2929");
-        html5Entities.put("setminus", "\u2216");
-        html5Entities.put("setmn", "\u2216");
-        html5Entities.put("sext", "\u2736");
-        html5Entities.put("Sfr", "\uD835\uDD16");
-        html5Entities.put("sfr", "\uD835\uDD30");
-        html5Entities.put("sfrown", "\u2322");
-        html5Entities.put("sharp", "\u266F");
-        html5Entities.put("SHCHcy", "\u0429");
-        html5Entities.put("shchcy", "\u0449");
-        html5Entities.put("SHcy", "\u0428");
-        html5Entities.put("shcy", "\u0448");
-        html5Entities.put("ShortDownArrow", "\u2193");
-        html5Entities.put("ShortLeftArrow", "\u2190");
-        html5Entities.put("shortmid", "\u2223");
-        html5Entities.put("shortparallel", "\u2225");
-        html5Entities.put("ShortRightArrow", "\u2192");
-        html5Entities.put("ShortUpArrow", "\u2191");
-        html5Entities.put("shy", "\u00AD");
-        html5Entities.put("Sigma", "\u03A3");
-        html5Entities.put("sigma", "\u03C3");
-        html5Entities.put("sigmaf", "\u03C2");
-        html5Entities.put("sigmav", "\u03C2");
-        html5Entities.put("sim", "\u223C");
-        html5Entities.put("simdot", "\u2A6A");
-        html5Entities.put("sime", "\u2243");
-        html5Entities.put("simeq", "\u2243");
-        html5Entities.put("simg", "\u2A9E");
-        html5Entities.put("simgE", "\u2AA0");
-        html5Entities.put("siml", "\u2A9D");
-        html5Entities.put("simlE", "\u2A9F");
-        html5Entities.put("simne", "\u2246");
-        html5Entities.put("simplus", "\u2A24");
-        html5Entities.put("simrarr", "\u2972");
-        html5Entities.put("slarr", "\u2190");
-        html5Entities.put("SmallCircle", "\u2218");
-        html5Entities.put("smallsetminus", "\u2216");
-        html5Entities.put("smashp", "\u2A33");
-        html5Entities.put("smeparsl", "\u29E4");
-        html5Entities.put("smid", "\u2223");
-        html5Entities.put("smile", "\u2323");
-        html5Entities.put("smt", "\u2AAA");
-        html5Entities.put("smte", "\u2AAC");
-        html5Entities.put("smtes", "\u2AAC\uFE00");
-        html5Entities.put("SOFTcy", "\u042C");
-        html5Entities.put("softcy", "\u044C");
-        html5Entities.put("solbar", "\u233F");
-        html5Entities.put("solb", "\u29C4");
-        html5Entities.put("sol", "\u002F");
-        html5Entities.put("Sopf", "\uD835\uDD4A");
-        html5Entities.put("sopf", "\uD835\uDD64");
-        html5Entities.put("spades", "\u2660");
-        html5Entities.put("spadesuit", "\u2660");
-        html5Entities.put("spar", "\u2225");
-        html5Entities.put("sqcap", "\u2293");
-        html5Entities.put("sqcaps", "\u2293\uFE00");
-        html5Entities.put("sqcup", "\u2294");
-        html5Entities.put("sqcups", "\u2294\uFE00");
-        html5Entities.put("Sqrt", "\u221A");
-        html5Entities.put("sqsub", "\u228F");
-        html5Entities.put("sqsube", "\u2291");
-        html5Entities.put("sqsubset", "\u228F");
-        html5Entities.put("sqsubseteq", "\u2291");
-        html5Entities.put("sqsup", "\u2290");
-        html5Entities.put("sqsupe", "\u2292");
-        html5Entities.put("sqsupset", "\u2290");
-        html5Entities.put("sqsupseteq", "\u2292");
-        html5Entities.put("square", "\u25A1");
-        html5Entities.put("Square", "\u25A1");
-        html5Entities.put("SquareIntersection", "\u2293");
-        html5Entities.put("SquareSubset", "\u228F");
-        html5Entities.put("SquareSubsetEqual", "\u2291");
-        html5Entities.put("SquareSuperset", "\u2290");
-        html5Entities.put("SquareSupersetEqual", "\u2292");
-        html5Entities.put("SquareUnion", "\u2294");
-        html5Entities.put("squarf", "\u25AA");
-        html5Entities.put("squ", "\u25A1");
-        html5Entities.put("squf", "\u25AA");
-        html5Entities.put("srarr", "\u2192");
-        html5Entities.put("Sscr", "\uD835\uDCAE");
-        html5Entities.put("sscr", "\uD835\uDCC8");
-        html5Entities.put("ssetmn", "\u2216");
-        html5Entities.put("ssmile", "\u2323");
-        html5Entities.put("sstarf", "\u22C6");
-        html5Entities.put("Star", "\u22C6");
-        html5Entities.put("star", "\u2606");
-        html5Entities.put("starf", "\u2605");
-        html5Entities.put("straightepsilon", "\u03F5");
-        html5Entities.put("straightphi", "\u03D5");
-        html5Entities.put("strns", "\u00AF");
-        html5Entities.put("sub", "\u2282");
-        html5Entities.put("Sub", "\u22D0");
-        html5Entities.put("subdot", "\u2ABD");
-        html5Entities.put("subE", "\u2AC5");
-        html5Entities.put("sube", "\u2286");
-        html5Entities.put("subedot", "\u2AC3");
-        html5Entities.put("submult", "\u2AC1");
-        html5Entities.put("subnE", "\u2ACB");
-        html5Entities.put("subne", "\u228A");
-        html5Entities.put("subplus", "\u2ABF");
-        html5Entities.put("subrarr", "\u2979");
-        html5Entities.put("subset", "\u2282");
-        html5Entities.put("Subset", "\u22D0");
-        html5Entities.put("subseteq", "\u2286");
-        html5Entities.put("subseteqq", "\u2AC5");
-        html5Entities.put("SubsetEqual", "\u2286");
-        html5Entities.put("subsetneq", "\u228A");
-        html5Entities.put("subsetneqq", "\u2ACB");
-        html5Entities.put("subsim", "\u2AC7");
-        html5Entities.put("subsub", "\u2AD5");
-        html5Entities.put("subsup", "\u2AD3");
-        html5Entities.put("succapprox", "\u2AB8");
-        html5Entities.put("succ", "\u227B");
-        html5Entities.put("succcurlyeq", "\u227D");
-        html5Entities.put("Succeeds", "\u227B");
-        html5Entities.put("SucceedsEqual", "\u2AB0");
-        html5Entities.put("SucceedsSlantEqual", "\u227D");
-        html5Entities.put("SucceedsTilde", "\u227F");
-        html5Entities.put("succeq", "\u2AB0");
-        html5Entities.put("succnapprox", "\u2ABA");
-        html5Entities.put("succneqq", "\u2AB6");
-        html5Entities.put("succnsim", "\u22E9");
-        html5Entities.put("succsim", "\u227F");
-        html5Entities.put("SuchThat", "\u220B");
-        html5Entities.put("sum", "\u2211");
-        html5Entities.put("Sum", "\u2211");
-        html5Entities.put("sung", "\u266A");
-        html5Entities.put("sup1", "\u00B9");
-        html5Entities.put("sup2", "\u00B2");
-        html5Entities.put("sup3", "\u00B3");
-        html5Entities.put("sup", "\u2283");
-        html5Entities.put("Sup", "\u22D1");
-        html5Entities.put("supdot", "\u2ABE");
-        html5Entities.put("supdsub", "\u2AD8");
-        html5Entities.put("supE", "\u2AC6");
-        html5Entities.put("supe", "\u2287");
-        html5Entities.put("supedot", "\u2AC4");
-        html5Entities.put("Superset", "\u2283");
-        html5Entities.put("SupersetEqual", "\u2287");
-        html5Entities.put("suphsol", "\u27C9");
-        html5Entities.put("suphsub", "\u2AD7");
-        html5Entities.put("suplarr", "\u297B");
-        html5Entities.put("supmult", "\u2AC2");
-        html5Entities.put("supnE", "\u2ACC");
-        html5Entities.put("supne", "\u228B");
-        html5Entities.put("supplus", "\u2AC0");
-        html5Entities.put("supset", "\u2283");
-        html5Entities.put("Supset", "\u22D1");
-        html5Entities.put("supseteq", "\u2287");
-        html5Entities.put("supseteqq", "\u2AC6");
-        html5Entities.put("supsetneq", "\u228B");
-        html5Entities.put("supsetneqq", "\u2ACC");
-        html5Entities.put("supsim", "\u2AC8");
-        html5Entities.put("supsub", "\u2AD4");
-        html5Entities.put("supsup", "\u2AD6");
-        html5Entities.put("swarhk", "\u2926");
-        html5Entities.put("swarr", "\u2199");
-        html5Entities.put("swArr", "\u21D9");
-        html5Entities.put("swarrow", "\u2199");
-        html5Entities.put("swnwar", "\u292A");
-        html5Entities.put("szlig", "\u00DF");
-        html5Entities.put("Tab", "\u0009");
-        html5Entities.put("target", "\u2316");
-        html5Entities.put("Tau", "\u03A4");
-        html5Entities.put("tau", "\u03C4");
-        html5Entities.put("tbrk", "\u23B4");
-        html5Entities.put("Tcaron", "\u0164");
-        html5Entities.put("tcaron", "\u0165");
-        html5Entities.put("Tcedil", "\u0162");
-        html5Entities.put("tcedil", "\u0163");
-        html5Entities.put("Tcy", "\u0422");
-        html5Entities.put("tcy", "\u0442");
-        html5Entities.put("tdot", "\u20DB");
-        html5Entities.put("telrec", "\u2315");
-        html5Entities.put("Tfr", "\uD835\uDD17");
-        html5Entities.put("tfr", "\uD835\uDD31");
-        html5Entities.put("there4", "\u2234");
-        html5Entities.put("therefore", "\u2234");
-        html5Entities.put("Therefore", "\u2234");
-        html5Entities.put("Theta", "\u0398");
-        html5Entities.put("theta", "\u03B8");
-        html5Entities.put("thetasym", "\u03D1");
-        html5Entities.put("thetav", "\u03D1");
-        html5Entities.put("thickapprox", "\u2248");
-        html5Entities.put("thicksim", "\u223C");
-        html5Entities.put("ThickSpace", "\u205F\u200A");
-        html5Entities.put("ThinSpace", "\u2009");
-        html5Entities.put("thinsp", "\u2009");
-        html5Entities.put("thkap", "\u2248");
-        html5Entities.put("thksim", "\u223C");
-        html5Entities.put("THORN", "\u00DE");
-        html5Entities.put("thorn", "\u00FE");
-        html5Entities.put("tilde", "\u02DC");
-        html5Entities.put("Tilde", "\u223C");
-        html5Entities.put("TildeEqual", "\u2243");
-        html5Entities.put("TildeFullEqual", "\u2245");
-        html5Entities.put("TildeTilde", "\u2248");
-        html5Entities.put("timesbar", "\u2A31");
-        html5Entities.put("timesb", "\u22A0");
-        html5Entities.put("times", "\u00D7");
-        html5Entities.put("timesd", "\u2A30");
-        html5Entities.put("tint", "\u222D");
-        html5Entities.put("toea", "\u2928");
-        html5Entities.put("topbot", "\u2336");
-        html5Entities.put("topcir", "\u2AF1");
-        html5Entities.put("top", "\u22A4");
-        html5Entities.put("Topf", "\uD835\uDD4B");
-        html5Entities.put("topf", "\uD835\uDD65");
-        html5Entities.put("topfork", "\u2ADA");
-        html5Entities.put("tosa", "\u2929");
-        html5Entities.put("tprime", "\u2034");
-        html5Entities.put("trade", "\u2122");
-        html5Entities.put("TRADE", "\u2122");
-        html5Entities.put("triangle", "\u25B5");
-        html5Entities.put("triangledown", "\u25BF");
-        html5Entities.put("triangleleft", "\u25C3");
-        html5Entities.put("trianglelefteq", "\u22B4");
-        html5Entities.put("triangleq", "\u225C");
-        html5Entities.put("triangleright", "\u25B9");
-        html5Entities.put("trianglerighteq", "\u22B5");
-        html5Entities.put("tridot", "\u25EC");
-        html5Entities.put("trie", "\u225C");
-        html5Entities.put("triminus", "\u2A3A");
-        html5Entities.put("TripleDot", "\u20DB");
-        html5Entities.put("triplus", "\u2A39");
-        html5Entities.put("trisb", "\u29CD");
-        html5Entities.put("tritime", "\u2A3B");
-        html5Entities.put("trpezium", "\u23E2");
-        html5Entities.put("Tscr", "\uD835\uDCAF");
-        html5Entities.put("tscr", "\uD835\uDCC9");
-        html5Entities.put("TScy", "\u0426");
-        html5Entities.put("tscy", "\u0446");
-        html5Entities.put("TSHcy", "\u040B");
-        html5Entities.put("tshcy", "\u045B");
-        html5Entities.put("Tstrok", "\u0166");
-        html5Entities.put("tstrok", "\u0167");
-        html5Entities.put("twixt", "\u226C");
-        html5Entities.put("twoheadleftarrow", "\u219E");
-        html5Entities.put("twoheadrightarrow", "\u21A0");
-        html5Entities.put("Uacute", "\u00DA");
-        html5Entities.put("uacute", "\u00FA");
-        html5Entities.put("uarr", "\u2191");
-        html5Entities.put("Uarr", "\u219F");
-        html5Entities.put("uArr", "\u21D1");
-        html5Entities.put("Uarrocir", "\u2949");
-        html5Entities.put("Ubrcy", "\u040E");
-        html5Entities.put("ubrcy", "\u045E");
-        html5Entities.put("Ubreve", "\u016C");
-        html5Entities.put("ubreve", "\u016D");
-        html5Entities.put("Ucirc", "\u00DB");
-        html5Entities.put("ucirc", "\u00FB");
-        html5Entities.put("Ucy", "\u0423");
-        html5Entities.put("ucy", "\u0443");
-        html5Entities.put("udarr", "\u21C5");
-        html5Entities.put("Udblac", "\u0170");
-        html5Entities.put("udblac", "\u0171");
-        html5Entities.put("udhar", "\u296E");
-        html5Entities.put("ufisht", "\u297E");
-        html5Entities.put("Ufr", "\uD835\uDD18");
-        html5Entities.put("ufr", "\uD835\uDD32");
-        html5Entities.put("Ugrave", "\u00D9");
-        html5Entities.put("ugrave", "\u00F9");
-        html5Entities.put("uHar", "\u2963");
-        html5Entities.put("uharl", "\u21BF");
-        html5Entities.put("uharr", "\u21BE");
-        html5Entities.put("uhblk", "\u2580");
-        html5Entities.put("ulcorn", "\u231C");
-        html5Entities.put("ulcorner", "\u231C");
-        html5Entities.put("ulcrop", "\u230F");
-        html5Entities.put("ultri", "\u25F8");
-        html5Entities.put("Umacr", "\u016A");
-        html5Entities.put("umacr", "\u016B");
-        html5Entities.put("uml", "\u00A8");
-        html5Entities.put("UnderBar", "\u005F");
-        html5Entities.put("UnderBrace", "\u23DF");
-        html5Entities.put("UnderBracket", "\u23B5");
-        html5Entities.put("UnderParenthesis", "\u23DD");
-        html5Entities.put("Union", "\u22C3");
-        html5Entities.put("UnionPlus", "\u228E");
-        html5Entities.put("Uogon", "\u0172");
-        html5Entities.put("uogon", "\u0173");
-        html5Entities.put("Uopf", "\uD835\uDD4C");
-        html5Entities.put("uopf", "\uD835\uDD66");
-        html5Entities.put("UpArrowBar", "\u2912");
-        html5Entities.put("uparrow", "\u2191");
-        html5Entities.put("UpArrow", "\u2191");
-        html5Entities.put("Uparrow", "\u21D1");
-        html5Entities.put("UpArrowDownArrow", "\u21C5");
-        html5Entities.put("updownarrow", "\u2195");
-        html5Entities.put("UpDownArrow", "\u2195");
-        html5Entities.put("Updownarrow", "\u21D5");
-        html5Entities.put("UpEquilibrium", "\u296E");
-        html5Entities.put("upharpoonleft", "\u21BF");
-        html5Entities.put("upharpoonright", "\u21BE");
-        html5Entities.put("uplus", "\u228E");
-        html5Entities.put("UpperLeftArrow", "\u2196");
-        html5Entities.put("UpperRightArrow", "\u2197");
-        html5Entities.put("upsi", "\u03C5");
-        html5Entities.put("Upsi", "\u03D2");
-        html5Entities.put("upsih", "\u03D2");
-        html5Entities.put("Upsilon", "\u03A5");
-        html5Entities.put("upsilon", "\u03C5");
-        html5Entities.put("UpTeeArrow", "\u21A5");
-        html5Entities.put("UpTee", "\u22A5");
-        html5Entities.put("upuparrows", "\u21C8");
-        html5Entities.put("urcorn", "\u231D");
-        html5Entities.put("urcorner", "\u231D");
-        html5Entities.put("urcrop", "\u230E");
-        html5Entities.put("Uring", "\u016E");
-        html5Entities.put("uring", "\u016F");
-        html5Entities.put("urtri", "\u25F9");
-        html5Entities.put("Uscr", "\uD835\uDCB0");
-        html5Entities.put("uscr", "\uD835\uDCCA");
-        html5Entities.put("utdot", "\u22F0");
-        html5Entities.put("Utilde", "\u0168");
-        html5Entities.put("utilde", "\u0169");
-        html5Entities.put("utri", "\u25B5");
-        html5Entities.put("utrif", "\u25B4");
-        html5Entities.put("uuarr", "\u21C8");
-        html5Entities.put("Uuml", "\u00DC");
-        html5Entities.put("uuml", "\u00FC");
-        html5Entities.put("uwangle", "\u29A7");
-        html5Entities.put("vangrt", "\u299C");
-        html5Entities.put("varepsilon", "\u03F5");
-        html5Entities.put("varkappa", "\u03F0");
-        html5Entities.put("varnothing", "\u2205");
-        html5Entities.put("varphi", "\u03D5");
-        html5Entities.put("varpi", "\u03D6");
-        html5Entities.put("varpropto", "\u221D");
-        html5Entities.put("varr", "\u2195");
-        html5Entities.put("vArr", "\u21D5");
-        html5Entities.put("varrho", "\u03F1");
-        html5Entities.put("varsigma", "\u03C2");
-        html5Entities.put("varsubsetneq", "\u228A\uFE00");
-        html5Entities.put("varsubsetneqq", "\u2ACB\uFE00");
-        html5Entities.put("varsupsetneq", "\u228B\uFE00");
-        html5Entities.put("varsupsetneqq", "\u2ACC\uFE00");
-        html5Entities.put("vartheta", "\u03D1");
-        html5Entities.put("vartriangleleft", "\u22B2");
-        html5Entities.put("vartriangleright", "\u22B3");
-        html5Entities.put("vBar", "\u2AE8");
-        html5Entities.put("Vbar", "\u2AEB");
-        html5Entities.put("vBarv", "\u2AE9");
-        html5Entities.put("Vcy", "\u0412");
-        html5Entities.put("vcy", "\u0432");
-        html5Entities.put("vdash", "\u22A2");
-        html5Entities.put("vDash", "\u22A8");
-        html5Entities.put("Vdash", "\u22A9");
-        html5Entities.put("VDash", "\u22AB");
-        html5Entities.put("Vdashl", "\u2AE6");
-        html5Entities.put("veebar", "\u22BB");
-        html5Entities.put("vee", "\u2228");
-        html5Entities.put("Vee", "\u22C1");
-        html5Entities.put("veeeq", "\u225A");
-        html5Entities.put("vellip", "\u22EE");
-        html5Entities.put("verbar", "\u007C");
-        html5Entities.put("Verbar", "\u2016");
-        html5Entities.put("vert", "\u007C");
-        html5Entities.put("Vert", "\u2016");
-        html5Entities.put("VerticalBar", "\u2223");
-        html5Entities.put("VerticalLine", "\u007C");
-        html5Entities.put("VerticalSeparator", "\u2758");
-        html5Entities.put("VerticalTilde", "\u2240");
-        html5Entities.put("VeryThinSpace", "\u200A");
-        html5Entities.put("Vfr", "\uD835\uDD19");
-        html5Entities.put("vfr", "\uD835\uDD33");
-        html5Entities.put("vltri", "\u22B2");
-        html5Entities.put("vnsub", "\u2282\u20D2");
-        html5Entities.put("vnsup", "\u2283\u20D2");
-        html5Entities.put("Vopf", "\uD835\uDD4D");
-        html5Entities.put("vopf", "\uD835\uDD67");
-        html5Entities.put("vprop", "\u221D");
-        html5Entities.put("vrtri", "\u22B3");
-        html5Entities.put("Vscr", "\uD835\uDCB1");
-        html5Entities.put("vscr", "\uD835\uDCCB");
-        html5Entities.put("vsubnE", "\u2ACB\uFE00");
-        html5Entities.put("vsubne", "\u228A\uFE00");
-        html5Entities.put("vsupnE", "\u2ACC\uFE00");
-        html5Entities.put("vsupne", "\u228B\uFE00");
-        html5Entities.put("Vvdash", "\u22AA");
-        html5Entities.put("vzigzag", "\u299A");
-        html5Entities.put("Wcirc", "\u0174");
-        html5Entities.put("wcirc", "\u0175");
-        html5Entities.put("wedbar", "\u2A5F");
-        html5Entities.put("wedge", "\u2227");
-        html5Entities.put("Wedge", "\u22C0");
-        html5Entities.put("wedgeq", "\u2259");
-        html5Entities.put("weierp", "\u2118");
-        html5Entities.put("Wfr", "\uD835\uDD1A");
-        html5Entities.put("wfr", "\uD835\uDD34");
-        html5Entities.put("Wopf", "\uD835\uDD4E");
-        html5Entities.put("wopf", "\uD835\uDD68");
-        html5Entities.put("wp", "\u2118");
-        html5Entities.put("wr", "\u2240");
-        html5Entities.put("wreath", "\u2240");
-        html5Entities.put("Wscr", "\uD835\uDCB2");
-        html5Entities.put("wscr", "\uD835\uDCCC");
-        html5Entities.put("xcap", "\u22C2");
-        html5Entities.put("xcirc", "\u25EF");
-        html5Entities.put("xcup", "\u22C3");
-        html5Entities.put("xdtri", "\u25BD");
-        html5Entities.put("Xfr", "\uD835\uDD1B");
-        html5Entities.put("xfr", "\uD835\uDD35");
-        html5Entities.put("xharr", "\u27F7");
-        html5Entities.put("xhArr", "\u27FA");
-        html5Entities.put("Xi", "\u039E");
-        html5Entities.put("xi", "\u03BE");
-        html5Entities.put("xlarr", "\u27F5");
-        html5Entities.put("xlArr", "\u27F8");
-        html5Entities.put("xmap", "\u27FC");
-        html5Entities.put("xnis", "\u22FB");
-        html5Entities.put("xodot", "\u2A00");
-        html5Entities.put("Xopf", "\uD835\uDD4F");
-        html5Entities.put("xopf", "\uD835\uDD69");
-        html5Entities.put("xoplus", "\u2A01");
-        html5Entities.put("xotime", "\u2A02");
-        html5Entities.put("xrarr", "\u27F6");
-        html5Entities.put("xrArr", "\u27F9");
-        html5Entities.put("Xscr", "\uD835\uDCB3");
-        html5Entities.put("xscr", "\uD835\uDCCD");
-        html5Entities.put("xsqcup", "\u2A06");
-        html5Entities.put("xuplus", "\u2A04");
-        html5Entities.put("xutri", "\u25B3");
-        html5Entities.put("xvee", "\u22C1");
-        html5Entities.put("xwedge", "\u22C0");
-        html5Entities.put("Yacute", "\u00DD");
-        html5Entities.put("yacute", "\u00FD");
-        html5Entities.put("YAcy", "\u042F");
-        html5Entities.put("yacy", "\u044F");
-        html5Entities.put("Ycirc", "\u0176");
-        html5Entities.put("ycirc", "\u0177");
-        html5Entities.put("Ycy", "\u042B");
-        html5Entities.put("ycy", "\u044B");
-        html5Entities.put("yen", "\u00A5");
-        html5Entities.put("Yfr", "\uD835\uDD1C");
-        html5Entities.put("yfr", "\uD835\uDD36");
-        html5Entities.put("YIcy", "\u0407");
-        html5Entities.put("yicy", "\u0457");
-        html5Entities.put("Yopf", "\uD835\uDD50");
-        html5Entities.put("yopf", "\uD835\uDD6A");
-        html5Entities.put("Yscr", "\uD835\uDCB4");
-        html5Entities.put("yscr", "\uD835\uDCCE");
-        html5Entities.put("YUcy", "\u042E");
-        html5Entities.put("yucy", "\u044E");
-        html5Entities.put("yuml", "\u00FF");
-        html5Entities.put("Yuml", "\u0178");
-        html5Entities.put("Zacute", "\u0179");
-        html5Entities.put("zacute", "\u017A");
-        html5Entities.put("Zcaron", "\u017D");
-        html5Entities.put("zcaron", "\u017E");
-        html5Entities.put("Zcy", "\u0417");
-        html5Entities.put("zcy", "\u0437");
-        html5Entities.put("Zdot", "\u017B");
-        html5Entities.put("zdot", "\u017C");
-        html5Entities.put("zeetrf", "\u2128");
-        html5Entities.put("ZeroWidthSpace", "\u200B");
-        html5Entities.put("Zeta", "\u0396");
-        html5Entities.put("zeta", "\u03B6");
-        html5Entities.put("zfr", "\uD835\uDD37");
-        html5Entities.put("Zfr", "\u2128");
-        html5Entities.put("ZHcy", "\u0416");
-        html5Entities.put("zhcy", "\u0436");
-        html5Entities.put("zigrarr", "\u21DD");
-        html5Entities.put("zopf", "\uD835\uDD6B");
-        html5Entities.put("Zopf", "\u2124");
-        html5Entities.put("Zscr", "\uD835\uDCB5");
-        html5Entities.put("zscr", "\uD835\uDCCF");
-        html5Entities.put("zwj", "\u200D");
-        html5Entities.put("zwnj", "\u200C");
-    }
-
-    public static boolean isValid(String name) {
-        return html5Entities.containsKey(name);
-    }
-
-    public static boolean isValid(int code) {
-        // See https://www.w3.org/TR/html52/syntax.html#character-references
-        return Character.isDefined(code)
-                && (!Character.isISOControl(code) || Character.isSpaceChar(code))
-                && (code < 0xd800 || code > 0xdfff);
-    }
-
-    public static String getValue(String name) {
-        return html5Entities.get(name);
-    }
-}
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/Entity.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/Entity.java
new file mode 100644
index 00000000000..577bc674b59
--- /dev/null
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/Entity.java
@@ -0,0 +1,2206 @@
+/*
+ * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 com.sun.tools.javac.api;
+
+import java.util.HashMap;
+
+import com.sun.source.doctree.EntityTree;
+import com.sun.tools.javac.util.StringUtils;
+
+/**
+ * Table of entities defined in HTML 5.2.
+ *
+ * <p> Derived from the
+ * <a href="https://www.w3.org/TR/html52/syntax.html#named-character-references">Named character references</a>
+ * section of the HTML 5.2 specification.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own
+ * risk.  This code and its internal interfaces are subject to change
+ * or deletion without notice.</b></p>
+ */
+class Entity {
+
+    private static final HashMap<String,String> entities = new HashMap<>();
+
+    static {
+        put("Aacute", '\u00C1');
+        put("aacute", '\u00E1');
+        put("Abreve", '\u0102');
+        put("abreve", '\u0103');
+        put("ac", '\u223E');
+        put("acd", '\u223F');
+        put("acE", '\u223E', '\u0333');
+        put("Acirc", '\u00C2');
+        put("acirc", '\u00E2');
+        put("acute", '\u00B4');
+        put("Acy", '\u0410');
+        put("acy", '\u0430');
+        put("AElig", '\u00C6');
+        put("aelig", '\u00E6');
+        put("af", '\u2061');
+        put("Afr", '\uD835', '\uDD04');
+        put("afr", '\uD835', '\uDD1E');
+        put("Agrave", '\u00C0');
+        put("agrave", '\u00E0');
+        put("alefsym", '\u2135');
+        put("aleph", '\u2135');
+        put("Alpha", '\u0391');
+        put("alpha", '\u03B1');
+        put("Amacr", '\u0100');
+        put("amacr", '\u0101');
+        put("amalg", '\u2A3F');
+        put("amp", '\u0026');
+        put("AMP", '\u0026');
+        put("andand", '\u2A55');
+        put("And", '\u2A53');
+        put("and", '\u2227');
+        put("andd", '\u2A5C');
+        put("andslope", '\u2A58');
+        put("andv", '\u2A5A');
+        put("ang", '\u2220');
+        put("ange", '\u29A4');
+        put("angle", '\u2220');
+        put("angmsdaa", '\u29A8');
+        put("angmsdab", '\u29A9');
+        put("angmsdac", '\u29AA');
+        put("angmsdad", '\u29AB');
+        put("angmsdae", '\u29AC');
+        put("angmsdaf", '\u29AD');
+        put("angmsdag", '\u29AE');
+        put("angmsdah", '\u29AF');
+        put("angmsd", '\u2221');
+        put("angrt", '\u221F');
+        put("angrtvb", '\u22BE');
+        put("angrtvbd", '\u299D');
+        put("angsph", '\u2222');
+        put("angst", '\u00C5');
+        put("angzarr", '\u237C');
+        put("Aogon", '\u0104');
+        put("aogon", '\u0105');
+        put("Aopf", '\uD835', '\uDD38');
+        put("aopf", '\uD835', '\uDD52');
+        put("apacir", '\u2A6F');
+        put("ap", '\u2248');
+        put("apE", '\u2A70');
+        put("ape", '\u224A');
+        put("apid", '\u224B');
+        put("apos", '\'');
+        put("ApplyFunction", '\u2061');
+        put("approx", '\u2248');
+        put("approxeq", '\u224A');
+        put("Aring", '\u00C5');
+        put("aring", '\u00E5');
+        put("Ascr", '\uD835', '\uDC9C');
+        put("ascr", '\uD835', '\uDCB6');
+        put("Assign", '\u2254');
+        put("ast", '\u002A');
+        put("asymp", '\u2248');
+        put("asympeq", '\u224D');
+        put("Atilde", '\u00C3');
+        put("atilde", '\u00E3');
+        put("Auml", '\u00C4');
+        put("auml", '\u00E4');
+        put("awconint", '\u2233');
+        put("awint", '\u2A11');
+        put("backcong", '\u224C');
+        put("backepsilon", '\u03F6');
+        put("backprime", '\u2035');
+        put("backsim", '\u223D');
+        put("backsimeq", '\u22CD');
+        put("Backslash", '\u2216');
+        put("Barv", '\u2AE7');
+        put("barvee", '\u22BD');
+        put("barwed", '\u2305');
+        put("Barwed", '\u2306');
+        put("barwedge", '\u2305');
+        put("bbrk", '\u23B5');
+        put("bbrktbrk", '\u23B6');
+        put("bcong", '\u224C');
+        put("Bcy", '\u0411');
+        put("bcy", '\u0431');
+        put("bdquo", '\u201E');
+        put("becaus", '\u2235');
+        put("because", '\u2235');
+        put("Because", '\u2235');
+        put("bemptyv", '\u29B0');
+        put("bepsi", '\u03F6');
+        put("bernou", '\u212C');
+        put("Bernoullis", '\u212C');
+        put("Beta", '\u0392');
+        put("beta", '\u03B2');
+        put("beth", '\u2136');
+        put("between", '\u226C');
+        put("Bfr", '\uD835', '\uDD05');
+        put("bfr", '\uD835', '\uDD1F');
+        put("bigcap", '\u22C2');
+        put("bigcirc", '\u25EF');
+        put("bigcup", '\u22C3');
+        put("bigodot", '\u2A00');
+        put("bigoplus", '\u2A01');
+        put("bigotimes", '\u2A02');
+        put("bigsqcup", '\u2A06');
+        put("bigstar", '\u2605');
+        put("bigtriangledown", '\u25BD');
+        put("bigtriangleup", '\u25B3');
+        put("biguplus", '\u2A04');
+        put("bigvee", '\u22C1');
+        put("bigwedge", '\u22C0');
+        put("bkarow", '\u290D');
+        put("blacklozenge", '\u29EB');
+        put("blacksquare", '\u25AA');
+        put("blacktriangle", '\u25B4');
+        put("blacktriangledown", '\u25BE');
+        put("blacktriangleleft", '\u25C2');
+        put("blacktriangleright", '\u25B8');
+        put("blank", '\u2423');
+        put("blk12", '\u2592');
+        put("blk14", '\u2591');
+        put("blk34", '\u2593');
+        put("block", '\u2588');
+        put("bne", '\u003D', '\u20E5');
+        put("bnequiv", '\u2261', '\u20E5');
+        put("bNot", '\u2AED');
+        put("bnot", '\u2310');
+        put("Bopf", '\uD835', '\uDD39');
+        put("bopf", '\uD835', '\uDD53');
+        put("bot", '\u22A5');
+        put("bottom", '\u22A5');
+        put("bowtie", '\u22C8');
+        put("boxbox", '\u29C9');
+        put("boxdl", '\u2510');
+        put("boxdL", '\u2555');
+        put("boxDl", '\u2556');
+        put("boxDL", '\u2557');
+        put("boxdr", '\u250C');
+        put("boxdR", '\u2552');
+        put("boxDr", '\u2553');
+        put("boxDR", '\u2554');
+        put("boxh", '\u2500');
+        put("boxH", '\u2550');
+        put("boxhd", '\u252C');
+        put("boxHd", '\u2564');
+        put("boxhD", '\u2565');
+        put("boxHD", '\u2566');
+        put("boxhu", '\u2534');
+        put("boxHu", '\u2567');
+        put("boxhU", '\u2568');
+        put("boxHU", '\u2569');
+        put("boxminus", '\u229F');
+        put("boxplus", '\u229E');
+        put("boxtimes", '\u22A0');
+        put("boxul", '\u2518');
+        put("boxuL", '\u255B');
+        put("boxUl", '\u255C');
+        put("boxUL", '\u255D');
+        put("boxur", '\u2514');
+        put("boxuR", '\u2558');
+        put("boxUr", '\u2559');
+        put("boxUR", '\u255A');
+        put("boxv", '\u2502');
+        put("boxV", '\u2551');
+        put("boxvh", '\u253C');
+        put("boxvH", '\u256A');
+        put("boxVh", '\u256B');
+        put("boxVH", '\u256C');
+        put("boxvl", '\u2524');
+        put("boxvL", '\u2561');
+        put("boxVl", '\u2562');
+        put("boxVL", '\u2563');
+        put("boxvr", '\u251C');
+        put("boxvR", '\u255E');
+        put("boxVr", '\u255F');
+        put("boxVR", '\u2560');
+        put("bprime", '\u2035');
+        put("breve", '\u02D8');
+        put("Breve", '\u02D8');
+        put("brvbar", '\u00A6');
+        put("bscr", '\uD835', '\uDCB7');
+        put("Bscr", '\u212C');
+        put("bsemi", '\u204F');
+        put("bsim", '\u223D');
+        put("bsime", '\u22CD');
+        put("bsolb", '\u29C5');
+        put("bsol", '\\');
+        put("bsolhsub", '\u27C8');
+        put("bull", '\u2022');
+        put("bullet", '\u2022');
+        put("bump", '\u224E');
+        put("bumpE", '\u2AAE');
+        put("bumpe", '\u224F');
+        put("Bumpeq", '\u224E');
+        put("bumpeq", '\u224F');
+        put("Cacute", '\u0106');
+        put("cacute", '\u0107');
+        put("capand", '\u2A44');
+        put("capbrcup", '\u2A49');
+        put("capcap", '\u2A4B');
+        put("cap", '\u2229');
+        put("Cap", '\u22D2');
+        put("capcup", '\u2A47');
+        put("capdot", '\u2A40');
+        put("CapitalDifferentialD", '\u2145');
+        put("caps", '\u2229', '\uFE00');
+        put("caret", '\u2041');
+        put("caron", '\u02C7');
+        put("Cayleys", '\u212D');
+        put("ccaps", '\u2A4D');
+        put("Ccaron", '\u010C');
+        put("ccaron", '\u010D');
+        put("Ccedil", '\u00C7');
+        put("ccedil", '\u00E7');
+        put("Ccirc", '\u0108');
+        put("ccirc", '\u0109');
+        put("Cconint", '\u2230');
+        put("ccups", '\u2A4C');
+        put("ccupssm", '\u2A50');
+        put("Cdot", '\u010A');
+        put("cdot", '\u010B');
+        put("cedil", '\u00B8');
+        put("Cedilla", '\u00B8');
+        put("cemptyv", '\u29B2');
+        put("cent", '\u00A2');
+        put("centerdot", '\u00B7');
+        put("CenterDot", '\u00B7');
+        put("cfr", '\uD835', '\uDD20');
+        put("Cfr", '\u212D');
+        put("CHcy", '\u0427');
+        put("chcy", '\u0447');
+        put("check", '\u2713');
+        put("checkmark", '\u2713');
+        put("Chi", '\u03A7');
+        put("chi", '\u03C7');
+        put("circ", '\u02C6');
+        put("circeq", '\u2257');
+        put("circlearrowleft", '\u21BA');
+        put("circlearrowright", '\u21BB');
+        put("circledast", '\u229B');
+        put("circledcirc", '\u229A');
+        put("circleddash", '\u229D');
+        put("CircleDot", '\u2299');
+        put("circledR", '\u00AE');
+        put("circledS", '\u24C8');
+        put("CircleMinus", '\u2296');
+        put("CirclePlus", '\u2295');
+        put("CircleTimes", '\u2297');
+        put("cir", '\u25CB');
+        put("cirE", '\u29C3');
+        put("cire", '\u2257');
+        put("cirfnint", '\u2A10');
+        put("cirmid", '\u2AEF');
+        put("cirscir", '\u29C2');
+        put("ClockwiseContourIntegral", '\u2232');
+        put("CloseCurlyDoubleQuote", '\u201D');
+        put("CloseCurlyQuote", '\u2019');
+        put("clubs", '\u2663');
+        put("clubsuit", '\u2663');
+        put("colon", '\u003A');
+        put("Colon", '\u2237');
+        put("Colone", '\u2A74');
+        put("colone", '\u2254');
+        put("coloneq", '\u2254');
+        put("comma", '\u002C');
+        put("commat", '\u0040');
+        put("comp", '\u2201');
+        put("compfn", '\u2218');
+        put("complement", '\u2201');
+        put("complexes", '\u2102');
+        put("cong", '\u2245');
+        put("congdot", '\u2A6D');
+        put("Congruent", '\u2261');
+        put("conint", '\u222E');
+        put("Conint", '\u222F');
+        put("ContourIntegral", '\u222E');
+        put("copf", '\uD835', '\uDD54');
+        put("Copf", '\u2102');
+        put("coprod", '\u2210');
+        put("Coproduct", '\u2210');
+        put("copy", '\u00A9');
+        put("COPY", '\u00A9');
+        put("copysr", '\u2117');
+        put("CounterClockwiseContourIntegral", '\u2233');
+        put("crarr", '\u21B5');
+        put("cross", '\u2717');
+        put("Cross", '\u2A2F');
+        put("Cscr", '\uD835', '\uDC9E');
+        put("cscr", '\uD835', '\uDCB8');
+        put("csub", '\u2ACF');
+        put("csube", '\u2AD1');
+        put("csup", '\u2AD0');
+        put("csupe", '\u2AD2');
+        put("ctdot", '\u22EF');
+        put("cudarrl", '\u2938');
+        put("cudarrr", '\u2935');
+        put("cuepr", '\u22DE');
+        put("cuesc", '\u22DF');
+        put("cularr", '\u21B6');
+        put("cularrp", '\u293D');
+        put("cupbrcap", '\u2A48');
+        put("cupcap", '\u2A46');
+        put("CupCap", '\u224D');
+        put("cup", '\u222A');
+        put("Cup", '\u22D3');
+        put("cupcup", '\u2A4A');
+        put("cupdot", '\u228D');
+        put("cupor", '\u2A45');
+        put("cups", '\u222A', '\uFE00');
+        put("curarr", '\u21B7');
+        put("curarrm", '\u293C');
+        put("curlyeqprec", '\u22DE');
+        put("curlyeqsucc", '\u22DF');
+        put("curlyvee", '\u22CE');
+        put("curlywedge", '\u22CF');
+        put("curren", '\u00A4');
+        put("curvearrowleft", '\u21B6');
+        put("curvearrowright", '\u21B7');
+        put("cuvee", '\u22CE');
+        put("cuwed", '\u22CF');
+        put("cwconint", '\u2232');
+        put("cwint", '\u2231');
+        put("cylcty", '\u232D');
+        put("dagger", '\u2020');
+        put("Dagger", '\u2021');
+        put("daleth", '\u2138');
+        put("darr", '\u2193');
+        put("Darr", '\u21A1');
+        put("dArr", '\u21D3');
+        put("dash", '\u2010');
+        put("Dashv", '\u2AE4');
+        put("dashv", '\u22A3');
+        put("dbkarow", '\u290F');
+        put("dblac", '\u02DD');
+        put("Dcaron", '\u010E');
+        put("dcaron", '\u010F');
+        put("Dcy", '\u0414');
+        put("dcy", '\u0434');
+        put("ddagger", '\u2021');
+        put("ddarr", '\u21CA');
+        put("DD", '\u2145');
+        put("dd", '\u2146');
+        put("DDotrahd", '\u2911');
+        put("ddotseq", '\u2A77');
+        put("deg", '\u00B0');
+        put("Del", '\u2207');
+        put("Delta", '\u0394');
+        put("delta", '\u03B4');
+        put("demptyv", '\u29B1');
+        put("dfisht", '\u297F');
+        put("Dfr", '\uD835', '\uDD07');
+        put("dfr", '\uD835', '\uDD21');
+        put("dHar", '\u2965');
+        put("dharl", '\u21C3');
+        put("dharr", '\u21C2');
+        put("DiacriticalAcute", '\u00B4');
+        put("DiacriticalDot", '\u02D9');
+        put("DiacriticalDoubleAcute", '\u02DD');
+        put("DiacriticalGrave", '\u0060');
+        put("DiacriticalTilde", '\u02DC');
+        put("diam", '\u22C4');
+        put("diamond", '\u22C4');
+        put("Diamond", '\u22C4');
+        put("diamondsuit", '\u2666');
+        put("diams", '\u2666');
+        put("die", '\u00A8');
+        put("DifferentialD", '\u2146');
+        put("digamma", '\u03DD');
+        put("disin", '\u22F2');
+        put("div", '\u00F7');
+        put("divide", '\u00F7');
+        put("divideontimes", '\u22C7');
+        put("divonx", '\u22C7');
+        put("DJcy", '\u0402');
+        put("djcy", '\u0452');
+        put("dlcorn", '\u231E');
+        put("dlcrop", '\u230D');
+        put("dollar", '\u0024');
+        put("Dopf", '\uD835', '\uDD3B');
+        put("dopf", '\uD835', '\uDD55');
+        put("Dot", '\u00A8');
+        put("dot", '\u02D9');
+        put("DotDot", '\u20DC');
+        put("doteq", '\u2250');
+        put("doteqdot", '\u2251');
+        put("DotEqual", '\u2250');
+        put("dotminus", '\u2238');
+        put("dotplus", '\u2214');
+        put("dotsquare", '\u22A1');
+        put("doublebarwedge", '\u2306');
+        put("DoubleContourIntegral", '\u222F');
+        put("DoubleDot", '\u00A8');
+        put("DoubleDownArrow", '\u21D3');
+        put("DoubleLeftArrow", '\u21D0');
+        put("DoubleLeftRightArrow", '\u21D4');
+        put("DoubleLeftTee", '\u2AE4');
+        put("DoubleLongLeftArrow", '\u27F8');
+        put("DoubleLongLeftRightArrow", '\u27FA');
+        put("DoubleLongRightArrow", '\u27F9');
+        put("DoubleRightArrow", '\u21D2');
+        put("DoubleRightTee", '\u22A8');
+        put("DoubleUpArrow", '\u21D1');
+        put("DoubleUpDownArrow", '\u21D5');
+        put("DoubleVerticalBar", '\u2225');
+        put("DownArrowBar", '\u2913');
+        put("downarrow", '\u2193');
+        put("DownArrow", '\u2193');
+        put("Downarrow", '\u21D3');
+        put("DownArrowUpArrow", '\u21F5');
+        put("DownBreve", '\u0311');
+        put("downdownarrows", '\u21CA');
+        put("downharpoonleft", '\u21C3');
+        put("downharpoonright", '\u21C2');
+        put("DownLeftRightVector", '\u2950');
+        put("DownLeftTeeVector", '\u295E');
+        put("DownLeftVectorBar", '\u2956');
+        put("DownLeftVector", '\u21BD');
+        put("DownRightTeeVector", '\u295F');
+        put("DownRightVectorBar", '\u2957');
+        put("DownRightVector", '\u21C1');
+        put("DownTeeArrow", '\u21A7');
+        put("DownTee", '\u22A4');
+        put("drbkarow", '\u2910');
+        put("drcorn", '\u231F');
+        put("drcrop", '\u230C');
+        put("Dscr", '\uD835', '\uDC9F');
+        put("dscr", '\uD835', '\uDCB9');
+        put("DScy", '\u0405');
+        put("dscy", '\u0455');
+        put("dsol", '\u29F6');
+        put("Dstrok", '\u0110');
+        put("dstrok", '\u0111');
+        put("dtdot", '\u22F1');
+        put("dtri", '\u25BF');
+        put("dtrif", '\u25BE');
+        put("duarr", '\u21F5');
+        put("duhar", '\u296F');
+        put("dwangle", '\u29A6');
+        put("DZcy", '\u040F');
+        put("dzcy", '\u045F');
+        put("dzigrarr", '\u27FF');
+        put("Eacute", '\u00C9');
+        put("eacute", '\u00E9');
+        put("easter", '\u2A6E');
+        put("Ecaron", '\u011A');
+        put("ecaron", '\u011B');
+        put("Ecirc", '\u00CA');
+        put("ecirc", '\u00EA');
+        put("ecir", '\u2256');
+        put("ecolon", '\u2255');
+        put("Ecy", '\u042D');
+        put("ecy", '\u044D');
+        put("eDDot", '\u2A77');
+        put("Edot", '\u0116');
+        put("edot", '\u0117');
+        put("eDot", '\u2251');
+        put("ee", '\u2147');
+        put("efDot", '\u2252');
+        put("Efr", '\uD835', '\uDD08');
+        put("efr", '\uD835', '\uDD22');
+        put("eg", '\u2A9A');
+        put("Egrave", '\u00C8');
+        put("egrave", '\u00E8');
+        put("egs", '\u2A96');
+        put("egsdot", '\u2A98');
+        put("el", '\u2A99');
+        put("Element", '\u2208');
+        put("elinters", '\u23E7');
+        put("ell", '\u2113');
+        put("els", '\u2A95');
+        put("elsdot", '\u2A97');
+        put("Emacr", '\u0112');
+        put("emacr", '\u0113');
+        put("empty", '\u2205');
+        put("emptyset", '\u2205');
+        put("EmptySmallSquare", '\u25FB');
+        put("emptyv", '\u2205');
+        put("EmptyVerySmallSquare", '\u25AB');
+        put("emsp13", '\u2004');
+        put("emsp14", '\u2005');
+        put("emsp", '\u2003');
+        put("ENG", '\u014A');
+        put("eng", '\u014B');
+        put("ensp", '\u2002');
+        put("Eogon", '\u0118');
+        put("eogon", '\u0119');
+        put("Eopf", '\uD835', '\uDD3C');
+        put("eopf", '\uD835', '\uDD56');
+        put("epar", '\u22D5');
+        put("eparsl", '\u29E3');
+        put("eplus", '\u2A71');
+        put("epsi", '\u03B5');
+        put("Epsilon", '\u0395');
+        put("epsilon", '\u03B5');
+        put("epsiv", '\u03F5');
+        put("eqcirc", '\u2256');
+        put("eqcolon", '\u2255');
+        put("eqsim", '\u2242');
+        put("eqslantgtr", '\u2A96');
+        put("eqslantless", '\u2A95');
+        put("Equal", '\u2A75');
+        put("equals", '\u003D');
+        put("EqualTilde", '\u2242');
+        put("equest", '\u225F');
+        put("Equilibrium", '\u21CC');
+        put("equiv", '\u2261');
+        put("equivDD", '\u2A78');
+        put("eqvparsl", '\u29E5');
+        put("erarr", '\u2971');
+        put("erDot", '\u2253');
+        put("escr", '\u212F');
+        put("Escr", '\u2130');
+        put("esdot", '\u2250');
+        put("Esim", '\u2A73');
+        put("esim", '\u2242');
+        put("Eta", '\u0397');
+        put("eta", '\u03B7');
+        put("ETH", '\u00D0');
+        put("eth", '\u00F0');
+        put("Euml", '\u00CB');
+        put("euml", '\u00EB');
+        put("euro", '\u20AC');
+        put("excl", '\u0021');
+        put("exist", '\u2203');
+        put("Exists", '\u2203');
+        put("expectation", '\u2130');
+        put("exponentiale", '\u2147');
+        put("ExponentialE", '\u2147');
+        put("fallingdotseq", '\u2252');
+        put("Fcy", '\u0424');
+        put("fcy", '\u0444');
+        put("female", '\u2640');
+        put("ffilig", '\uFB03');
+        put("fflig", '\uFB00');
+        put("ffllig", '\uFB04');
+        put("Ffr", '\uD835', '\uDD09');
+        put("ffr", '\uD835', '\uDD23');
+        put("filig", '\uFB01');
+        put("FilledSmallSquare", '\u25FC');
+        put("FilledVerySmallSquare", '\u25AA');
+        put("fjlig", '\u0066', '\u006A');
+        put("flat", '\u266D');
+        put("fllig", '\uFB02');
+        put("fltns", '\u25B1');
+        put("fnof", '\u0192');
+        put("Fopf", '\uD835', '\uDD3D');
+        put("fopf", '\uD835', '\uDD57');
+        put("forall", '\u2200');
+        put("ForAll", '\u2200');
+        put("fork", '\u22D4');
+        put("forkv", '\u2AD9');
+        put("Fouriertrf", '\u2131');
+        put("fpartint", '\u2A0D');
+        put("frac12", '\u00BD');
+        put("frac13", '\u2153');
+        put("frac14", '\u00BC');
+        put("frac15", '\u2155');
+        put("frac16", '\u2159');
+        put("frac18", '\u215B');
+        put("frac23", '\u2154');
+        put("frac25", '\u2156');
+        put("frac34", '\u00BE');
+        put("frac35", '\u2157');
+        put("frac38", '\u215C');
+        put("frac45", '\u2158');
+        put("frac56", '\u215A');
+        put("frac58", '\u215D');
+        put("frac78", '\u215E');
+        put("frasl", '\u2044');
+        put("frown", '\u2322');
+        put("fscr", '\uD835', '\uDCBB');
+        put("Fscr", '\u2131');
+        put("gacute", '\u01F5');
+        put("Gamma", '\u0393');
+        put("gamma", '\u03B3');
+        put("Gammad", '\u03DC');
+        put("gammad", '\u03DD');
+        put("gap", '\u2A86');
+        put("Gbreve", '\u011E');
+        put("gbreve", '\u011F');
+        put("Gcedil", '\u0122');
+        put("Gcirc", '\u011C');
+        put("gcirc", '\u011D');
+        put("Gcy", '\u0413');
+        put("gcy", '\u0433');
+        put("Gdot", '\u0120');
+        put("gdot", '\u0121');
+        put("ge", '\u2265');
+        put("gE", '\u2267');
+        put("gEl", '\u2A8C');
+        put("gel", '\u22DB');
+        put("geq", '\u2265');
+        put("geqq", '\u2267');
+        put("geqslant", '\u2A7E');
+        put("gescc", '\u2AA9');
+        put("ges", '\u2A7E');
+        put("gesdot", '\u2A80');
+        put("gesdoto", '\u2A82');
+        put("gesdotol", '\u2A84');
+        put("gesl", '\u22DB', '\uFE00');
+        put("gesles", '\u2A94');
+        put("Gfr", '\uD835', '\uDD0A');
+        put("gfr", '\uD835', '\uDD24');
+        put("gg", '\u226B');
+        put("Gg", '\u22D9');
+        put("ggg", '\u22D9');
+        put("gimel", '\u2137');
+        put("GJcy", '\u0403');
+        put("gjcy", '\u0453');
+        put("gla", '\u2AA5');
+        put("gl", '\u2277');
+        put("glE", '\u2A92');
+        put("glj", '\u2AA4');
+        put("gnap", '\u2A8A');
+        put("gnapprox", '\u2A8A');
+        put("gne", '\u2A88');
+        put("gnE", '\u2269');
+        put("gneq", '\u2A88');
+        put("gneqq", '\u2269');
+        put("gnsim", '\u22E7');
+        put("Gopf", '\uD835', '\uDD3E');
+        put("gopf", '\uD835', '\uDD58');
+        put("grave", '\u0060');
+        put("GreaterEqual", '\u2265');
+        put("GreaterEqualLess", '\u22DB');
+        put("GreaterFullEqual", '\u2267');
+        put("GreaterGreater", '\u2AA2');
+        put("GreaterLess", '\u2277');
+        put("GreaterSlantEqual", '\u2A7E');
+        put("GreaterTilde", '\u2273');
+        put("Gscr", '\uD835', '\uDCA2');
+        put("gscr", '\u210A');
+        put("gsim", '\u2273');
+        put("gsime", '\u2A8E');
+        put("gsiml", '\u2A90');
+        put("gtcc", '\u2AA7');
+        put("gtcir", '\u2A7A');
+        put("gt", '\u003E');
+        put("GT", '\u003E');
+        put("Gt", '\u226B');
+        put("gtdot", '\u22D7');
+        put("gtlPar", '\u2995');
+        put("gtquest", '\u2A7C');
+        put("gtrapprox", '\u2A86');
+        put("gtrarr", '\u2978');
+        put("gtrdot", '\u22D7');
+        put("gtreqless", '\u22DB');
+        put("gtreqqless", '\u2A8C');
+        put("gtrless", '\u2277');
+        put("gtrsim", '\u2273');
+        put("gvertneqq", '\u2269', '\uFE00');
+        put("gvnE", '\u2269', '\uFE00');
+        put("Hacek", '\u02C7');
+        put("hairsp", '\u200A');
+        put("half", '\u00BD');
+        put("hamilt", '\u210B');
+        put("HARDcy", '\u042A');
+        put("hardcy", '\u044A');
+        put("harrcir", '\u2948');
+        put("harr", '\u2194');
+        put("hArr", '\u21D4');
+        put("harrw", '\u21AD');
+        put("Hat", '\u005E');
+        put("hbar", '\u210F');
+        put("Hcirc", '\u0124');
+        put("hcirc", '\u0125');
+        put("hearts", '\u2665');
+        put("heartsuit", '\u2665');
+        put("hellip", '\u2026');
+        put("hercon", '\u22B9');
+        put("hfr", '\uD835', '\uDD25');
+        put("Hfr", '\u210C');
+        put("HilbertSpace", '\u210B');
+        put("hksearow", '\u2925');
+        put("hkswarow", '\u2926');
+        put("hoarr", '\u21FF');
+        put("homtht", '\u223B');
+        put("hookleftarrow", '\u21A9');
+        put("hookrightarrow", '\u21AA');
+        put("hopf", '\uD835', '\uDD59');
+        put("Hopf", '\u210D');
+        put("horbar", '\u2015');
+        put("HorizontalLine", '\u2500');
+        put("hscr", '\uD835', '\uDCBD');
+        put("Hscr", '\u210B');
+        put("hslash", '\u210F');
+        put("Hstrok", '\u0126');
+        put("hstrok", '\u0127');
+        put("HumpDownHump", '\u224E');
+        put("HumpEqual", '\u224F');
+        put("hybull", '\u2043');
+        put("hyphen", '\u2010');
+        put("Iacute", '\u00CD');
+        put("iacute", '\u00ED');
+        put("ic", '\u2063');
+        put("Icirc", '\u00CE');
+        put("icirc", '\u00EE');
+        put("Icy", '\u0418');
+        put("icy", '\u0438');
+        put("Idot", '\u0130');
+        put("IEcy", '\u0415');
+        put("iecy", '\u0435');
+        put("iexcl", '\u00A1');
+        put("iff", '\u21D4');
+        put("ifr", '\uD835', '\uDD26');
+        put("Ifr", '\u2111');
+        put("Igrave", '\u00CC');
+        put("igrave", '\u00EC');
+        put("ii", '\u2148');
+        put("iiiint", '\u2A0C');
+        put("iiint", '\u222D');
+        put("iinfin", '\u29DC');
+        put("iiota", '\u2129');
+        put("IJlig", '\u0132');
+        put("ijlig", '\u0133');
+        put("Imacr", '\u012A');
+        put("imacr", '\u012B');
+        put("image", '\u2111');
+        put("ImaginaryI", '\u2148');
+        put("imagline", '\u2110');
+        put("imagpart", '\u2111');
+        put("imath", '\u0131');
+        put("Im", '\u2111');
+        put("imof", '\u22B7');
+        put("imped", '\u01B5');
+        put("Implies", '\u21D2');
+        put("incare", '\u2105');
+        put("in", '\u2208');
+        put("infin", '\u221E');
+        put("infintie", '\u29DD');
+        put("inodot", '\u0131');
+        put("intcal", '\u22BA');
+        put("int", '\u222B');
+        put("Int", '\u222C');
+        put("integers", '\u2124');
+        put("Integral", '\u222B');
+        put("intercal", '\u22BA');
+        put("Intersection", '\u22C2');
+        put("intlarhk", '\u2A17');
+        put("intprod", '\u2A3C');
+        put("InvisibleComma", '\u2063');
+        put("InvisibleTimes", '\u2062');
+        put("IOcy", '\u0401');
+        put("iocy", '\u0451');
+        put("Iogon", '\u012E');
+        put("iogon", '\u012F');
+        put("Iopf", '\uD835', '\uDD40');
+        put("iopf", '\uD835', '\uDD5A');
+        put("Iota", '\u0399');
+        put("iota", '\u03B9');
+        put("iprod", '\u2A3C');
+        put("iquest", '\u00BF');
+        put("iscr", '\uD835', '\uDCBE');
+        put("Iscr", '\u2110');
+        put("isin", '\u2208');
+        put("isindot", '\u22F5');
+        put("isinE", '\u22F9');
+        put("isins", '\u22F4');
+        put("isinsv", '\u22F3');
+        put("isinv", '\u2208');
+        put("it", '\u2062');
+        put("Itilde", '\u0128');
+        put("itilde", '\u0129');
+        put("Iukcy", '\u0406');
+        put("iukcy", '\u0456');
+        put("Iuml", '\u00CF');
+        put("iuml", '\u00EF');
+        put("Jcirc", '\u0134');
+        put("jcirc", '\u0135');
+        put("Jcy", '\u0419');
+        put("jcy", '\u0439');
+        put("Jfr", '\uD835', '\uDD0D');
+        put("jfr", '\uD835', '\uDD27');
+        put("jmath", '\u0237');
+        put("Jopf", '\uD835', '\uDD41');
+        put("jopf", '\uD835', '\uDD5B');
+        put("Jscr", '\uD835', '\uDCA5');
+        put("jscr", '\uD835', '\uDCBF');
+        put("Jsercy", '\u0408');
+        put("jsercy", '\u0458');
+        put("Jukcy", '\u0404');
+        put("jukcy", '\u0454');
+        put("Kappa", '\u039A');
+        put("kappa", '\u03BA');
+        put("kappav", '\u03F0');
+        put("Kcedil", '\u0136');
+        put("kcedil", '\u0137');
+        put("Kcy", '\u041A');
+        put("kcy", '\u043A');
+        put("Kfr", '\uD835', '\uDD0E');
+        put("kfr", '\uD835', '\uDD28');
+        put("kgreen", '\u0138');
+        put("KHcy", '\u0425');
+        put("khcy", '\u0445');
+        put("KJcy", '\u040C');
+        put("kjcy", '\u045C');
+        put("Kopf", '\uD835', '\uDD42');
+        put("kopf", '\uD835', '\uDD5C');
+        put("Kscr", '\uD835', '\uDCA6');
+        put("kscr", '\uD835', '\uDCC0');
+        put("lAarr", '\u21DA');
+        put("Lacute", '\u0139');
+        put("lacute", '\u013A');
+        put("laemptyv", '\u29B4');
+        put("lagran", '\u2112');
+        put("Lambda", '\u039B');
+        put("lambda", '\u03BB');
+        put("lang", '\u27E8');
+        put("Lang", '\u27EA');
+        put("langd", '\u2991');
+        put("langle", '\u27E8');
+        put("lap", '\u2A85');
+        put("Laplacetrf", '\u2112');
+        put("laquo", '\u00AB');
+        put("larrb", '\u21E4');
+        put("larrbfs", '\u291F');
+        put("larr", '\u2190');
+        put("Larr", '\u219E');
+        put("lArr", '\u21D0');
+        put("larrfs", '\u291D');
+        put("larrhk", '\u21A9');
+        put("larrlp", '\u21AB');
+        put("larrpl", '\u2939');
+        put("larrsim", '\u2973');
+        put("larrtl", '\u21A2');
+        put("latail", '\u2919');
+        put("lAtail", '\u291B');
+        put("lat", '\u2AAB');
+        put("late", '\u2AAD');
+        put("lates", '\u2AAD', '\uFE00');
+        put("lbarr", '\u290C');
+        put("lBarr", '\u290E');
+        put("lbbrk", '\u2772');
+        put("lbrace", '\u007B');
+        put("lbrack", '\u005B');
+        put("lbrke", '\u298B');
+        put("lbrksld", '\u298F');
+        put("lbrkslu", '\u298D');
+        put("Lcaron", '\u013D');
+        put("lcaron", '\u013E');
+        put("Lcedil", '\u013B');
+        put("lcedil", '\u013C');
+        put("lceil", '\u2308');
+        put("lcub", '\u007B');
+        put("Lcy", '\u041B');
+        put("lcy", '\u043B');
+        put("ldca", '\u2936');
+        put("ldquo", '\u201C');
+        put("ldquor", '\u201E');
+        put("ldrdhar", '\u2967');
+        put("ldrushar", '\u294B');
+        put("ldsh", '\u21B2');
+        put("le", '\u2264');
+        put("lE", '\u2266');
+        put("LeftAngleBracket", '\u27E8');
+        put("LeftArrowBar", '\u21E4');
+        put("leftarrow", '\u2190');
+        put("LeftArrow", '\u2190');
+        put("Leftarrow", '\u21D0');
+        put("LeftArrowRightArrow", '\u21C6');
+        put("leftarrowtail", '\u21A2');
+        put("LeftCeiling", '\u2308');
+        put("LeftDoubleBracket", '\u27E6');
+        put("LeftDownTeeVector", '\u2961');
+        put("LeftDownVectorBar", '\u2959');
+        put("LeftDownVector", '\u21C3');
+        put("LeftFloor", '\u230A');
+        put("leftharpoondown", '\u21BD');
+        put("leftharpoonup", '\u21BC');
+        put("leftleftarrows", '\u21C7');
+        put("leftrightarrow", '\u2194');
+        put("LeftRightArrow", '\u2194');
+        put("Leftrightarrow", '\u21D4');
+        put("leftrightarrows", '\u21C6');
+        put("leftrightharpoons", '\u21CB');
+        put("leftrightsquigarrow", '\u21AD');
+        put("LeftRightVector", '\u294E');
+        put("LeftTeeArrow", '\u21A4');
+        put("LeftTee", '\u22A3');
+        put("LeftTeeVector", '\u295A');
+        put("leftthreetimes", '\u22CB');
+        put("LeftTriangleBar", '\u29CF');
+        put("LeftTriangle", '\u22B2');
+        put("LeftTriangleEqual", '\u22B4');
+        put("LeftUpDownVector", '\u2951');
+        put("LeftUpTeeVector", '\u2960');
+        put("LeftUpVectorBar", '\u2958');
+        put("LeftUpVector", '\u21BF');
+        put("LeftVectorBar", '\u2952');
+        put("LeftVector", '\u21BC');
+        put("lEg", '\u2A8B');
+        put("leg", '\u22DA');
+        put("leq", '\u2264');
+        put("leqq", '\u2266');
+        put("leqslant", '\u2A7D');
+        put("lescc", '\u2AA8');
+        put("les", '\u2A7D');
+        put("lesdot", '\u2A7F');
+        put("lesdoto", '\u2A81');
+        put("lesdotor", '\u2A83');
+        put("lesg", '\u22DA', '\uFE00');
+        put("lesges", '\u2A93');
+        put("lessapprox", '\u2A85');
+        put("lessdot", '\u22D6');
+        put("lesseqgtr", '\u22DA');
+        put("lesseqqgtr", '\u2A8B');
+        put("LessEqualGreater", '\u22DA');
+        put("LessFullEqual", '\u2266');
+        put("LessGreater", '\u2276');
+        put("lessgtr", '\u2276');
+        put("LessLess", '\u2AA1');
+        put("lesssim", '\u2272');
+        put("LessSlantEqual", '\u2A7D');
+        put("LessTilde", '\u2272');
+        put("lfisht", '\u297C');
+        put("lfloor", '\u230A');
+        put("Lfr", '\uD835', '\uDD0F');
+        put("lfr", '\uD835', '\uDD29');
+        put("lg", '\u2276');
+        put("lgE", '\u2A91');
+        put("lHar", '\u2962');
+        put("lhard", '\u21BD');
+        put("lharu", '\u21BC');
+        put("lharul", '\u296A');
+        put("lhblk", '\u2584');
+        put("LJcy", '\u0409');
+        put("ljcy", '\u0459');
+        put("llarr", '\u21C7');
+        put("ll", '\u226A');
+        put("Ll", '\u22D8');
+        put("llcorner", '\u231E');
+        put("Lleftarrow", '\u21DA');
+        put("llhard", '\u296B');
+        put("lltri", '\u25FA');
+        put("Lmidot", '\u013F');
+        put("lmidot", '\u0140');
+        put("lmoustache", '\u23B0');
+        put("lmoust", '\u23B0');
+        put("lnap", '\u2A89');
+        put("lnapprox", '\u2A89');
+        put("lne", '\u2A87');
+        put("lnE", '\u2268');
+        put("lneq", '\u2A87');
+        put("lneqq", '\u2268');
+        put("lnsim", '\u22E6');
+        put("loang", '\u27EC');
+        put("loarr", '\u21FD');
+        put("lobrk", '\u27E6');
+        put("longleftarrow", '\u27F5');
+        put("LongLeftArrow", '\u27F5');
+        put("Longleftarrow", '\u27F8');
+        put("longleftrightarrow", '\u27F7');
+        put("LongLeftRightArrow", '\u27F7');
+        put("Longleftrightarrow", '\u27FA');
+        put("longmapsto", '\u27FC');
+        put("longrightarrow", '\u27F6');
+        put("LongRightArrow", '\u27F6');
+        put("Longrightarrow", '\u27F9');
+        put("looparrowleft", '\u21AB');
+        put("looparrowright", '\u21AC');
+        put("lopar", '\u2985');
+        put("Lopf", '\uD835', '\uDD43');
+        put("lopf", '\uD835', '\uDD5D');
+        put("loplus", '\u2A2D');
+        put("lotimes", '\u2A34');
+        put("lowast", '\u2217');
+        put("lowbar", '\u005F');
+        put("LowerLeftArrow", '\u2199');
+        put("LowerRightArrow", '\u2198');
+        put("loz", '\u25CA');
+        put("lozenge", '\u25CA');
+        put("lozf", '\u29EB');
+        put("lpar", '\u0028');
+        put("lparlt", '\u2993');
+        put("lrarr", '\u21C6');
+        put("lrcorner", '\u231F');
+        put("lrhar", '\u21CB');
+        put("lrhard", '\u296D');
+        put("lrm", '\u200E');
+        put("lrtri", '\u22BF');
+        put("lsaquo", '\u2039');
+        put("lscr", '\uD835', '\uDCC1');
+        put("Lscr", '\u2112');
+        put("lsh", '\u21B0');
+        put("Lsh", '\u21B0');
+        put("lsim", '\u2272');
+        put("lsime", '\u2A8D');
+        put("lsimg", '\u2A8F');
+        put("lsqb", '\u005B');
+        put("lsquo", '\u2018');
+        put("lsquor", '\u201A');
+        put("Lstrok", '\u0141');
+        put("lstrok", '\u0142');
+        put("ltcc", '\u2AA6');
+        put("ltcir", '\u2A79');
+        put("lt", '\u003C');
+        put("LT", '\u003C');
+        put("Lt", '\u226A');
+        put("ltdot", '\u22D6');
+        put("lthree", '\u22CB');
+        put("ltimes", '\u22C9');
+        put("ltlarr", '\u2976');
+        put("ltquest", '\u2A7B');
+        put("ltri", '\u25C3');
+        put("ltrie", '\u22B4');
+        put("ltrif", '\u25C2');
+        put("ltrPar", '\u2996');
+        put("lurdshar", '\u294A');
+        put("luruhar", '\u2966');
+        put("lvertneqq", '\u2268', '\uFE00');
+        put("lvnE", '\u2268', '\uFE00');
+        put("macr", '\u00AF');
+        put("male", '\u2642');
+        put("malt", '\u2720');
+        put("maltese", '\u2720');
+        put("Map", '\u2905');
+        put("map", '\u21A6');
+        put("mapsto", '\u21A6');
+        put("mapstodown", '\u21A7');
+        put("mapstoleft", '\u21A4');
+        put("mapstoup", '\u21A5');
+        put("marker", '\u25AE');
+        put("mcomma", '\u2A29');
+        put("Mcy", '\u041C');
+        put("mcy", '\u043C');
+        put("mdash", '\u2014');
+        put("mDDot", '\u223A');
+        put("measuredangle", '\u2221');
+        put("MediumSpace", '\u205F');
+        put("Mellintrf", '\u2133');
+        put("Mfr", '\uD835', '\uDD10');
+        put("mfr", '\uD835', '\uDD2A');
+        put("mho", '\u2127');
+        put("micro", '\u00B5');
+        put("midast", '\u002A');
+        put("midcir", '\u2AF0');
+        put("mid", '\u2223');
+        put("middot", '\u00B7');
+        put("minusb", '\u229F');
+        put("minus", '\u2212');
+        put("minusd", '\u2238');
+        put("minusdu", '\u2A2A');
+        put("MinusPlus", '\u2213');
+        put("mlcp", '\u2ADB');
+        put("mldr", '\u2026');
+        put("mnplus", '\u2213');
+        put("models", '\u22A7');
+        put("Mopf", '\uD835', '\uDD44');
+        put("mopf", '\uD835', '\uDD5E');
+        put("mp", '\u2213');
+        put("mscr", '\uD835', '\uDCC2');
+        put("Mscr", '\u2133');
+        put("mstpos", '\u223E');
+        put("Mu", '\u039C');
+        put("mu", '\u03BC');
+        put("multimap", '\u22B8');
+        put("mumap", '\u22B8');
+        put("nabla", '\u2207');
+        put("Nacute", '\u0143');
+        put("nacute", '\u0144');
+        put("nang", '\u2220', '\u20D2');
+        put("nap", '\u2249');
+        put("napE", '\u2A70', '\u0338');
+        put("napid", '\u224B', '\u0338');
+        put("napos", '\u0149');
+        put("napprox", '\u2249');
+        put("natural", '\u266E');
+        put("naturals", '\u2115');
+        put("natur", '\u266E');
+        put("nbsp", '\u00A0');
+        put("nbump", '\u224E', '\u0338');
+        put("nbumpe", '\u224F', '\u0338');
+        put("ncap", '\u2A43');
+        put("Ncaron", '\u0147');
+        put("ncaron", '\u0148');
+        put("Ncedil", '\u0145');
+        put("ncedil", '\u0146');
+        put("ncong", '\u2247');
+        put("ncongdot", '\u2A6D', '\u0338');
+        put("ncup", '\u2A42');
+        put("Ncy", '\u041D');
+        put("ncy", '\u043D');
+        put("ndash", '\u2013');
+        put("nearhk", '\u2924');
+        put("nearr", '\u2197');
+        put("neArr", '\u21D7');
+        put("nearrow", '\u2197');
+        put("ne", '\u2260');
+        put("nedot", '\u2250', '\u0338');
+        put("NegativeMediumSpace", '\u200B');
+        put("NegativeThickSpace", '\u200B');
+        put("NegativeThinSpace", '\u200B');
+        put("NegativeVeryThinSpace", '\u200B');
+        put("nequiv", '\u2262');
+        put("nesear", '\u2928');
+        put("nesim", '\u2242', '\u0338');
+        put("NestedGreaterGreater", '\u226B');
+        put("NestedLessLess", '\u226A');
+        put("NewLine", '\n');
+        put("nexist", '\u2204');
+        put("nexists", '\u2204');
+        put("Nfr", '\uD835', '\uDD11');
+        put("nfr", '\uD835', '\uDD2B');
+        put("ngE", '\u2267', '\u0338');
+        put("nge", '\u2271');
+        put("ngeq", '\u2271');
+        put("ngeqq", '\u2267', '\u0338');
+        put("ngeqslant", '\u2A7E', '\u0338');
+        put("nges", '\u2A7E', '\u0338');
+        put("nGg", '\u22D9', '\u0338');
+        put("ngsim", '\u2275');
+        put("nGt", '\u226B', '\u20D2');
+        put("ngt", '\u226F');
+        put("ngtr", '\u226F');
+        put("nGtv", '\u226B', '\u0338');
+        put("nharr", '\u21AE');
+        put("nhArr", '\u21CE');
+        put("nhpar", '\u2AF2');
+        put("ni", '\u220B');
+        put("nis", '\u22FC');
+        put("nisd", '\u22FA');
+        put("niv", '\u220B');
+        put("NJcy", '\u040A');
+        put("njcy", '\u045A');
+        put("nlarr", '\u219A');
+        put("nlArr", '\u21CD');
+        put("nldr", '\u2025');
+        put("nlE", '\u2266', '\u0338');
+        put("nle", '\u2270');
+        put("nleftarrow", '\u219A');
+        put("nLeftarrow", '\u21CD');
+        put("nleftrightarrow", '\u21AE');
+        put("nLeftrightarrow", '\u21CE');
+        put("nleq", '\u2270');
+        put("nleqq", '\u2266', '\u0338');
+        put("nleqslant", '\u2A7D', '\u0338');
+        put("nles", '\u2A7D', '\u0338');
+        put("nless", '\u226E');
+        put("nLl", '\u22D8', '\u0338');
+        put("nlsim", '\u2274');
+        put("nLt", '\u226A', '\u20D2');
+        put("nlt", '\u226E');
+        put("nltri", '\u22EA');
+        put("nltrie", '\u22EC');
+        put("nLtv", '\u226A', '\u0338');
+        put("nmid", '\u2224');
+        put("NoBreak", '\u2060');
+        put("NonBreakingSpace", '\u00A0');
+        put("nopf", '\uD835', '\uDD5F');
+        put("Nopf", '\u2115');
+        put("Not", '\u2AEC');
+        put("not", '\u00AC');
+        put("NotCongruent", '\u2262');
+        put("NotCupCap", '\u226D');
+        put("NotDoubleVerticalBar", '\u2226');
+        put("NotElement", '\u2209');
+        put("NotEqual", '\u2260');
+        put("NotEqualTilde", '\u2242', '\u0338');
+        put("NotExists", '\u2204');
+        put("NotGreater", '\u226F');
+        put("NotGreaterEqual", '\u2271');
+        put("NotGreaterFullEqual", '\u2267', '\u0338');
+        put("NotGreaterGreater", '\u226B', '\u0338');
+        put("NotGreaterLess", '\u2279');
+        put("NotGreaterSlantEqual", '\u2A7E', '\u0338');
+        put("NotGreaterTilde", '\u2275');
+        put("NotHumpDownHump", '\u224E', '\u0338');
+        put("NotHumpEqual", '\u224F', '\u0338');
+        put("notin", '\u2209');
+        put("notindot", '\u22F5', '\u0338');
+        put("notinE", '\u22F9', '\u0338');
+        put("notinva", '\u2209');
+        put("notinvb", '\u22F7');
+        put("notinvc", '\u22F6');
+        put("NotLeftTriangleBar", '\u29CF', '\u0338');
+        put("NotLeftTriangle", '\u22EA');
+        put("NotLeftTriangleEqual", '\u22EC');
+        put("NotLess", '\u226E');
+        put("NotLessEqual", '\u2270');
+        put("NotLessGreater", '\u2278');
+        put("NotLessLess", '\u226A', '\u0338');
+        put("NotLessSlantEqual", '\u2A7D', '\u0338');
+        put("NotLessTilde", '\u2274');
+        put("NotNestedGreaterGreater", '\u2AA2', '\u0338');
+        put("NotNestedLessLess", '\u2AA1', '\u0338');
+        put("notni", '\u220C');
+        put("notniva", '\u220C');
+        put("notnivb", '\u22FE');
+        put("notnivc", '\u22FD');
+        put("NotPrecedes", '\u2280');
+        put("NotPrecedesEqual", '\u2AAF', '\u0338');
+        put("NotPrecedesSlantEqual", '\u22E0');
+        put("NotReverseElement", '\u220C');
+        put("NotRightTriangleBar", '\u29D0', '\u0338');
+        put("NotRightTriangle", '\u22EB');
+        put("NotRightTriangleEqual", '\u22ED');
+        put("NotSquareSubset", '\u228F', '\u0338');
+        put("NotSquareSubsetEqual", '\u22E2');
+        put("NotSquareSuperset", '\u2290', '\u0338');
+        put("NotSquareSupersetEqual", '\u22E3');
+        put("NotSubset", '\u2282', '\u20D2');
+        put("NotSubsetEqual", '\u2288');
+        put("NotSucceeds", '\u2281');
+        put("NotSucceedsEqual", '\u2AB0', '\u0338');
+        put("NotSucceedsSlantEqual", '\u22E1');
+        put("NotSucceedsTilde", '\u227F', '\u0338');
+        put("NotSuperset", '\u2283', '\u20D2');
+        put("NotSupersetEqual", '\u2289');
+        put("NotTilde", '\u2241');
+        put("NotTildeEqual", '\u2244');
+        put("NotTildeFullEqual", '\u2247');
+        put("NotTildeTilde", '\u2249');
+        put("NotVerticalBar", '\u2224');
+        put("nparallel", '\u2226');
+        put("npar", '\u2226');
+        put("nparsl", '\u2AFD', '\u20E5');
+        put("npart", '\u2202', '\u0338');
+        put("npolint", '\u2A14');
+        put("npr", '\u2280');
+        put("nprcue", '\u22E0');
+        put("nprec", '\u2280');
+        put("npreceq", '\u2AAF', '\u0338');
+        put("npre", '\u2AAF', '\u0338');
+        put("nrarrc", '\u2933', '\u0338');
+        put("nrarr", '\u219B');
+        put("nrArr", '\u21CF');
+        put("nrarrw", '\u219D', '\u0338');
+        put("nrightarrow", '\u219B');
+        put("nRightarrow", '\u21CF');
+        put("nrtri", '\u22EB');
+        put("nrtrie", '\u22ED');
+        put("nsc", '\u2281');
+        put("nsccue", '\u22E1');
+        put("nsce", '\u2AB0', '\u0338');
+        put("Nscr", '\uD835', '\uDCA9');
+        put("nscr", '\uD835', '\uDCC3');
+        put("nshortmid", '\u2224');
+        put("nshortparallel", '\u2226');
+        put("nsim", '\u2241');
+        put("nsime", '\u2244');
+        put("nsimeq", '\u2244');
+        put("nsmid", '\u2224');
+        put("nspar", '\u2226');
+        put("nsqsube", '\u22E2');
+        put("nsqsupe", '\u22E3');
+        put("nsub", '\u2284');
+        put("nsubE", '\u2AC5', '\u0338');
+        put("nsube", '\u2288');
+        put("nsubset", '\u2282', '\u20D2');
+        put("nsubseteq", '\u2288');
+        put("nsubseteqq", '\u2AC5', '\u0338');
+        put("nsucc", '\u2281');
+        put("nsucceq", '\u2AB0', '\u0338');
+        put("nsup", '\u2285');
+        put("nsupE", '\u2AC6', '\u0338');
+        put("nsupe", '\u2289');
+        put("nsupset", '\u2283', '\u20D2');
+        put("nsupseteq", '\u2289');
+        put("nsupseteqq", '\u2AC6', '\u0338');
+        put("ntgl", '\u2279');
+        put("Ntilde", '\u00D1');
+        put("ntilde", '\u00F1');
+        put("ntlg", '\u2278');
+        put("ntriangleleft", '\u22EA');
+        put("ntrianglelefteq", '\u22EC');
+        put("ntriangleright", '\u22EB');
+        put("ntrianglerighteq", '\u22ED');
+        put("Nu", '\u039D');
+        put("nu", '\u03BD');
+        put("num", '\u0023');
+        put("numero", '\u2116');
+        put("numsp", '\u2007');
+        put("nvap", '\u224D', '\u20D2');
+        put("nvdash", '\u22AC');
+        put("nvDash", '\u22AD');
+        put("nVdash", '\u22AE');
+        put("nVDash", '\u22AF');
+        put("nvge", '\u2265', '\u20D2');
+        put("nvgt", '\u003E', '\u20D2');
+        put("nvHarr", '\u2904');
+        put("nvinfin", '\u29DE');
+        put("nvlArr", '\u2902');
+        put("nvle", '\u2264', '\u20D2');
+        put("nvlt", '\u003C', '\u20D2');
+        put("nvltrie", '\u22B4', '\u20D2');
+        put("nvrArr", '\u2903');
+        put("nvrtrie", '\u22B5', '\u20D2');
+        put("nvsim", '\u223C', '\u20D2');
+        put("nwarhk", '\u2923');
+        put("nwarr", '\u2196');
+        put("nwArr", '\u21D6');
+        put("nwarrow", '\u2196');
+        put("nwnear", '\u2927');
+        put("Oacute", '\u00D3');
+        put("oacute", '\u00F3');
+        put("oast", '\u229B');
+        put("Ocirc", '\u00D4');
+        put("ocirc", '\u00F4');
+        put("ocir", '\u229A');
+        put("Ocy", '\u041E');
+        put("ocy", '\u043E');
+        put("odash", '\u229D');
+        put("Odblac", '\u0150');
+        put("odblac", '\u0151');
+        put("odiv", '\u2A38');
+        put("odot", '\u2299');
+        put("odsold", '\u29BC');
+        put("OElig", '\u0152');
+        put("oelig", '\u0153');
+        put("ofcir", '\u29BF');
+        put("Ofr", '\uD835', '\uDD12');
+        put("ofr", '\uD835', '\uDD2C');
+        put("ogon", '\u02DB');
+        put("Ograve", '\u00D2');
+        put("ograve", '\u00F2');
+        put("ogt", '\u29C1');
+        put("ohbar", '\u29B5');
+        put("ohm", '\u03A9');
+        put("oint", '\u222E');
+        put("olarr", '\u21BA');
+        put("olcir", '\u29BE');
+        put("olcross", '\u29BB');
+        put("oline", '\u203E');
+        put("olt", '\u29C0');
+        put("Omacr", '\u014C');
+        put("omacr", '\u014D');
+        put("Omega", '\u03A9');
+        put("omega", '\u03C9');
+        put("Omicron", '\u039F');
+        put("omicron", '\u03BF');
+        put("omid", '\u29B6');
+        put("ominus", '\u2296');
+        put("Oopf", '\uD835', '\uDD46');
+        put("oopf", '\uD835', '\uDD60');
+        put("opar", '\u29B7');
+        put("OpenCurlyDoubleQuote", '\u201C');
+        put("OpenCurlyQuote", '\u2018');
+        put("operp", '\u29B9');
+        put("oplus", '\u2295');
+        put("orarr", '\u21BB');
+        put("Or", '\u2A54');
+        put("or", '\u2228');
+        put("ord", '\u2A5D');
+        put("order", '\u2134');
+        put("orderof", '\u2134');
+        put("ordf", '\u00AA');
+        put("ordm", '\u00BA');
+        put("origof", '\u22B6');
+        put("oror", '\u2A56');
+        put("orslope", '\u2A57');
+        put("orv", '\u2A5B');
+        put("oS", '\u24C8');
+        put("Oscr", '\uD835', '\uDCAA');
+        put("oscr", '\u2134');
+        put("Oslash", '\u00D8');
+        put("oslash", '\u00F8');
+        put("osol", '\u2298');
+        put("Otilde", '\u00D5');
+        put("otilde", '\u00F5');
+        put("otimesas", '\u2A36');
+        put("Otimes", '\u2A37');
+        put("otimes", '\u2297');
+        put("Ouml", '\u00D6');
+        put("ouml", '\u00F6');
+        put("ovbar", '\u233D');
+        put("OverBar", '\u203E');
+        put("OverBrace", '\u23DE');
+        put("OverBracket", '\u23B4');
+        put("OverParenthesis", '\u23DC');
+        put("para", '\u00B6');
+        put("parallel", '\u2225');
+        put("par", '\u2225');
+        put("parsim", '\u2AF3');
+        put("parsl", '\u2AFD');
+        put("part", '\u2202');
+        put("PartialD", '\u2202');
+        put("Pcy", '\u041F');
+        put("pcy", '\u043F');
+        put("percnt", '\u0025');
+        put("period", '\u002E');
+        put("permil", '\u2030');
+        put("perp", '\u22A5');
+        put("pertenk", '\u2031');
+        put("Pfr", '\uD835', '\uDD13');
+        put("pfr", '\uD835', '\uDD2D');
+        put("Phi", '\u03A6');
+        put("phi", '\u03C6');
+        put("phiv", '\u03D5');
+        put("phmmat", '\u2133');
+        put("phone", '\u260E');
+        put("Pi", '\u03A0');
+        put("pi", '\u03C0');
+        put("pitchfork", '\u22D4');
+        put("piv", '\u03D6');
+        put("planck", '\u210F');
+        put("planckh", '\u210E');
+        put("plankv", '\u210F');
+        put("plusacir", '\u2A23');
+        put("plusb", '\u229E');
+        put("pluscir", '\u2A22');
+        put("plus", '\u002B');
+        put("plusdo", '\u2214');
+        put("plusdu", '\u2A25');
+        put("pluse", '\u2A72');
+        put("PlusMinus", '\u00B1');
+        put("plusmn", '\u00B1');
+        put("plussim", '\u2A26');
+        put("plustwo", '\u2A27');
+        put("pm", '\u00B1');
+        put("Poincareplane", '\u210C');
+        put("pointint", '\u2A15');
+        put("popf", '\uD835', '\uDD61');
+        put("Popf", '\u2119');
+        put("pound", '\u00A3');
+        put("prap", '\u2AB7');
+        put("Pr", '\u2ABB');
+        put("pr", '\u227A');
+        put("prcue", '\u227C');
+        put("precapprox", '\u2AB7');
+        put("prec", '\u227A');
+        put("preccurlyeq", '\u227C');
+        put("Precedes", '\u227A');
+        put("PrecedesEqual", '\u2AAF');
+        put("PrecedesSlantEqual", '\u227C');
+        put("PrecedesTilde", '\u227E');
+        put("preceq", '\u2AAF');
+        put("precnapprox", '\u2AB9');
+        put("precneqq", '\u2AB5');
+        put("precnsim", '\u22E8');
+        put("pre", '\u2AAF');
+        put("prE", '\u2AB3');
+        put("precsim", '\u227E');
+        put("prime", '\u2032');
+        put("Prime", '\u2033');
+        put("primes", '\u2119');
+        put("prnap", '\u2AB9');
+        put("prnE", '\u2AB5');
+        put("prnsim", '\u22E8');
+        put("prod", '\u220F');
+        put("Product", '\u220F');
+        put("profalar", '\u232E');
+        put("profline", '\u2312');
+        put("profsurf", '\u2313');
+        put("prop", '\u221D');
+        put("Proportional", '\u221D');
+        put("Proportion", '\u2237');
+        put("propto", '\u221D');
+        put("prsim", '\u227E');
+        put("prurel", '\u22B0');
+        put("Pscr", '\uD835', '\uDCAB');
+        put("pscr", '\uD835', '\uDCC5');
+        put("Psi", '\u03A8');
+        put("psi", '\u03C8');
+        put("puncsp", '\u2008');
+        put("Qfr", '\uD835', '\uDD14');
+        put("qfr", '\uD835', '\uDD2E');
+        put("qint", '\u2A0C');
+        put("qopf", '\uD835', '\uDD62');
+        put("Qopf", '\u211A');
+        put("qprime", '\u2057');
+        put("Qscr", '\uD835', '\uDCAC');
+        put("qscr", '\uD835', '\uDCC6');
+        put("quaternions", '\u210D');
+        put("quatint", '\u2A16');
+        put("quest", '\u003F');
+        put("questeq", '\u225F');
+        put("quot", '\"');
+        put("QUOT", '\"');
+        put("rAarr", '\u21DB');
+        put("race", '\u223D', '\u0331');
+        put("Racute", '\u0154');
+        put("racute", '\u0155');
+        put("radic", '\u221A');
+        put("raemptyv", '\u29B3');
+        put("rang", '\u27E9');
+        put("Rang", '\u27EB');
+        put("rangd", '\u2992');
+        put("range", '\u29A5');
+        put("rangle", '\u27E9');
+        put("raquo", '\u00BB');
+        put("rarrap", '\u2975');
+        put("rarrb", '\u21E5');
+        put("rarrbfs", '\u2920');
+        put("rarrc", '\u2933');
+        put("rarr", '\u2192');
+        put("Rarr", '\u21A0');
+        put("rArr", '\u21D2');
+        put("rarrfs", '\u291E');
+        put("rarrhk", '\u21AA');
+        put("rarrlp", '\u21AC');
+        put("rarrpl", '\u2945');
+        put("rarrsim", '\u2974');
+        put("Rarrtl", '\u2916');
+        put("rarrtl", '\u21A3');
+        put("rarrw", '\u219D');
+        put("ratail", '\u291A');
+        put("rAtail", '\u291C');
+        put("ratio", '\u2236');
+        put("rationals", '\u211A');
+        put("rbarr", '\u290D');
+        put("rBarr", '\u290F');
+        put("RBarr", '\u2910');
+        put("rbbrk", '\u2773');
+        put("rbrace", '\u007D');
+        put("rbrack", '\u005D');
+        put("rbrke", '\u298C');
+        put("rbrksld", '\u298E');
+        put("rbrkslu", '\u2990');
+        put("Rcaron", '\u0158');
+        put("rcaron", '\u0159');
+        put("Rcedil", '\u0156');
+        put("rcedil", '\u0157');
+        put("rceil", '\u2309');
+        put("rcub", '\u007D');
+        put("Rcy", '\u0420');
+        put("rcy", '\u0440');
+        put("rdca", '\u2937');
+        put("rdldhar", '\u2969');
+        put("rdquo", '\u201D');
+        put("rdquor", '\u201D');
+        put("rdsh", '\u21B3');
+        put("real", '\u211C');
+        put("realine", '\u211B');
+        put("realpart", '\u211C');
+        put("reals", '\u211D');
+        put("Re", '\u211C');
+        put("rect", '\u25AD');
+        put("reg", '\u00AE');
+        put("REG", '\u00AE');
+        put("ReverseElement", '\u220B');
+        put("ReverseEquilibrium", '\u21CB');
+        put("ReverseUpEquilibrium", '\u296F');
+        put("rfisht", '\u297D');
+        put("rfloor", '\u230B');
+        put("rfr", '\uD835', '\uDD2F');
+        put("Rfr", '\u211C');
+        put("rHar", '\u2964');
+        put("rhard", '\u21C1');
+        put("rharu", '\u21C0');
+        put("rharul", '\u296C');
+        put("Rho", '\u03A1');
+        put("rho", '\u03C1');
+        put("rhov", '\u03F1');
+        put("RightAngleBracket", '\u27E9');
+        put("RightArrowBar", '\u21E5');
+        put("rightarrow", '\u2192');
+        put("RightArrow", '\u2192');
+        put("Rightarrow", '\u21D2');
+        put("RightArrowLeftArrow", '\u21C4');
+        put("rightarrowtail", '\u21A3');
+        put("RightCeiling", '\u2309');
+        put("RightDoubleBracket", '\u27E7');
+        put("RightDownTeeVector", '\u295D');
+        put("RightDownVectorBar", '\u2955');
+        put("RightDownVector", '\u21C2');
+        put("RightFloor", '\u230B');
+        put("rightharpoondown", '\u21C1');
+        put("rightharpoonup", '\u21C0');
+        put("rightleftarrows", '\u21C4');
+        put("rightleftharpoons", '\u21CC');
+        put("rightrightarrows", '\u21C9');
+        put("rightsquigarrow", '\u219D');
+        put("RightTeeArrow", '\u21A6');
+        put("RightTee", '\u22A2');
+        put("RightTeeVector", '\u295B');
+        put("rightthreetimes", '\u22CC');
+        put("RightTriangleBar", '\u29D0');
+        put("RightTriangle", '\u22B3');
+        put("RightTriangleEqual", '\u22B5');
+        put("RightUpDownVector", '\u294F');
+        put("RightUpTeeVector", '\u295C');
+        put("RightUpVectorBar", '\u2954');
+        put("RightUpVector", '\u21BE');
+        put("RightVectorBar", '\u2953');
+        put("RightVector", '\u21C0');
+        put("ring", '\u02DA');
+        put("risingdotseq", '\u2253');
+        put("rlarr", '\u21C4');
+        put("rlhar", '\u21CC');
+        put("rlm", '\u200F');
+        put("rmoustache", '\u23B1');
+        put("rmoust", '\u23B1');
+        put("rnmid", '\u2AEE');
+        put("roang", '\u27ED');
+        put("roarr", '\u21FE');
+        put("robrk", '\u27E7');
+        put("ropar", '\u2986');
+        put("ropf", '\uD835', '\uDD63');
+        put("Ropf", '\u211D');
+        put("roplus", '\u2A2E');
+        put("rotimes", '\u2A35');
+        put("RoundImplies", '\u2970');
+        put("rpar", '\u0029');
+        put("rpargt", '\u2994');
+        put("rppolint", '\u2A12');
+        put("rrarr", '\u21C9');
+        put("Rrightarrow", '\u21DB');
+        put("rsaquo", '\u203A');
+        put("rscr", '\uD835', '\uDCC7');
+        put("Rscr", '\u211B');
+        put("rsh", '\u21B1');
+        put("Rsh", '\u21B1');
+        put("rsqb", '\u005D');
+        put("rsquo", '\u2019');
+        put("rsquor", '\u2019');
+        put("rthree", '\u22CC');
+        put("rtimes", '\u22CA');
+        put("rtri", '\u25B9');
+        put("rtrie", '\u22B5');
+        put("rtrif", '\u25B8');
+        put("rtriltri", '\u29CE');
+        put("RuleDelayed", '\u29F4');
+        put("ruluhar", '\u2968');
+        put("rx", '\u211E');
+        put("Sacute", '\u015A');
+        put("sacute", '\u015B');
+        put("sbquo", '\u201A');
+        put("scap", '\u2AB8');
+        put("Scaron", '\u0160');
+        put("scaron", '\u0161');
+        put("Sc", '\u2ABC');
+        put("sc", '\u227B');
+        put("sccue", '\u227D');
+        put("sce", '\u2AB0');
+        put("scE", '\u2AB4');
+        put("Scedil", '\u015E');
+        put("scedil", '\u015F');
+        put("Scirc", '\u015C');
+        put("scirc", '\u015D');
+        put("scnap", '\u2ABA');
+        put("scnE", '\u2AB6');
+        put("scnsim", '\u22E9');
+        put("scpolint", '\u2A13');
+        put("scsim", '\u227F');
+        put("Scy", '\u0421');
+        put("scy", '\u0441');
+        put("sdotb", '\u22A1');
+        put("sdot", '\u22C5');
+        put("sdote", '\u2A66');
+        put("searhk", '\u2925');
+        put("searr", '\u2198');
+        put("seArr", '\u21D8');
+        put("searrow", '\u2198');
+        put("sect", '\u00A7');
+        put("semi", '\u003B');
+        put("seswar", '\u2929');
+        put("setminus", '\u2216');
+        put("setmn", '\u2216');
+        put("sext", '\u2736');
+        put("Sfr", '\uD835', '\uDD16');
+        put("sfr", '\uD835', '\uDD30');
+        put("sfrown", '\u2322');
+        put("sharp", '\u266F');
+        put("SHCHcy", '\u0429');
+        put("shchcy", '\u0449');
+        put("SHcy", '\u0428');
+        put("shcy", '\u0448');
+        put("ShortDownArrow", '\u2193');
+        put("ShortLeftArrow", '\u2190');
+        put("shortmid", '\u2223');
+        put("shortparallel", '\u2225');
+        put("ShortRightArrow", '\u2192');
+        put("ShortUpArrow", '\u2191');
+        put("shy", '\u00AD');
+        put("Sigma", '\u03A3');
+        put("sigma", '\u03C3');
+        put("sigmaf", '\u03C2');
+        put("sigmav", '\u03C2');
+        put("sim", '\u223C');
+        put("simdot", '\u2A6A');
+        put("sime", '\u2243');
+        put("simeq", '\u2243');
+        put("simg", '\u2A9E');
+        put("simgE", '\u2AA0');
+        put("siml", '\u2A9D');
+        put("simlE", '\u2A9F');
+        put("simne", '\u2246');
+        put("simplus", '\u2A24');
+        put("simrarr", '\u2972');
+        put("slarr", '\u2190');
+        put("SmallCircle", '\u2218');
+        put("smallsetminus", '\u2216');
+        put("smashp", '\u2A33');
+        put("smeparsl", '\u29E4');
+        put("smid", '\u2223');
+        put("smile", '\u2323');
+        put("smt", '\u2AAA');
+        put("smte", '\u2AAC');
+        put("smtes", '\u2AAC', '\uFE00');
+        put("SOFTcy", '\u042C');
+        put("softcy", '\u044C');
+        put("solbar", '\u233F');
+        put("solb", '\u29C4');
+        put("sol", '\u002F');
+        put("Sopf", '\uD835', '\uDD4A');
+        put("sopf", '\uD835', '\uDD64');
+        put("spades", '\u2660');
+        put("spadesuit", '\u2660');
+        put("spar", '\u2225');
+        put("sqcap", '\u2293');
+        put("sqcaps", '\u2293', '\uFE00');
+        put("sqcup", '\u2294');
+        put("sqcups", '\u2294', '\uFE00');
+        put("Sqrt", '\u221A');
+        put("sqsub", '\u228F');
+        put("sqsube", '\u2291');
+        put("sqsubset", '\u228F');
+        put("sqsubseteq", '\u2291');
+        put("sqsup", '\u2290');
+        put("sqsupe", '\u2292');
+        put("sqsupset", '\u2290');
+        put("sqsupseteq", '\u2292');
+        put("square", '\u25A1');
+        put("Square", '\u25A1');
+        put("SquareIntersection", '\u2293');
+        put("SquareSubset", '\u228F');
+        put("SquareSubsetEqual", '\u2291');
+        put("SquareSuperset", '\u2290');
+        put("SquareSupersetEqual", '\u2292');
+        put("SquareUnion", '\u2294');
+        put("squarf", '\u25AA');
+        put("squ", '\u25A1');
+        put("squf", '\u25AA');
+        put("srarr", '\u2192');
+        put("Sscr", '\uD835', '\uDCAE');
+        put("sscr", '\uD835', '\uDCC8');
+        put("ssetmn", '\u2216');
+        put("ssmile", '\u2323');
+        put("sstarf", '\u22C6');
+        put("Star", '\u22C6');
+        put("star", '\u2606');
+        put("starf", '\u2605');
+        put("straightepsilon", '\u03F5');
+        put("straightphi", '\u03D5');
+        put("strns", '\u00AF');
+        put("sub", '\u2282');
+        put("Sub", '\u22D0');
+        put("subdot", '\u2ABD');
+        put("subE", '\u2AC5');
+        put("sube", '\u2286');
+        put("subedot", '\u2AC3');
+        put("submult", '\u2AC1');
+        put("subnE", '\u2ACB');
+        put("subne", '\u228A');
+        put("subplus", '\u2ABF');
+        put("subrarr", '\u2979');
+        put("subset", '\u2282');
+        put("Subset", '\u22D0');
+        put("subseteq", '\u2286');
+        put("subseteqq", '\u2AC5');
+        put("SubsetEqual", '\u2286');
+        put("subsetneq", '\u228A');
+        put("subsetneqq", '\u2ACB');
+        put("subsim", '\u2AC7');
+        put("subsub", '\u2AD5');
+        put("subsup", '\u2AD3');
+        put("succapprox", '\u2AB8');
+        put("succ", '\u227B');
+        put("succcurlyeq", '\u227D');
+        put("Succeeds", '\u227B');
+        put("SucceedsEqual", '\u2AB0');
+        put("SucceedsSlantEqual", '\u227D');
+        put("SucceedsTilde", '\u227F');
+        put("succeq", '\u2AB0');
+        put("succnapprox", '\u2ABA');
+        put("succneqq", '\u2AB6');
+        put("succnsim", '\u22E9');
+        put("succsim", '\u227F');
+        put("SuchThat", '\u220B');
+        put("sum", '\u2211');
+        put("Sum", '\u2211');
+        put("sung", '\u266A');
+        put("sup1", '\u00B9');
+        put("sup2", '\u00B2');
+        put("sup3", '\u00B3');
+        put("sup", '\u2283');
+        put("Sup", '\u22D1');
+        put("supdot", '\u2ABE');
+        put("supdsub", '\u2AD8');
+        put("supE", '\u2AC6');
+        put("supe", '\u2287');
+        put("supedot", '\u2AC4');
+        put("Superset", '\u2283');
+        put("SupersetEqual", '\u2287');
+        put("suphsol", '\u27C9');
+        put("suphsub", '\u2AD7');
+        put("suplarr", '\u297B');
+        put("supmult", '\u2AC2');
+        put("supnE", '\u2ACC');
+        put("supne", '\u228B');
+        put("supplus", '\u2AC0');
+        put("supset", '\u2283');
+        put("Supset", '\u22D1');
+        put("supseteq", '\u2287');
+        put("supseteqq", '\u2AC6');
+        put("supsetneq", '\u228B');
+        put("supsetneqq", '\u2ACC');
+        put("supsim", '\u2AC8');
+        put("supsub", '\u2AD4');
+        put("supsup", '\u2AD6');
+        put("swarhk", '\u2926');
+        put("swarr", '\u2199');
+        put("swArr", '\u21D9');
+        put("swarrow", '\u2199');
+        put("swnwar", '\u292A');
+        put("szlig", '\u00DF');
+        put("Tab", '\u0009');
+        put("target", '\u2316');
+        put("Tau", '\u03A4');
+        put("tau", '\u03C4');
+        put("tbrk", '\u23B4');
+        put("Tcaron", '\u0164');
+        put("tcaron", '\u0165');
+        put("Tcedil", '\u0162');
+        put("tcedil", '\u0163');
+        put("Tcy", '\u0422');
+        put("tcy", '\u0442');
+        put("tdot", '\u20DB');
+        put("telrec", '\u2315');
+        put("Tfr", '\uD835', '\uDD17');
+        put("tfr", '\uD835', '\uDD31');
+        put("there4", '\u2234');
+        put("therefore", '\u2234');
+        put("Therefore", '\u2234');
+        put("Theta", '\u0398');
+        put("theta", '\u03B8');
+        put("thetasym", '\u03D1');
+        put("thetav", '\u03D1');
+        put("thickapprox", '\u2248');
+        put("thicksim", '\u223C');
+        put("ThickSpace", '\u205F', '\u200A');
+        put("ThinSpace", '\u2009');
+        put("thinsp", '\u2009');
+        put("thkap", '\u2248');
+        put("thksim", '\u223C');
+        put("THORN", '\u00DE');
+        put("thorn", '\u00FE');
+        put("tilde", '\u02DC');
+        put("Tilde", '\u223C');
+        put("TildeEqual", '\u2243');
+        put("TildeFullEqual", '\u2245');
+        put("TildeTilde", '\u2248');
+        put("timesbar", '\u2A31');
+        put("timesb", '\u22A0');
+        put("times", '\u00D7');
+        put("timesd", '\u2A30');
+        put("tint", '\u222D');
+        put("toea", '\u2928');
+        put("topbot", '\u2336');
+        put("topcir", '\u2AF1');
+        put("top", '\u22A4');
+        put("Topf", '\uD835', '\uDD4B');
+        put("topf", '\uD835', '\uDD65');
+        put("topfork", '\u2ADA');
+        put("tosa", '\u2929');
+        put("tprime", '\u2034');
+        put("trade", '\u2122');
+        put("TRADE", '\u2122');
+        put("triangle", '\u25B5');
+        put("triangledown", '\u25BF');
+        put("triangleleft", '\u25C3');
+        put("trianglelefteq", '\u22B4');
+        put("triangleq", '\u225C');
+        put("triangleright", '\u25B9');
+        put("trianglerighteq", '\u22B5');
+        put("tridot", '\u25EC');
+        put("trie", '\u225C');
+        put("triminus", '\u2A3A');
+        put("TripleDot", '\u20DB');
+        put("triplus", '\u2A39');
+        put("trisb", '\u29CD');
+        put("tritime", '\u2A3B');
+        put("trpezium", '\u23E2');
+        put("Tscr", '\uD835', '\uDCAF');
+        put("tscr", '\uD835', '\uDCC9');
+        put("TScy", '\u0426');
+        put("tscy", '\u0446');
+        put("TSHcy", '\u040B');
+        put("tshcy", '\u045B');
+        put("Tstrok", '\u0166');
+        put("tstrok", '\u0167');
+        put("twixt", '\u226C');
+        put("twoheadleftarrow", '\u219E');
+        put("twoheadrightarrow", '\u21A0');
+        put("Uacute", '\u00DA');
+        put("uacute", '\u00FA');
+        put("uarr", '\u2191');
+        put("Uarr", '\u219F');
+        put("uArr", '\u21D1');
+        put("Uarrocir", '\u2949');
+        put("Ubrcy", '\u040E');
+        put("ubrcy", '\u045E');
+        put("Ubreve", '\u016C');
+        put("ubreve", '\u016D');
+        put("Ucirc", '\u00DB');
+        put("ucirc", '\u00FB');
+        put("Ucy", '\u0423');
+        put("ucy", '\u0443');
+        put("udarr", '\u21C5');
+        put("Udblac", '\u0170');
+        put("udblac", '\u0171');
+        put("udhar", '\u296E');
+        put("ufisht", '\u297E');
+        put("Ufr", '\uD835', '\uDD18');
+        put("ufr", '\uD835', '\uDD32');
+        put("Ugrave", '\u00D9');
+        put("ugrave", '\u00F9');
+        put("uHar", '\u2963');
+        put("uharl", '\u21BF');
+        put("uharr", '\u21BE');
+        put("uhblk", '\u2580');
+        put("ulcorn", '\u231C');
+        put("ulcorner", '\u231C');
+        put("ulcrop", '\u230F');
+        put("ultri", '\u25F8');
+        put("Umacr", '\u016A');
+        put("umacr", '\u016B');
+        put("uml", '\u00A8');
+        put("UnderBar", '\u005F');
+        put("UnderBrace", '\u23DF');
+        put("UnderBracket", '\u23B5');
+        put("UnderParenthesis", '\u23DD');
+        put("Union", '\u22C3');
+        put("UnionPlus", '\u228E');
+        put("Uogon", '\u0172');
+        put("uogon", '\u0173');
+        put("Uopf", '\uD835', '\uDD4C');
+        put("uopf", '\uD835', '\uDD66');
+        put("UpArrowBar", '\u2912');
+        put("uparrow", '\u2191');
+        put("UpArrow", '\u2191');
+        put("Uparrow", '\u21D1');
+        put("UpArrowDownArrow", '\u21C5');
+        put("updownarrow", '\u2195');
+        put("UpDownArrow", '\u2195');
+        put("Updownarrow", '\u21D5');
+        put("UpEquilibrium", '\u296E');
+        put("upharpoonleft", '\u21BF');
+        put("upharpoonright", '\u21BE');
+        put("uplus", '\u228E');
+        put("UpperLeftArrow", '\u2196');
+        put("UpperRightArrow", '\u2197');
+        put("upsi", '\u03C5');
+        put("Upsi", '\u03D2');
+        put("upsih", '\u03D2');
+        put("Upsilon", '\u03A5');
+        put("upsilon", '\u03C5');
+        put("UpTeeArrow", '\u21A5');
+        put("UpTee", '\u22A5');
+        put("upuparrows", '\u21C8');
+        put("urcorn", '\u231D');
+        put("urcorner", '\u231D');
+        put("urcrop", '\u230E');
+        put("Uring", '\u016E');
+        put("uring", '\u016F');
+        put("urtri", '\u25F9');
+        put("Uscr", '\uD835', '\uDCB0');
+        put("uscr", '\uD835', '\uDCCA');
+        put("utdot", '\u22F0');
+        put("Utilde", '\u0168');
+        put("utilde", '\u0169');
+        put("utri", '\u25B5');
+        put("utrif", '\u25B4');
+        put("uuarr", '\u21C8');
+        put("Uuml", '\u00DC');
+        put("uuml", '\u00FC');
+        put("uwangle", '\u29A7');
+        put("vangrt", '\u299C');
+        put("varepsilon", '\u03F5');
+        put("varkappa", '\u03F0');
+        put("varnothing", '\u2205');
+        put("varphi", '\u03D5');
+        put("varpi", '\u03D6');
+        put("varpropto", '\u221D');
+        put("varr", '\u2195');
+        put("vArr", '\u21D5');
+        put("varrho", '\u03F1');
+        put("varsigma", '\u03C2');
+        put("varsubsetneq", '\u228A', '\uFE00');
+        put("varsubsetneqq", '\u2ACB', '\uFE00');
+        put("varsupsetneq", '\u228B', '\uFE00');
+        put("varsupsetneqq", '\u2ACC', '\uFE00');
+        put("vartheta", '\u03D1');
+        put("vartriangleleft", '\u22B2');
+        put("vartriangleright", '\u22B3');
+        put("vBar", '\u2AE8');
+        put("Vbar", '\u2AEB');
+        put("vBarv", '\u2AE9');
+        put("Vcy", '\u0412');
+        put("vcy", '\u0432');
+        put("vdash", '\u22A2');
+        put("vDash", '\u22A8');
+        put("Vdash", '\u22A9');
+        put("VDash", '\u22AB');
+        put("Vdashl", '\u2AE6');
+        put("veebar", '\u22BB');
+        put("vee", '\u2228');
+        put("Vee", '\u22C1');
+        put("veeeq", '\u225A');
+        put("vellip", '\u22EE');
+        put("verbar", '\u007C');
+        put("Verbar", '\u2016');
+        put("vert", '\u007C');
+        put("Vert", '\u2016');
+        put("VerticalBar", '\u2223');
+        put("VerticalLine", '\u007C');
+        put("VerticalSeparator", '\u2758');
+        put("VerticalTilde", '\u2240');
+        put("VeryThinSpace", '\u200A');
+        put("Vfr", '\uD835', '\uDD19');
+        put("vfr", '\uD835', '\uDD33');
+        put("vltri", '\u22B2');
+        put("vnsub", '\u2282', '\u20D2');
+        put("vnsup", '\u2283', '\u20D2');
+        put("Vopf", '\uD835', '\uDD4D');
+        put("vopf", '\uD835', '\uDD67');
+        put("vprop", '\u221D');
+        put("vrtri", '\u22B3');
+        put("Vscr", '\uD835', '\uDCB1');
+        put("vscr", '\uD835', '\uDCCB');
+        put("vsubnE", '\u2ACB', '\uFE00');
+        put("vsubne", '\u228A', '\uFE00');
+        put("vsupnE", '\u2ACC', '\uFE00');
+        put("vsupne", '\u228B', '\uFE00');
+        put("Vvdash", '\u22AA');
+        put("vzigzag", '\u299A');
+        put("Wcirc", '\u0174');
+        put("wcirc", '\u0175');
+        put("wedbar", '\u2A5F');
+        put("wedge", '\u2227');
+        put("Wedge", '\u22C0');
+        put("wedgeq", '\u2259');
+        put("weierp", '\u2118');
+        put("Wfr", '\uD835', '\uDD1A');
+        put("wfr", '\uD835', '\uDD34');
+        put("Wopf", '\uD835', '\uDD4E');
+        put("wopf", '\uD835', '\uDD68');
+        put("wp", '\u2118');
+        put("wr", '\u2240');
+        put("wreath", '\u2240');
+        put("Wscr", '\uD835', '\uDCB2');
+        put("wscr", '\uD835', '\uDCCC');
+        put("xcap", '\u22C2');
+        put("xcirc", '\u25EF');
+        put("xcup", '\u22C3');
+        put("xdtri", '\u25BD');
+        put("Xfr", '\uD835', '\uDD1B');
+        put("xfr", '\uD835', '\uDD35');
+        put("xharr", '\u27F7');
+        put("xhArr", '\u27FA');
+        put("Xi", '\u039E');
+        put("xi", '\u03BE');
+        put("xlarr", '\u27F5');
+        put("xlArr", '\u27F8');
+        put("xmap", '\u27FC');
+        put("xnis", '\u22FB');
+        put("xodot", '\u2A00');
+        put("Xopf", '\uD835', '\uDD4F');
+        put("xopf", '\uD835', '\uDD69');
+        put("xoplus", '\u2A01');
+        put("xotime", '\u2A02');
+        put("xrarr", '\u27F6');
+        put("xrArr", '\u27F9');
+        put("Xscr", '\uD835', '\uDCB3');
+        put("xscr", '\uD835', '\uDCCD');
+        put("xsqcup", '\u2A06');
+        put("xuplus", '\u2A04');
+        put("xutri", '\u25B3');
+        put("xvee", '\u22C1');
+        put("xwedge", '\u22C0');
+        put("Yacute", '\u00DD');
+        put("yacute", '\u00FD');
+        put("YAcy", '\u042F');
+        put("yacy", '\u044F');
+        put("Ycirc", '\u0176');
+        put("ycirc", '\u0177');
+        put("Ycy", '\u042B');
+        put("ycy", '\u044B');
+        put("yen", '\u00A5');
+        put("Yfr", '\uD835', '\uDD1C');
+        put("yfr", '\uD835', '\uDD36');
+        put("YIcy", '\u0407');
+        put("yicy", '\u0457');
+        put("Yopf", '\uD835', '\uDD50');
+        put("yopf", '\uD835', '\uDD6A');
+        put("Yscr", '\uD835', '\uDCB4');
+        put("yscr", '\uD835', '\uDCCE');
+        put("YUcy", '\u042E');
+        put("yucy", '\u044E');
+        put("yuml", '\u00FF');
+        put("Yuml", '\u0178');
+        put("Zacute", '\u0179');
+        put("zacute", '\u017A');
+        put("Zcaron", '\u017D');
+        put("zcaron", '\u017E');
+        put("Zcy", '\u0417');
+        put("zcy", '\u0437');
+        put("Zdot", '\u017B');
+        put("zdot", '\u017C');
+        put("zeetrf", '\u2128');
+        put("ZeroWidthSpace", '\u200B');
+        put("Zeta", '\u0396');
+        put("zeta", '\u03B6');
+        put("zfr", '\uD835', '\uDD37');
+        put("Zfr", '\u2128');
+        put("ZHcy", '\u0416');
+        put("zhcy", '\u0436');
+        put("zigrarr", '\u21DD');
+        put("zopf", '\uD835', '\uDD6B');
+        put("Zopf", '\u2124');
+        put("Zscr", '\uD835', '\uDCB5');
+        put("zscr", '\uD835', '\uDCCF');
+        put("zwj", '\u200D');
+        put("zwnj", '\u200C');
+    }
+
+    private static void put(String name, char c) {
+        entities.put(name, String.valueOf(c));
+    }
+
+    private static void put(String name, char c1, char c2) {
+        entities.put(name, String.valueOf(new char[] { c1, c2 }));
+    }
+
+    static String getCharacters(EntityTree tree) {
+        String name = tree.getName().toString();
+        if (name.startsWith("#")) {
+            try {
+                int v = StringUtils.toLowerCase(name).startsWith("#x")
+                        ? Integer.parseInt(name.substring(2), 16)
+                        : Integer.parseInt(name.substring(1), 10);
+                // See https://www.w3.org/TR/html52/syntax.html#character-references
+                if (Character.isDefined(v)
+                        && (!Character.isISOControl(v) || Character.isSpaceChar(v))
+                        && (v < 0xd800 || v > 0xdfff)) {
+                    return String.valueOf((char) v);
+                }
+            } catch (NumberFormatException ex) {
+                //ignore
+            }
+            return null;
+        } else {
+            return entities.get(name);
+        }
+    }
+}
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
index e656e4e9e0d..4a1c0702e06 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java
@@ -59,6 +59,7 @@
 
 import com.sun.source.doctree.DocCommentTree;
 import com.sun.source.doctree.DocTree;
+import com.sun.source.doctree.EntityTree;
 import com.sun.source.tree.CatchTree;
 import com.sun.source.tree.ClassTree;
 import com.sun.source.tree.CompilationUnitTree;
@@ -102,7 +103,6 @@
 import com.sun.tools.javac.parser.DocCommentParser;
 import com.sun.tools.javac.parser.ParserFactory;
 import com.sun.tools.javac.parser.Tokens.Comment;
-import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import com.sun.tools.javac.resources.CompilerProperties.Errors;
 import com.sun.tools.javac.resources.CompilerProperties.Notes;
@@ -1162,6 +1162,11 @@ public void setBreakIterator(BreakIterator breakiterator) {
         this.breakIterator = breakiterator;
     }
 
+    @Override @DefinedBy(Api.COMPILER_TREE)
+    public String getCharacters(EntityTree tree) {
+        return Entity.getCharacters(tree);
+    }
+
     /**
      * Makes a copy of a tree, noting the value resulting from copying a particular leaf.
      **/
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java
index f43484bb3b1..aebbc78da36 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java
@@ -220,7 +220,11 @@ public static EnumSet<Flag> asFlagSet(long flags) {
      */
     public static final long UNION = 1L<<39;
 
-    // Flag bit (1L << 40) is available.
+    /**
+     * Flags an erroneous TypeSymbol as viable for recovery.
+     * TypeSymbols only.
+     */
+    public static final long RECOVERABLE = 1L<<40;
 
     /**
      * Flag that marks an 'effectively final' local variable.
@@ -508,6 +512,7 @@ public enum Flag {
         MATCH_BINDING(Flags.MATCH_BINDING),
         MATCH_BINDING_TO_OUTER(Flags.MATCH_BINDING_TO_OUTER),
         RECORD(Flags.RECORD),
+        RECOVERABLE(Flags.RECOVERABLE),
         SEALED(Flags.SEALED),
         NON_SEALED(Flags.NON_SEALED) {
             @Override
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java
index d79f3f7b51a..cf760027c67 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Preview.java
@@ -166,6 +166,7 @@ public boolean isEnabled() {
      */
     public boolean isPreview(Feature feature) {
         if (feature == Feature.PATTERN_MATCHING_IN_INSTANCEOF ||
+            feature == Feature.DECONSTRUCTION_PATTERNS ||
             feature == Feature.REIFIABLE_TYPES_INSTANCEOF ||
             feature == Feature.RECORDS ||
             feature == Feature.SEALED_CLASSES)
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java
index 72e92107bb7..773333de1e2 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java
@@ -218,6 +218,9 @@ public enum Feature {
         REIFIABLE_TYPES_INSTANCEOF(JDK16, Fragments.FeatureReifiableTypesInstanceof, DiagKind.PLURAL),
         RECORDS(JDK16, Fragments.FeatureRecords, DiagKind.PLURAL),
         SEALED_CLASSES(JDK16, Fragments.FeatureSealedClasses, DiagKind.PLURAL),
+        LAMBDA_PARAMETER_SHADOWING(JDK16),
+        UNDERSCORE_AS_PARAM_NAME(JDK16),
+        DECONSTRUCTION_PATTERNS(JDK16, Fragments.FeatureDeconstructionPatterns, DiagKind.PLURAL),
         ;
 
         enum DiagKind {
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java
index 5a5d78be3c8..15ab9cf5642 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java
@@ -155,6 +155,14 @@ public static Symtab instance(Context context) {
     /** The builtin type of all methods. */
     public final ClassSymbol methodClass;
 
+    /** A common method type for all those method symbols owning a lambda scope.
+     */
+    public final MethodType lambdaScopeMethodType;
+
+    /** A common method type for all those method symbols owning a block scope.
+     */
+    public final MethodType blockScopeMethodType;
+
     /** A symbol for the java.base module.
      */
     public final ModuleSymbol java_base;
@@ -479,6 +487,9 @@ public <R, P> R accept(ElementVisitor<R, P> v, P p) {
         methodClass = new ClassSymbol(PUBLIC|ACYCLIC, names.Method, noSymbol);
         methodClass.members_field = new Scope.ErrorScope(boundClass);
 
+        lambdaScopeMethodType = new MethodType(List.nil(), voidType, List.nil(), methodClass);
+        blockScopeMethodType = new MethodType(List.nil(), voidType, List.nil(), methodClass);
+
         // Create class to hold all predefined constants and operations.
         predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage);
         WriteableScope scope = WriteableScope.create(predefClass);
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
index cf26504dfa9..450a63902cc 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -27,7 +27,7 @@
 
 import java.util.*;
 import java.util.function.BiConsumer;
-import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.lang.model.element.ElementKind;
 import javax.tools.JavaFileObject;
@@ -120,6 +120,7 @@ public class Attr extends JCTree.Visitor {
     final Annotate annotate;
     final ArgumentAttr argumentAttr;
     final MatchBindingsComputer matchBindingsComputer;
+    final AttrRecover attrRecover;
 
     public static Attr instance(Context context) {
         Attr instance = context.get(attrKey);
@@ -157,6 +158,7 @@ protected Attr(Context context) {
         dependencies = Dependencies.instance(context);
         argumentAttr = ArgumentAttr.instance(context);
         matchBindingsComputer = MatchBindingsComputer.instance(context);
+        attrRecover = AttrRecover.instance(context);
 
         Options options = Options.instance(context);
 
@@ -166,6 +168,7 @@ protected Attr(Context context) {
         allowLambda = Feature.LAMBDA.allowedInSource(source);
         allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
         allowStaticInterfaceMethods = Feature.STATIC_INTERFACE_METHODS.allowedInSource(source);
+        allowShadowingOfLambdaParameters = Feature.LAMBDA_PARAMETER_SHADOWING.allowedInSource(source);
         allowReifiableTypesInInstanceof =
                 Feature.REIFIABLE_TYPES_INSTANCEOF.allowedInSource(source) &&
                 (!preview.isPreview(Feature.REIFIABLE_TYPES_INSTANCEOF) || preview.isEnabled());
@@ -211,6 +214,11 @@ protected Attr(Context context) {
      */
     boolean useBeforeDeclarationWarning;
 
+    /**
+     * Switch: allow shadowing of lambda parameters?
+     */
+    boolean allowShadowingOfLambdaParameters;
+
     /**
      * Switch: name of source level; used for error reporting.
      */
@@ -419,8 +427,9 @@ private Env<AttrContext> attribToTree(JCTree root, Env<AttrContext> env, JCTree
         JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
         try {
             deferredAttr.attribSpeculative(root, env, resultInfo,
-                    null, DeferredAttr.AttributionMode.ANALYZER,
+                    null, DeferredAttr.AttributionMode.ATTRIB_TO_TREE,
                     argumentAttr.withLocalCacheContext());
+            attrRecover.doRecovery();
         } catch (BreakAttr b) {
             return b.env;
         } catch (AssertionError ae) {
@@ -738,6 +747,7 @@ public Type attribStat(JCTree tree, Env<AttrContext> env) {
         Env<AttrContext> analyzeEnv = analyzer.copyEnvIfNeeded(tree, env);
         Type result = attribTree(tree, env, statInfo);
         analyzer.analyzeIfNeeded(tree, analyzeEnv);
+        attrRecover.doRecovery();
         return result;
     }
 
@@ -1309,6 +1319,12 @@ public void visitVarDef(JCVariableDecl tree) {
                 }
             }
             result = tree.type = v.type;
+            if (tree.name == names.underscore) {
+                WriteableScope enclScope = enter.enterScope(env);
+                if (enclScope != null) {
+                    enclScope.remove(tree.sym);
+                }
+            }
             if (env.enclClass.sym.isRecord() && tree.sym.owner.kind == TYP && !v.isStatic()) {
                 if (isNonArgsMethodInObject(v.name)) {
                     log.error(tree, Errors.IllegalRecordComponentName(v));
@@ -1405,7 +1421,7 @@ public void visitBlock(JCBlock tree) {
             // created BLOCK-method.
             Symbol fakeOwner =
                 new MethodSymbol(tree.flags | BLOCK |
-                    env.info.scope.owner.flags() & STRICTFP, names.empty, null,
+                    env.info.scope.owner.flags() & STRICTFP, names.empty, syms.blockScopeMethodType,
                     env.info.scope.owner);
             final Env<AttrContext> localEnv =
                 env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
@@ -2092,6 +2108,7 @@ public void visitIf(JCIf tree) {
     }
 
         void preFlow(JCTree tree) {
+            attrRecover.doRecovery();
             new PostAttrAnalyzer() {
                 @Override
                 public void scan(JCTree tree) {
@@ -3114,6 +3131,7 @@ TargetInfo getTargetInfo(JCPolyExpression that, ResultInfo resultInfo, List<Type
         }
 
         void preFlow(JCLambda tree) {
+            attrRecover.doRecovery();
             new PostAttrAnalyzer() {
                 @Override
                 public void scan(JCTree tree) {
@@ -3324,10 +3342,11 @@ public MethodSymbol removeClinit(ClassSymbol sym) {
         public Env<AttrContext> lambdaEnv(JCLambda that, Env<AttrContext> env) {
             Env<AttrContext> lambdaEnv;
             Symbol owner = env.info.scope.owner;
+            ClassSymbol enclClass = owner.enclClass();
+            Symbol newScopeOwner = null;
             if (owner.kind == VAR && owner.owner.kind == TYP) {
                 //field initializer
-                ClassSymbol enclClass = owner.enclClass();
-                Symbol newScopeOwner = env.info.scope.owner;
+                newScopeOwner = env.info.scope.owner;
                 /* if the field isn't static, then we can get the first constructor
                  * and use it as the owner of the environment. This is what
                  * LTM code is doing to look for type annotations so we are fine.
@@ -3352,6 +3371,16 @@ public Env<AttrContext> lambdaEnv(JCLambda that, Env<AttrContext> env) {
                     }
                     newScopeOwner = clinit;
                 }
+            } else {
+                if (allowShadowingOfLambdaParameters) {
+                    newScopeOwner = new MethodSymbol(
+                        HYPOTHETICAL,
+                        names.empty,
+                        syms.lambdaScopeMethodType,
+                        owner);
+                }
+            }
+            if (newScopeOwner != null) {
                 lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared(newScopeOwner)));
             } else {
                 lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup()));
@@ -3922,16 +3951,7 @@ public void visitTypeTest(JCInstanceOf tree) {
                 if (preview.isPreview(Feature.REIFIABLE_TYPES_INSTANCEOF)) {
                     preview.warnPreview(tree.expr.pos(), Feature.REIFIABLE_TYPES_INSTANCEOF);
                 }
-                Warner warner = new Warner();
-                if (!types.isCastable(exprtype, clazztype, warner)) {
-                    chk.basicHandler.report(tree.expr.pos(),
-                                            diags.fragment(Fragments.InconvertibleTypes(exprtype, clazztype)));
-                } else if (warner.hasLint(LintCategory.UNCHECKED)) {
-                    log.error(tree.expr.pos(),
-                              Errors.InstanceofReifiableNotSafe(exprtype, clazztype));
-                } else {
-                    valid = true;
-                }
+                valid = verifyCastable(tree.expr.pos(), exprtype, clazztype);
             } else {
                 log.error(typeTree.pos(), Errors.IllegalGenericTypeForInstof);
             }
@@ -3945,18 +3965,79 @@ public void visitTypeTest(JCInstanceOf tree) {
     }
 
     public void visitBindingPattern(JCBindingPattern tree) {
-        ResultInfo varInfo = new ResultInfo(KindSelector.TYP, resultInfo.pt, resultInfo.checkContext);
-        tree.type = attribTree(tree.vartype, env, varInfo);
-        VarSymbol v = tree.symbol = new BindingSymbol(tree.name, tree.vartype.type, env.info.scope.owner);
+        if (tree.vartype != null) {
+            ResultInfo varInfo = new ResultInfo(KindSelector.TYP, resultInfo.pt, resultInfo.checkContext);
+            tree.type = attribTree(tree.vartype, env, varInfo);
+        } else {
+            tree.type = resultInfo.pt;
+        }
+        VarSymbol v = tree.symbol = new BindingSymbol(tree.name, tree.vartype != null ? tree.vartype.type : (tree.type.hasTag(BOT) ? syms.objectType : tree.type), env.info.scope.owner);
         if (chk.checkUnique(tree.pos(), v, env.info.scope)) {
             chk.checkTransparentVar(tree.pos(), v, env.info.scope);
         }
-        annotate.queueScanTreeAndTypeAnnotate(tree.vartype, env, v, tree.pos());
-        annotate.flush();
+        if (tree.vartype != null) {
+            annotate.queueScanTreeAndTypeAnnotate(tree.vartype, env, v, tree.pos());
+            annotate.flush();
+        }
         result = tree.type;
         matchBindings = new MatchBindings(List.of(tree.symbol), List.nil());
     }
 
+    @Override
+    public void visitDeconstructionPattern(JCDeconstructionPattern tree) {
+        tree.type = attribType(tree.deconstructor, env);
+        Type site = types.removeWildcards(tree.type);
+        List<Type> expectedRecordTypes;
+        if (site.tsym.kind == Kind.TYP && ((ClassSymbol) site.tsym).isRecord()) {
+            ClassSymbol record = (ClassSymbol) site.tsym;
+            expectedRecordTypes = record.getRecordComponents().stream().map(rc -> types.memberType(site, rc)).collect(List.collector());
+            tree.record = record;
+        } else {
+            log.error(tree.pos(), Errors.DeconstructionPatternOnlyRecords(site.tsym));
+            expectedRecordTypes = Stream.generate(() -> Type.noType)
+                                .limit(tree.nested.size())
+                                .collect(List.collector());
+        }
+        ListBuffer<BindingSymbol> outBindings = new ListBuffer<>();
+        List<Type> recordTypes = expectedRecordTypes;
+        List<JCPattern> nestedPatterns = tree.nested;
+        while (recordTypes.nonEmpty() && nestedPatterns.nonEmpty()) {
+            boolean nestedIsVarPattern = nestedPatterns.head.hasTag(BINDINGPATTERN) &&
+                                         ((JCBindingPattern) nestedPatterns.head).vartype == null;
+            attribExpr(nestedPatterns.head, env, nestedIsVarPattern ? recordTypes.head : Type.noType);
+            verifyCastable(nestedPatterns.head.pos(), recordTypes.head, nestedPatterns.head.type);
+            outBindings.addAll(matchBindings.bindingsWhenTrue);
+            nestedPatterns = nestedPatterns.tail;
+            recordTypes = recordTypes.tail;
+        }
+        if (recordTypes.nonEmpty() || nestedPatterns.nonEmpty()) {
+            while (nestedPatterns.nonEmpty()) {
+                attribExpr(nestedPatterns.head, env, Type.noType);
+                nestedPatterns = nestedPatterns.tail;
+            }
+            List<Type> nestedTypes =
+                    tree.nested.stream().map(p -> p.type).collect(List.collector());
+            log.error(tree.pos(),
+                      Errors.IncorrectNumberOfNestedPatterns(expectedRecordTypes,
+                                                             nestedTypes));
+        }
+        result = tree.type;
+        matchBindings = new MatchBindings(outBindings.toList(), List.nil());
+    }
+
+    private boolean verifyCastable(DiagnosticPosition pos, Type exprtype, Type clazztype) {
+        Warner warner = new Warner();
+        if (!chk.checkCastable(pos, exprtype, clazztype, chk.basicHandler, warner)) {
+            return false;
+        } else if (warner.hasLint(LintCategory.UNCHECKED)) {
+            log.error(pos,
+                      Errors.InstanceofReifiableNotSafe(exprtype, clazztype));
+            return false;
+        } else {
+            return true;
+        }
+    }
+
     public void visitIndexed(JCArrayAccess tree) {
         Type owntype = types.createErrorType(tree.type);
         Type atype = attribExpr(tree.indexed, env);
@@ -4307,10 +4388,7 @@ Type checkMethodIdInternal(JCTree tree,
                      Env<AttrContext> env,
                      ResultInfo resultInfo) {
             if (resultInfo.pkind.contains(KindSelector.POLY)) {
-                Type pt = resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase));
-                Type owntype = checkIdInternal(tree, site, sym, pt, env, resultInfo);
-                resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
-                return owntype;
+                return attrRecover.recoverMethodInvocation(tree, site, sym, env, resultInfo);
             } else {
                 return checkIdInternal(tree, site, sym, resultInfo.pt, env, resultInfo);
             }
@@ -4916,9 +4994,12 @@ public void visitAnnotatedType(JCAnnotatedType tree) {
     }
 
     public void visitErroneous(JCErroneous tree) {
-        if (tree.errs != null)
+        if (tree.errs != null) {
+            Env<AttrContext> errEnv = env.dup(env.tree);
+            errEnv.info.returnResult = unknownExprInfo;
             for (JCTree err : tree.errs)
-                attribTree(err, env, new ResultInfo(KindSelector.ERR, pt()));
+                attribTree(err, errEnv, new ResultInfo(KindSelector.ERR, pt()));
+        }
         result = tree.type = syms.errType;
     }
 
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java
new file mode 100644
index 00000000000..8fd09501717
--- /dev/null
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/AttrRecover.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.tools.javac.comp;
+
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Symbol;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ArrayType;
+import com.sun.tools.javac.code.Type.ErrorType;
+import com.sun.tools.javac.code.TypeTag;
+import com.sun.tools.javac.code.Types;
+import com.sun.tools.javac.comp.Attr.ResultInfo;
+import com.sun.tools.javac.comp.DeferredAttr.AttrMode;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCErroneous;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.JCTree.JCLambda;
+import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
+import com.sun.tools.javac.tree.JCTree.JCReturn;
+import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.tree.JCTree.Tag;
+import com.sun.tools.javac.tree.TreeInfo;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.tree.TreeTranslator;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.JCDiagnostic;
+import com.sun.tools.javac.util.List;
+import com.sun.tools.javac.util.ListBuffer;
+import com.sun.tools.javac.util.Names;
+
+/** This is an error recovery addon for Attr. Currently, it recovers
+ *  method invocations with lambdas, that require type inference.
+ *
+ *  <p><b>This is NOT part of any supported API.
+ *  If you write code that depends on this, you do so at your own risk.
+ *  This code and its internal interfaces are subject to change or
+ *  deletion without notice.</b>
+ */
+public class AttrRecover {
+    protected static final Context.Key<AttrRecover> attrRepairKey = new Context.Key<>();
+
+    final Attr attr;
+    final DeferredAttr deferredAttr;
+    final Names names;
+    final TreeMaker make;
+    final Symtab syms;
+    final Types types;
+
+    public static AttrRecover instance(Context context) {
+        AttrRecover instance = context.get(attrRepairKey);
+        if (instance == null)
+            instance = new AttrRecover(context);
+        return instance;
+    }
+
+    protected AttrRecover(Context context) {
+        context.put(attrRepairKey, this);
+
+        attr = Attr.instance(context);
+        deferredAttr = DeferredAttr.instance(context);
+        names = Names.instance(context);
+        make = TreeMaker.instance(context);
+        syms = Symtab.instance(context);
+        types = Types.instance(context);
+    }
+
+    private final ListBuffer<RecoverTodo> recoveryTodo = new ListBuffer<>();
+
+    public void doRecovery() {
+        while (recoveryTodo.nonEmpty()) {
+            RecoverTodo todo = recoveryTodo.remove();
+            ListBuffer<Runnable> rollback = new ListBuffer<>();
+            boolean repaired = false;
+            RECOVER: if (todo.env.tree.hasTag(Tag.APPLY)) {
+                JCMethodInvocation mit = (JCMethodInvocation) todo.env.tree;
+                boolean vararg = (todo.candSym.flags() & Flags.VARARGS) !=  0;
+                if (!vararg &&
+                    mit.args.length() > todo.candSym.type.getParameterTypes().length()) {
+                    break RECOVER; //too many actual parameters, skip
+                }
+                List<JCExpression> args = mit.args;
+                List<Type> formals = todo.candSym.type.getParameterTypes();
+                while (args.nonEmpty() && formals.nonEmpty()) {
+                    JCExpression arg = args.head;
+                    Type formal = formals.tail.nonEmpty() || !vararg
+                            ? formals.head : ((ArrayType) formals.head).elemtype;
+                    if (arg.hasTag(JCTree.Tag.LAMBDA)) {
+                        final JCTree.JCLambda lambda = (JCLambda) arg;
+                        if (lambda.paramKind == JCLambda.ParameterKind.IMPLICIT) {
+                            for (JCVariableDecl var : lambda.params) {
+                                var.vartype = null; //reset type
+                            }
+                        }
+                        if (types.isFunctionalInterface(formal)) {
+                            Type functionalType = types.findDescriptorType(formal);
+                            boolean voidCompatible = functionalType.getReturnType().hasTag(TypeTag.VOID);
+                            lambda.body = new TreeTranslator() {
+                                @Override
+                                public void visitReturn(JCReturn tree) {
+                                    result = tree;
+                                    if (voidCompatible) {
+                                        if (tree.expr != null) {
+                                            JCErroneous err = make.Erroneous(List.of(tree));
+                                            result = err;
+                                            rollback.append(() -> {
+                                                lambda.body = new TreeTranslator() {
+                                                    @SuppressWarnings("unchecked")
+                                                    public <T extends JCTree> T translate(T t) {
+                                                        if (t == err) return (T) tree;
+                                                        else return super.translate(t);
+                                                    }
+                                                }.translate(lambda.body);
+                                            });
+                                        }
+                                    } else {
+                                        if (tree.expr == null) {
+                                            tree.expr = make.Erroneous().setType(syms.errType);
+                                            rollback.append(() -> {
+                                                tree.expr = null;
+                                            });
+                                        }
+                                    }
+                                }
+                                @Override
+                                public void visitLambda(JCLambda tree) {
+                                    //do not touch nested lambdas
+                                }
+                                @Override
+                                public void visitClassDef(JCClassDecl tree) {
+                                    //do not touch nested classes
+                                }
+                            }.translate(lambda.body);
+                            if (!voidCompatible) {
+                                JCReturn ret = make.Return(make.Erroneous().setType(syms.errType));
+                                ((JCBlock) lambda.body).stats = ((JCBlock) lambda.body).stats.append(ret);
+                                rollback.append(() -> {
+                                    ((JCBlock) lambda.body).stats = List.filter(((JCBlock) lambda.body).stats, ret);
+                                });
+                            }
+                        }
+                        repaired = true;
+                    }
+                    args = args.tail;
+                    if (formals.tail.nonEmpty() || !vararg) {
+                        formals = formals.tail;
+                    }
+                }
+                List<JCExpression> prevArgs = mit.args;
+                while (formals.nonEmpty()) {
+                    mit.args = mit.args.append(make.Erroneous().setType(syms.errType));
+                    formals = formals.tail;
+                    repaired = true;
+                }
+                rollback.append(() -> {
+                    mit.args = prevArgs;
+                });
+            }
+
+            Type owntype;
+            if (repaired) {
+                List<JCExpression> args = TreeInfo.args(todo.env.tree);
+                List<Type> pats = todo.resultInfo.pt.getParameterTypes();
+                while (pats.length() < args.length()) {
+                    pats = pats.append(syms.errType);
+                }
+                owntype = attr.checkMethod(todo.site, todo.candSym,
+                                 attr.new ResultInfo(todo.resultInfo.pkind, todo.resultInfo.pt.getReturnType(), todo.resultInfo.checkContext, todo.resultInfo.checkMode),
+                                 todo.env, args, pats,
+                                 todo.resultInfo.pt.getTypeArguments());
+                rollback.stream().forEach(Runnable::run);
+            } else {
+                owntype = basicMethodInvocationRecovery(todo.tree, todo.site, todo.errSym, todo.env, todo.resultInfo);
+            }
+            todo.tree.type = owntype;
+        }
+    }
+
+    Type recoverMethodInvocation(JCTree tree,
+                                 Type site,
+                                 Symbol sym,
+                                 Env<AttrContext> env,
+                                 ResultInfo resultInfo) {
+        if ((sym.flags_field & Flags.RECOVERABLE) != 0 && env.info.attributionMode.recover()) {
+            recoveryTodo.append(new RecoverTodo(tree, site, sym, ((RecoveryErrorType) sym.type).candidateSymbol, attr.copyEnv(env), resultInfo));
+            return syms.errType;
+        } else {
+            return basicMethodInvocationRecovery(tree, site, sym, env, resultInfo);
+        }
+    }
+
+    private Type basicMethodInvocationRecovery(JCTree tree,
+                                               Type site,
+                                               Symbol sym,
+                                               Env<AttrContext> env,
+                                               ResultInfo resultInfo) {
+        Type pt = resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, sym, env.info.pendingResolutionPhase));
+        Type owntype = attr.checkIdInternal(tree, site, sym, pt, env, resultInfo);
+        resultInfo.pt.map(deferredAttr.new RecoveryDeferredTypeMap(AttrMode.CHECK, sym, env.info.pendingResolutionPhase));
+        return owntype;
+    }
+
+    void wrongMethodSymbolCandidate(TypeSymbol errSymbol, Symbol candSym, JCDiagnostic diag) {
+        List<JCDiagnostic> diags = List.of(diag);
+        boolean recoverable = false;
+        while (!recoverable && diags.nonEmpty()) {
+            JCDiagnostic d = diags.head;
+            diags = diags.tail;
+            switch (d.getCode()) {
+                case "compiler.misc.missing.ret.val":
+                case "compiler.misc.unexpected.ret.val":
+                case "compiler.misc.infer.arg.length.mismatch":
+                case "compiler.misc.arg.length.mismatch":
+                    errSymbol.type = new RecoveryErrorType((Type.ErrorType) errSymbol.type, candSym);
+                    errSymbol.flags_field |= Flags.RECOVERABLE;
+                    return ;
+                default:
+                    break;
+            }
+            for (Object a : d.getArgs()) {
+                if (a instanceof JCDiagnostic) {
+                    diags = diags.prepend((JCDiagnostic) a);
+                }
+            }
+        }
+    }
+
+    private static class RecoveryErrorType extends ErrorType {
+        public final Symbol candidateSymbol;
+
+        public RecoveryErrorType(ErrorType original, Symbol candidateSymbol) {
+            super(original.getOriginalType(), original.tsym);
+            this.candidateSymbol = candidateSymbol;
+        }
+
+    }
+
+    private static class RecoverTodo {
+        public final JCTree tree;
+        public final Type site;
+        public final Symbol errSym;
+        public final Symbol candSym;
+        public final Env<AttrContext> env;
+        public final ResultInfo resultInfo;
+
+        public RecoverTodo(JCTree tree, Type site, Symbol errSym, Symbol candSym,
+                           Env<AttrContext> env, Attr.ResultInfo resultInfo) {
+            this.tree = tree;
+            this.site = site;
+            this.errSym = errSym;
+            this.candSym = candSym;
+            this.env = env;
+            this.resultInfo = resultInfo;
+        }
+
+    }
+}
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
index f1725857891..b59065c5511 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java
@@ -630,14 +630,23 @@ Type checkCastable(DiagnosticPosition pos, Type found, Type req) {
         return checkCastable(pos, found, req, basicHandler);
     }
     Type checkCastable(DiagnosticPosition pos, Type found, Type req, CheckContext checkContext) {
-        if (types.isCastable(found, req, castWarner(pos, found, req))) {
+        if (checkCastable(pos, found, req, checkContext, castWarner(pos, found, req))) {
             return req;
         } else {
-            checkContext.report(pos, diags.fragment(Fragments.InconvertibleTypes(found, req)));
             return types.createErrorType(found);
         }
     }
 
+    boolean checkCastable(DiagnosticPosition pos, Type found, Type req,
+                          CheckContext checkContext, Warner warner) {
+        if (types.isCastable(found, req, warner)) {
+            return true;
+        } else {
+            checkContext.report(pos, diags.fragment(Fragments.InconvertibleTypes(found, req)));
+            return false;
+        }
+    }
+
     /** Check for redundant casts (i.e. where source type is a subtype of target type)
      * The problem should only be reported for non-292 cast
      */
@@ -1307,7 +1316,10 @@ && checkDisjoint(pos, flags,
                            SEALED | NON_SEALED)
                  && checkDisjoint(pos, flags,
                                 SEALED,
-                           FINAL | NON_SEALED)) {
+                           FINAL | NON_SEALED)
+                 && checkDisjoint(pos, flags,
+                                SEALED,
+                                ANNOTATION)) {
             // skip
         }
         return flags & (mask | ~ExtendedStandardFlags) | implicit;
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
index 66ed1834179..f64274ca4de 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/DeferredAttr.java
@@ -1329,20 +1329,28 @@ public void visitReference(JCMemberReference tree) {
      */
     enum AttributionMode {
         /**Normal, non-speculative, attribution.*/
-        FULL(false),
+        FULL(false, true),
         /**Speculative attribution on behalf of an Analyzer.*/
-        ANALYZER(true),
+        ATTRIB_TO_TREE(true, true),
+        /**Speculative attribution on behalf of an Analyzer.*/
+        ANALYZER(true, false),
         /**Speculative attribution.*/
-        SPECULATIVE(true);
+        SPECULATIVE(true, false);
 
-        AttributionMode(boolean isSpeculative) {
+        AttributionMode(boolean isSpeculative, boolean recover) {
             this.isSpeculative = isSpeculative;
+            this.recover = recover;
         }
 
         boolean isSpeculative() {
             return isSpeculative;
         }
 
+        boolean recover() {
+            return recover;
+        }
+
         final boolean isSpeculative;
+        final boolean recover;
     }
 }
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java
index b4dd7d84cc4..f70d1d72c4b 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java
@@ -480,9 +480,11 @@ public void visitClassDef(JCClassDecl tree) {
             // which contains this class in a non-static context
             // (its "enclosing instance class"), provided such a class exists.
             Symbol owner1 = owner;
+            owner1 = skipLambdaOwner(owner1);
             while (owner1.kind.matches(KindSelector.VAL_MTH) &&
                    (owner1.flags_field & STATIC) == 0) {
                 owner1 = owner1.owner;
+                owner1 = skipLambdaOwner(owner1);
             }
             if (owner1.kind == TYP) {
                 ct.setEnclosingType(owner1.type);
@@ -517,6 +519,13 @@ private static boolean classNameMatchesFileName(ClassSymbol c,
                                                             JavaFileObject.Kind.SOURCE);
         }
 
+        private Symbol skipLambdaOwner(Symbol currentOwner) {
+            while (currentOwner.type == syms.lambdaScopeMethodType) {
+                currentOwner = currentOwner.owner;
+            }
+            return currentOwner;
+        }
+
     /** Complain about a duplicate class. */
     protected void duplicateClass(DiagnosticPosition pos, ClassSymbol c) {
         log.error(pos, Errors.DuplicateClass(c.fullname));
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
index 095e5f68d28..1d67ec9bdc0 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -2527,47 +2527,6 @@ JCTree generateRecordMethod(JCClassDecl tree, Name name, List<VarSymbol> vars, M
         }
     }
 
-    private String argsTypeSig(List<Type> typeList) {
-        LowerSignatureGenerator sg = new LowerSignatureGenerator();
-        sg.assembleSig(typeList);
-        return sg.toString();
-    }
-
-    /**
-     * Signature Generation
-     */
-    private class LowerSignatureGenerator extends Types.SignatureGenerator {
-
-        /**
-         * An output buffer for type signatures.
-         */
-        StringBuilder sb = new StringBuilder();
-
-        LowerSignatureGenerator() {
-            super(types);
-        }
-
-        @Override
-        protected void append(char ch) {
-            sb.append(ch);
-        }
-
-        @Override
-        protected void append(byte[] ba) {
-            sb.append(new String(ba));
-        }
-
-        @Override
-        protected void append(Name name) {
-            sb.append(name.toString());
-        }
-
-        @Override
-        public String toString() {
-            return sb.toString();
-        }
-    }
-
     /**
      * Creates an indy qualifier, helpful to be part of an indy invocation
      * @param site                the site
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MatchBindingsComputer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MatchBindingsComputer.java
index 07e48ff1838..7e44d52936e 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MatchBindingsComputer.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MatchBindingsComputer.java
@@ -120,7 +120,7 @@ public MatchBindings binary(JCTree tree, MatchBindings lhsBindings, MatchBinding
     public MatchBindings finishBindings(JCTree tree, MatchBindings matchBindings) {
         switch (tree.getTag()) {
             case NOT: case AND: case OR: case BINDINGPATTERN:
-            case PARENS: case TYPETEST:
+            case PARENS: case TYPETEST: case DECONSTRUCTIONPATTERN:
             case CONDEXPR: //error recovery:
                 return matchBindings;
             default:
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
index e855c240360..6fd598340b7 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -96,6 +96,7 @@ public class Resolve {
     Log log;
     Symtab syms;
     Attr attr;
+    AttrRecover attrRecover;
     DeferredAttr deferredAttr;
     Check chk;
     Infer infer;
@@ -126,6 +127,7 @@ protected Resolve(Context context) {
         names = Names.instance(context);
         log = Log.instance(context);
         attr = Attr.instance(context);
+        attrRecover = AttrRecover.instance(context);
         deferredAttr = DeferredAttr.instance(context);
         chk = Check.instance(context);
         infer = Infer.instance(context);
@@ -4043,12 +4045,12 @@ JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind,
 
         @Override
         public Symbol access(Name name, TypeSymbol location) {
-            Symbol sym = bestCandidate();
-            return types.createErrorType(name, location, sym != null ? sym.type : syms.errSymbol.type).tsym;
-        }
-
-        protected Symbol bestCandidate() {
-            return errCandidate().fst;
+            Pair<Symbol, JCDiagnostic> cand = errCandidate();
+            TypeSymbol errSymbol = types.createErrorType(name, location, cand != null ? cand.fst.type : syms.errSymbol.type).tsym;
+            if (cand != null) {
+                attrRecover.wrongMethodSymbolCandidate(errSymbol, cand.fst, cand.snd);
+            }
+            return errSymbol;
         }
 
         protected Pair<Symbol, JCDiagnostic> errCandidate() {
@@ -4181,11 +4183,12 @@ private List<JCDiagnostic> candidateDetails(Map<Symbol, JCDiagnostic> candidates
             }
 
         @Override
-        protected Symbol bestCandidate() {
+        protected Pair<Symbol, JCDiagnostic> errCandidate() {
             Map<Symbol, JCDiagnostic> candidatesMap = mapCandidates();
             Map<Symbol, JCDiagnostic> filteredCandidates = filterCandidates(candidatesMap);
             if (filteredCandidates.size() == 1) {
-                return filteredCandidates.keySet().iterator().next();
+                return Pair.of(filteredCandidates.keySet().iterator().next(),
+                               filteredCandidates.values().iterator().next());
             }
             return null;
         }
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java
index 4a97cf4c1c1..ee572e4d95f 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransPatterns.java
@@ -26,13 +26,13 @@
 package com.sun.tools.javac.comp;
 
 import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Kinds.Kind;
 import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.BindingSymbol;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
 import com.sun.tools.javac.code.Symbol.VarSymbol;
 import com.sun.tools.javac.code.Symtab;
-import com.sun.tools.javac.code.Type;
 import com.sun.tools.javac.code.Types;
-import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCAssign;
 import com.sun.tools.javac.tree.JCTree.JCBinary;
 import com.sun.tools.javac.tree.JCTree.JCConditional;
@@ -58,18 +58,23 @@
 
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.LinkedHashMap;
 
 import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.code.Symbol.RecordComponent;
+import com.sun.tools.javac.code.Type;
 import static com.sun.tools.javac.code.TypeTag.BOT;
 import com.sun.tools.javac.jvm.Target;
 import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCBlock;
+import com.sun.tools.javac.tree.JCTree.JCClassDecl;
+import com.sun.tools.javac.tree.JCTree.JCDeconstructionPattern;
 import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop;
+import com.sun.tools.javac.tree.JCTree.JCPattern;
 import com.sun.tools.javac.tree.JCTree.JCLambda;
 import com.sun.tools.javac.tree.JCTree.JCStatement;
 import com.sun.tools.javac.tree.JCTree.LetExpr;
 import com.sun.tools.javac.util.List;
-import java.util.HashMap;
 
 /**
  * This pass translates pattern-matching constructs, such as instanceof <pattern>.
@@ -131,7 +136,8 @@ boolean tryPrepend(BindingSymbol binding, JCVariableDecl var) {
 
     boolean debugTransPatterns;
 
-    private MethodSymbol currentMethodSym = null;
+    private ClassSymbol currentClass;
+    private Symbol currentOwnerSym = null;
 
     protected TransPatterns(Context context) {
         context.put(transPatternsKey, this);
@@ -148,38 +154,122 @@ protected TransPatterns(Context context) {
 
     @Override
     public void visitTypeTest(JCInstanceOf tree) {
-        if (tree.pattern.hasTag(Tag.BINDINGPATTERN)) {
+        if (tree.pattern.hasTag(Tag.BINDINGPATTERN) || tree.pattern.hasTag(Tag.DECONSTRUCTIONPATTERN)) {
             //E instanceof T N
+            //E instanceof T(PATT1, PATT2, ...)
             //=>
-            //(let T' N$temp = E; N$temp instanceof T && (N = (T) N$temp == (T) N$temp))
-            JCBindingPattern patt = (JCBindingPattern)tree.pattern;
-            VarSymbol pattSym = patt.symbol;
+            //(let T' N$temp = E; N$temp instanceof T && <pattern extractor>)
             Type tempType = tree.expr.type.hasTag(BOT) ?
                     syms.objectType
                     : tree.expr.type;
-            VarSymbol temp = new VarSymbol(pattSym.flags() | Flags.SYNTHETIC,
-                    names.fromString(pattSym.name.toString() + target.syntheticNameChar() + "temp"),
+            VarSymbol temp = new VarSymbol(Flags.SYNTHETIC,
+                    names.fromString(target.syntheticNameChar() + "e" + target.syntheticNameChar()),
                     tempType,
-                    patt.symbol.owner);
+                    currentOwnerSym);
             JCExpression translatedExpr = translate(tree.expr);
-            Type castTargetType = types.boxedTypeOrType(pattSym.erasure(types));
+            Type castTargetType;
+            //TODO: use rule switch (when boot JDK is 14):
+            switch (tree.pattern.getTag()) {
+                case BINDINGPATTERN:
+                    castTargetType = ((JCBindingPattern)tree.pattern).symbol.type;
+                    break;
+                case DECONSTRUCTIONPATTERN:
+                    castTargetType = ((JCDeconstructionPattern)tree.pattern).type;
+                    break;
+                default:
+                    throw new AssertionError("Unexpected pattern type: " + tree.pattern.getTag());
+            }
+
+            castTargetType = types.boxedTypeOrType(types.erasure(castTargetType));
 
-            result = makeTypeTest(make.Ident(temp), make.Type(castTargetType));
+            result = makeTypeTest(make.at(tree.pos).Ident(temp), make.Type(castTargetType));
+            result = makeBinary(Tag.AND, (JCExpression)result,
+                                         preparePatternExtractor(tree, tree.getPattern(), temp, castTargetType));
+            result = make.at(tree.pos).LetExpr(make.VarDef(temp, translatedExpr),
+                                               (JCExpression)result).setType(syms.booleanType);
+            ((LetExpr) result).needsCond = true;
+        } else {
+            super.visitTypeTest(tree);
+        }
+    }
 
-            VarSymbol bindingVar = bindingContext.bindingDeclared(patt.symbol);
+    private JCExpression preparePatternExtractor(JCInstanceOf tree, JCPattern patt, VarSymbol temp, Type targetType) {
+        if (targetType == syms.botType) {
+            targetType = syms.objectType;
+        }
+        if (patt.hasTag(Tag.BINDINGPATTERN)) {
+            //type test already done, finish handling of type test patterns ("T N")
+            //=>
+            //(let N = (T) N$temp; true)
+            VarSymbol bindingVar = bindingContext.bindingDeclared(((JCBindingPattern) patt).symbol);
             if (bindingVar != null) { //TODO: cannot be null here?
                 JCAssign fakeInit = (JCAssign)make.at(tree.pos).Assign(
-                        make.Ident(bindingVar), convert(make.Ident(temp), castTargetType)).setType(bindingVar.erasure(types));
+                        make.Ident(bindingVar), convert(make.Ident(temp), targetType)).setType(bindingVar.erasure(types));
                 LetExpr nestedLE = make.LetExpr(List.of(make.Exec(fakeInit)),
                                                 make.Literal(true));
                 nestedLE.needsCond = true;
                 nestedLE.setType(syms.booleanType);
-                result = makeBinary(Tag.AND, (JCExpression)result, nestedLE);
+                return nestedLE;
             }
-            result = make.at(tree.pos).LetExpr(make.VarDef(temp, translatedExpr), (JCExpression)result).setType(syms.booleanType);
-            ((LetExpr) result).needsCond = true;
+            return make.Literal(true);
+        } else if (patt.hasTag(Tag.DECONSTRUCTIONPATTERN)) {
+            //type test already done, finish handling of deconstruction patterns ("T(PATT1, PATT2, ...)")
+            //=>
+            //<PATT1-handling> && <PATT2-handling> && ...
+            JCDeconstructionPattern dpatt = (JCDeconstructionPattern) patt;
+            List<? extends RecordComponent> components = dpatt.record.getRecordComponents();
+            List<? extends JCPattern> nestedPatterns = dpatt.nested;
+            JCExpression test = null;
+            while (components.nonEmpty() && nestedPatterns.nonEmpty()) {
+                //PATTn for record component COMPn of type Tn;
+                //PATTn is a type test pattern or a deconstruction pattern:
+                //=>
+                //(let Tn $c$COMPn = ((T) N$temp).COMPn(); <PATTn extractor>)
+                //or
+                //(let Tn $c$COMPn = ((T) N$temp).COMPn(); $c$COMPn != null && <PATTn extractor>)
+                //or
+                //(let Tn $c$COMPn = ((T) N$temp).COMPn(); $c$COMPn instanceof T' && <PATTn extractor>)
+                RecordComponent component = components.head;
+                JCPattern nested = nestedPatterns.head;
+                VarSymbol nestedTemp = new VarSymbol(Flags.SYNTHETIC,
+                    names.fromString(target.syntheticNameChar() + "c" + target.syntheticNameChar() + component.name),
+                                     component.erasure(types),
+                                     currentOwnerSym);
+                Symbol accessor = dpatt.record
+                                       .members()
+                                       .findFirst(component.name, s -> s.kind == Kind.MTH &&
+                                                                       ((MethodSymbol) s).params.isEmpty());
+                JCVariableDecl nestedTempVar =
+                        make.VarDef(nestedTemp,
+                                    make.App(make.Select(convert(make.Ident(temp), dpatt.type),
+                                                         accessor)));
+                JCExpression extracted =
+                        preparePatternExtractor(tree, nested, nestedTemp, nested.type);
+                JCExpression extraTest = null;
+                if (!types.isAssignable(nestedTemp.type, nested.type)) {
+                    extraTest = makeTypeTest(make.Ident(nestedTemp),
+                                             make.Type(nested.type));
+                } else if (nested.type.isReference()) {
+                    extraTest = makeBinary(Tag.NE, make.Ident(nestedTemp), makeNull());
+                }
+                if (extraTest != null) {
+                    extracted = makeBinary(Tag.AND, extraTest, extracted);
+                }
+                LetExpr getAndRun = make.LetExpr(nestedTempVar, extracted);
+                getAndRun.needsCond = true;
+                getAndRun.setType(syms.booleanType);
+                if (test == null) {
+                    test = getAndRun;
+                } else {
+                    test = makeBinary(Tag.AND, test, getAndRun);
+                }
+                components = components.tail;
+                nestedPatterns = nestedPatterns.tail;
+            }
+            Assert.check(components.isEmpty() == nestedPatterns.isEmpty());
+            return test != null ? test : make.Literal(true);
         } else {
-            super.visitTypeTest(tree);
+            throw new IllegalStateException();
         }
     }
 
@@ -251,12 +341,36 @@ public void visitDoLoop(JCDoWhileLoop tree) {
 
     @Override
     public void visitMethodDef(JCMethodDecl tree) {
-        MethodSymbol prevMethodSym = currentMethodSym;
+        Symbol prevOwnerSym = currentOwnerSym;
         try {
-            currentMethodSym = tree.sym;
+            currentOwnerSym = tree.sym;
             super.visitMethodDef(tree);
         } finally {
-            currentMethodSym = prevMethodSym;
+            currentOwnerSym = prevOwnerSym;
+        }
+    }
+
+    @Override
+    public void visitVarDef(JCVariableDecl tree) {
+        Symbol prevOwnerSym = currentOwnerSym;
+        try {
+            if (tree.sym.owner.kind == Kind.TYP) {
+                currentOwnerSym = tree.sym;
+            }
+            super.visitVarDef(tree);
+        } finally {
+            currentOwnerSym = prevOwnerSym;
+        }
+    }
+
+    @Override
+    public void visitClassDef(JCClassDecl tree) {
+        ClassSymbol prevCurrentClass = currentClass;
+        try {
+            currentClass = tree.sym;
+            super.visitClassDef(tree);
+        } finally {
+            currentClass = prevCurrentClass;
         }
     }
 
@@ -297,7 +411,13 @@ boolean tryPrepend(BindingSymbol binding, JCVariableDecl var) {
                 return true;
             }
         };
+        Symbol prevOwnerSym = currentOwnerSym;
         try {
+            if (currentOwnerSym == null) {
+                currentOwnerSym = new MethodSymbol(tree.flags | Flags.BLOCK,
+                                 names.empty, null,
+                                 currentClass);
+            }
             for (List<JCStatement> l = tree.stats; l.nonEmpty(); l = l.tail) {
                 statements.append(translate(l.head));
             }
@@ -306,6 +426,7 @@ boolean tryPrepend(BindingSymbol binding, JCVariableDecl var) {
             result = tree;
         } finally {
             bindingContext.pop();
+            currentOwnerSym = prevOwnerSym;
         }
     }
 
@@ -355,6 +476,22 @@ JCBinary makeBinary(JCTree.Tag optag, JCExpression lhs, JCExpression rhs) {
         return tree;
     }
 
+    /** Make an attributed tree representing a literal. This will be an
+     *  Ident node in the case of boolean literals, a Literal node in all
+     *  other cases.
+     *  @param type       The literal's type.
+     *  @param value      The literal's value.
+     */
+    JCExpression makeLit(Type type, Object value) {
+        return make.Literal(type.getTag(), value).setType(type.constType(value));
+    }
+
+    /** Make an attributed tree representing null.
+     */
+    JCExpression makeNull() {
+        return makeLit(syms.botType, null);
+    }
+
     JCExpression convert(JCExpression expr, Type target) {
         JCExpression result = make.at(expr.pos()).TypeCast(make.Type(target), expr);
         result.type = target;
@@ -376,7 +513,7 @@ class BasicBindingContext extends BindingContext {
 
         public BasicBindingContext() {
             this.parent = bindingContext;
-            this.hoistedVarMap = new HashMap<>();
+            this.hoistedVarMap = new LinkedHashMap<>();
         }
 
         @Override
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
index fb33a7b0d7f..e737230a3ae 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TransTypes.java
@@ -585,6 +585,13 @@ public void visitSwitchExpression(JCSwitchExpression tree) {
         result = retype(tree, tree.type, pt);
     }
 
+    @Override
+    public void visitDeconstructionPattern(JCDeconstructionPattern tree) {
+        tree.deconstructor = translate(tree.deconstructor, null);
+        tree.nested = translate(tree.nested, null);
+        result = tree;
+    }
+
     public void visitSynchronized(JCSynchronized tree) {
         tree.lock = translate(tree.lock, erasure(tree.lock.type));
         tree.body = translate(tree.body);
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TreeDiffer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TreeDiffer.java
index 124fa61f4e8..55a934fd3fb 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TreeDiffer.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TreeDiffer.java
@@ -45,6 +45,7 @@
 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
 import com.sun.tools.javac.tree.JCTree.JCConditional;
 import com.sun.tools.javac.tree.JCTree.JCContinue;
+import com.sun.tools.javac.tree.JCTree.JCDeconstructionPattern;
 import com.sun.tools.javac.tree.JCTree.JCDoWhileLoop;
 import com.sun.tools.javac.tree.JCTree.JCEnhancedForLoop;
 import com.sun.tools.javac.tree.JCTree.JCErroneous;
@@ -266,6 +267,14 @@ public void visitBindingPattern(JCBindingPattern tree) {
         equiv.put(tree.symbol, that.symbol);
     }
 
+    @Override
+    public void visitDeconstructionPattern(JCTree.JCDeconstructionPattern tree) {
+        JCDeconstructionPattern that = (JCDeconstructionPattern) parameter;
+        result =
+                scan(tree.deconstructor, that.deconstructor)
+                        && scan(tree.nested, that.nested);
+    }
+
     @Override
     public void visitBlock(JCBlock tree) {
         JCBlock that = (JCBlock) parameter;
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
index c4dd360812d..c4098479b59 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
@@ -144,6 +144,9 @@ public class ClassWriter extends ClassFile {
     /** Access to files. */
     private final JavaFileManager fileManager;
 
+    /** The symbol table. */
+    private final Symtab syms;
+
     /** The tags and constants used in compressed stackmap. */
     static final int SAME_FRAME_SIZE = 64;
     static final int SAME_LOCALS_1_STACK_ITEM_EXTENDED = 247;
@@ -182,6 +185,8 @@ protected ClassWriter(Context context) {
         emitSourceFile = options.isUnset(G_CUSTOM) ||
                             options.isSet(G_CUSTOM, "source");
 
+        syms = Symtab.instance(context);
+
         String modifierFlags = options.get("debug.dumpmodifiers");
         if (modifierFlags != null) {
             dumpClassModifiers = modifierFlags.indexOf('c') != -1;
@@ -328,7 +333,7 @@ protected int writeEnclosingMethodAttribute(Name attributeName, ClassSymbol c) {
         int alenIdx = writeAttr(attributeName);
         ClassSymbol enclClass = c.owner.enclClass();
         MethodSymbol enclMethod =
-            (c.owner.type == null // local to init block
+            (c.owner.type == syms.blockScopeMethodType // local to init block
              || c.owner.kind != MTH) // or member init
             ? null
             : ((MethodSymbol)c.owner).originalEnclosingMethod();
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java
index 94809475200..440df2a35fa 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/DocCommentParser.java
@@ -248,7 +248,7 @@ protected List<DCTree> blockContent(Phase phase) {
      */
     protected List<DCTree> blockTags() {
         ListBuffer<DCTree> tags = new ListBuffer<>();
-        while (ch == '@')
+        while (bp < buflen && ch == '@')
             tags.add(blockTag());
         return tags.toList();
     }
@@ -354,7 +354,7 @@ private enum WhitespaceRetentionPolicy {
      * Matching pairs of { } are skipped; the text is terminated by the first
      * unmatched }. It is an error if the beginning of the next tag is detected.
      */
-    private DCTree inlineText(WhitespaceRetentionPolicy whitespacePolicy) throws ParseException {
+    private DCText inlineText(WhitespaceRetentionPolicy whitespacePolicy) throws ParseException {
         switch (whitespacePolicy) {
             case REMOVE_ALL:
                 skipWhitespace();
@@ -663,14 +663,14 @@ protected DCTree entity() {
             nextChar();
             if (isDecimalDigit(ch)) {
                 nextChar();
-                while (isDecimalDigit(ch))
+                while (bp < buflen && isDecimalDigit(ch))
                     nextChar();
                 name = names.fromChars(buf, namep, bp - namep);
             } else if (ch == 'x' || ch == 'X') {
                 nextChar();
                 if (isHexDigit(ch)) {
                     nextChar();
-                    while (isHexDigit(ch))
+                    while (bp < buflen && isHexDigit(ch))
                         nextChar();
                     name = names.fromChars(buf, namep, bp - namep);
                 }
@@ -843,7 +843,7 @@ private DCTree html() {
                     nextChar();
                     while (bp < buflen) {
                         int dash = 0;
-                        while (ch == '-') {
+                        while (bp < buflen && ch == '-') {
                             dash++;
                             nextChar();
                         }
@@ -890,7 +890,7 @@ protected List<DCTree> htmlAttrs() {
         skipWhitespace();
 
         loop:
-        while (isIdentifierStart(ch)) {
+        while (bp < buflen && isIdentifierStart(ch)) {
             int namePos = bp;
             Name name = readAttributeName();
             skipWhitespace();
@@ -1057,7 +1057,7 @@ protected boolean isWhitespace(char ch) {
     }
 
     protected void skipWhitespace() {
-        while (isWhitespace(ch)) {
+        while (bp < buflen && isWhitespace(ch)) {
             nextChar();
         }
     }
@@ -1118,9 +1118,9 @@ public DCTree parse(int pos) {
             new TagParser(TagParser.Kind.INLINE, DCTree.Kind.CODE, true) {
                 @Override
                 public DCTree parse(int pos) throws ParseException {
-                    DCTree text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
+                    DCText text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
                     nextChar();
-                    return m.at(pos).newCodeTree((DCText) text);
+                    return m.at(pos).newCodeTree(text);
                 }
             },
 
@@ -1228,9 +1228,9 @@ public DCTree parse(int pos) throws ParseException {
             new TagParser(TagParser.Kind.INLINE, DCTree.Kind.LITERAL, true) {
                 @Override
                 public DCTree parse(int pos) throws ParseException {
-                    DCTree text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
+                    DCText text = inlineText(WhitespaceRetentionPolicy.REMOVE_FIRST_SPACE);
                     nextChar();
-                    return m.at(pos).newLiteralTree((DCText) text);
+                    return m.at(pos).newLiteralTree(text);
                 }
             },
 
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
index 4ffef19e081..49896495506 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -239,6 +239,7 @@ protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFact
      *     mode = NOPARAMS    : no parameters allowed for type
      *     mode = TYPEARG     : type argument
      *     mode |= NOLAMBDA   : lambdas are not allowed
+     *     mode |= NOINVOCATION : method invocations are not allowed
      */
     protected static final int EXPR = 0x1;
     protected static final int TYPE = 0x2;
@@ -246,13 +247,14 @@ protected DocCommentTable newDocCommentTable(boolean keepDocComments, ParserFact
     protected static final int TYPEARG = 0x8;
     protected static final int DIAMOND = 0x10;
     protected static final int NOLAMBDA = 0x20;
+    protected static final int NOINVOCATION = 0x40;
 
     protected void selectExprMode() {
-        mode = (mode & NOLAMBDA) | EXPR;
+        mode = (mode & (NOLAMBDA | NOINVOCATION)) | EXPR;
     }
 
     protected void selectTypeMode() {
-        mode = (mode & NOLAMBDA) | TYPE;
+        mode = (mode & (NOLAMBDA|NOINVOCATION)) | TYPE;
     }
 
     /** The current mode.
@@ -564,10 +566,14 @@ public int getEndPos(JCTree tree) {
      * Ident = IDENTIFIER
      */
     public Name ident() {
-        return ident(false);
+        return ident(false, false);
     }
 
     protected Name ident(boolean advanceOnErrors) {
+        return ident(advanceOnErrors, false);
+    }
+
+    protected Name ident(boolean advanceOnErrors, boolean underscoreAllowed) {
         if (token.kind == IDENTIFIER) {
             Name name = token.name();
             nextToken();
@@ -593,10 +599,16 @@ protected Name ident(boolean advanceOnErrors) {
                 return names.error;
             }
         } else if (token.kind == UNDERSCORE) {
-            if (Feature.UNDERSCORE_IDENTIFIER.allowedInSource(source)) {
-                log.warning(token.pos, Warnings.UnderscoreAsIdentifier);
-            } else {
-                log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.UnderscoreAsIdentifier);
+            if (!underscoreAllowed) {
+                if (Feature.UNDERSCORE_AS_PARAM_NAME.allowedInSource(source)) {
+                    log.error(token.pos, Errors.UnderscoreNotAllowed);
+                } else {
+                    if (Feature.UNDERSCORE_IDENTIFIER.allowedInSource(source)) {
+                        log.warning(token.pos, Warnings.UnderscoreAsIdentifier);
+                    } else {
+                        log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.UnderscoreAsIdentifier);
+                    }
+                }
             }
             Name name = token.name();
             nextToken();
@@ -614,7 +626,11 @@ protected Name ident(boolean advanceOnErrors) {
      * Qualident = Ident { DOT [Annotations] Ident }
      */
     public JCExpression qualident(boolean allowAnnos) {
-        JCExpression t = toP(F.at(token.pos).Ident(ident()));
+        return qualident(allowAnnos, false);
+    }
+
+    public JCExpression qualident(boolean allowAnnos, boolean underscoreAllowed) {
+        JCExpression t = toP(F.at(token.pos).Ident(ident(false, underscoreAllowed)));
         while (token.kind == DOT) {
             int pos = token.pos;
             nextToken();
@@ -754,6 +770,31 @@ public JCExpression parseExpression() {
         return term(EXPR);
     }
 
+    /** parses patterns.
+     */
+
+    public JCPattern parsePattern() {
+        int pos = token.pos;
+        if (token.kind == IDENTIFIER && token.name() == names.var) {
+            nextToken();
+            return toP(F.at(pos).BindingPattern(ident(), null));
+        } else {
+            JCExpression e = term(EXPR | TYPE | NOLAMBDA | NOINVOCATION);
+            if (token.kind == LPAREN) {
+                ListBuffer<JCPattern> nested = new ListBuffer<>();
+                do {
+                    nextToken();
+                    JCPattern nestedPattern = parsePattern();
+                    nested.append(nestedPattern);
+                } while (token.kind == COMMA);
+                accept(RPAREN);
+                return toP(F.at(pos).DeconstructionPattern(e, nested.toList()));
+            } else {
+                return toP(F.at(pos).BindingPattern(ident(), e));
+            }
+        }
+    }
+
     /**
      * parses (optional) type annotations followed by a type. If the
      * annotations are present before the type and are not consumed during array
@@ -936,6 +977,16 @@ JCExpression term2Rest(JCExpression t, int minprec) {
                 if (token.kind == IDENTIFIER) {
                     checkSourceLevel(token.pos, Feature.PATTERN_MATCHING_IN_INSTANCEOF);
                     pattern = toP(F.at(token.pos).BindingPattern(ident(), pattern));
+                } else if (token.kind == LPAREN) {
+                    checkSourceLevel(Feature.DECONSTRUCTION_PATTERNS);
+                    ListBuffer<JCPattern> nested = new ListBuffer<>();
+                    do {
+                        nextToken();
+                        JCPattern nestedPattern = parsePattern();
+                        nested.append(nestedPattern);
+                    } while (token.kind == COMMA);
+                    accept(RPAREN);
+                    pattern = toP(F.at(pattern).DeconstructionPattern((JCExpression) pattern, nested.toList()));
                 }
                 odStack[top] = F.at(pos).TypeTest(odStack[top], pattern);
             } else {
@@ -1265,7 +1316,7 @@ protected JCExpression term3() {
                         }
                         break loop;
                     case LPAREN:
-                        if ((mode & EXPR) != 0) {
+                        if ((mode & EXPR) != 0 && (mode & NOINVOCATION) == 0) {
                             selectExprMode();
                             t = arguments(typeArgs, t);
                             if (!annos.isEmpty()) t = illegal(annos.head.pos);
@@ -1795,7 +1846,7 @@ enum ParensResult {
 
     JCExpression lambdaExpressionOrStatement(boolean hasParens, boolean explicitParams, int pos) {
         List<JCVariableDecl> params = explicitParams ?
-                formalParameters(true, false) :
+                formalParameters(FormalParameterKind.LAMBDA) :
                 implicitParameters(hasParens);
         if (explicitParams) {
             LambdaClassifier lambdaClassifier = new LambdaClassifier();
@@ -2873,7 +2924,7 @@ protected JCCatch catchClause() {
         JCExpression paramType = catchTypes.size() > 1 ?
                 toP(F.at(catchTypes.head.getStartPosition()).TypeUnion(catchTypes)) :
                 catchTypes.head;
-        JCVariableDecl formal = variableDeclaratorId(mods, paramType);
+        JCVariableDecl formal = variableDeclaratorId(mods, paramType, FormalParameterKind.CATCH);
         accept(RPAREN);
         JCBlock body = block();
         return F.at(pos).Catch(formal, body);
@@ -3370,26 +3421,61 @@ Source restrictedTypeNameStartingAtSource(Name name, int pos, boolean shouldWarn
         return null;
     }
 
+    /** The kind of a formal parameter
+     */
+    enum FormalParameterKind {
+        /* a formal lambda parameter
+         */
+        LAMBDA {
+            @Override
+            boolean isLambdaParameter() {
+                return true;
+            }
+        },
+        /* a formal catch clause parameter
+         */
+        CATCH,
+        /* a formal method parameter
+         */
+        METHOD,
+        /* a formal record parameter
+         */
+        RECORD;
+
+        boolean isLambdaParameter() {
+            return false;
+        }
+        boolean isRecordParameter() {
+            return false;
+        }
+    }
+
     /** VariableDeclaratorId = Ident BracketsOpt
      */
     JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) {
-        return variableDeclaratorId(mods, type, false, false);
+        return variableDeclaratorId(mods, type, FormalParameterKind.METHOD);
     }
-    //where
-    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean lambdaParameter, boolean recordComponent) {
+
+    JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, FormalParameterKind parameterKind) {
         int pos = token.pos;
         Name name;
-        if (lambdaParameter && token.kind == UNDERSCORE) {
+        boolean allowUnderscoreAsFormal = Feature.UNDERSCORE_AS_PARAM_NAME.allowedInSource(source);
+        boolean isUnderscore = token.kind == UNDERSCORE;
+        if (parameterKind.isLambdaParameter() && isUnderscore && !allowUnderscoreAsFormal) {
             log.error(pos, Errors.UnderscoreAsIdentifierInLambda);
             name = token.name();
             nextToken();
+        } else if (parameterKind == FormalParameterKind.METHOD && isUnderscore && allowUnderscoreAsFormal) {
+            log.error(pos, Errors.UnderscoreAsIdentifierInMethod);
+            name = token.name();
+            nextToken();
         } else {
             if (allowThisIdent ||
-                !lambdaParameter ||
+                parameterKind != FormalParameterKind.LAMBDA ||
                 LAX_IDENTIFIER.accepts(token.kind) ||
                 mods.flags != Flags.PARAMETER ||
                 mods.annotations.nonEmpty()) {
-                JCExpression pn = qualident(false);
+                JCExpression pn = qualident(false, allowUnderscoreAsFormal);
                 if (pn.hasTag(Tag.IDENT) && ((JCIdent)pn).name != names._this) {
                     name = ((JCIdent)pn).name;
                 } else {
@@ -3421,12 +3507,16 @@ JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type, boolean
                 token.kind == LBRACKET) {
             log.error(token.pos, Errors.VarargsAndOldArraySyntax);
         }
-        if (recordComponent && token.kind == LBRACKET) {
+        if (parameterKind == FormalParameterKind.RECORD && token.kind == LBRACKET) {
             log.error(token.pos, Errors.RecordComponentAndOldArraySyntax);
         }
-        type = bracketsOpt(type);
 
-        return toP(F.at(pos).VarDef(mods, name, type, null));
+        int dimensionsPos = token.pos;
+        JCExpression typeWithDimensions = bracketsOpt(type);
+        if (allowUnderscoreAsFormal && isUnderscore && typeWithDimensions != type) {
+            log.error(dimensionsPos, Errors.UnderscoreCantBeFollowedByDimensions);
+        }
+        return toP(F.at(pos).VarDef(mods, name, typeWithDimensions, null));
     }
 
     /** Resources = Resource { ";" Resources }
@@ -3780,7 +3870,7 @@ protected JCClassDecl recordDeclaration(JCModifiers mods, Comment dc) {
 
         List<JCTypeParameter> typarams = typeParametersOpt();
 
-        List<JCVariableDecl> headerFields = formalParameters(false, true);
+        List<JCVariableDecl> headerFields = formalParameters(FormalParameterKind.RECORD);
 
         List<JCExpression> implementing = List.nil();
         if (token.kind == IMPLEMENTS) {
@@ -4256,11 +4346,19 @@ protected boolean isSealedClassStart(boolean local) {
     private boolean allowedAfterSealedOrNonSealed(Token next, boolean local, boolean currentIsNonSealed) {
         return local ?
             switch (next.kind) {
-                case MONKEYS_AT, ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
+                case MONKEYS_AT -> {
+                    Token afterNext = S.token(2);
+                    yield afterNext.kind != INTERFACE || currentIsNonSealed;
+                }
+                case ABSTRACT, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
                 default -> false;
             } :
             switch (next.kind) {
-                case MONKEYS_AT, PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
+                case MONKEYS_AT -> {
+                    Token afterNext = S.token(2);
+                    yield afterNext.kind != INTERFACE || currentIsNonSealed;
+                }
+                case PUBLIC, PROTECTED, PRIVATE, ABSTRACT, STATIC, FINAL, STRICTFP, CLASS, INTERFACE, ENUM -> true;
                 case IDENTIFIER -> isNonSealedIdentifier(next, currentIsNonSealed ? 3 : 1) || next.name() == names.sealed;
                 default -> false;
             };
@@ -4296,7 +4394,7 @@ protected JCTree methodDeclaratorRest(int pos,
             List<JCVariableDecl> params = List.nil();
             List<JCExpression> thrown = List.nil();
             if (!isRecord || name != names.init || token.kind == LPAREN) {
-                params = formalParameters();
+                params = formalParameters(FormalParameterKind.METHOD);
                 if (!isVoid) type = bracketsOpt(type);
                 if (token.kind == THROWS) {
                     nextToken();
@@ -4412,16 +4510,13 @@ JCTypeParameter typeParameter() {
      *  FormalParameterList = [ FormalParameterListNovarargs , ] LastFormalParameter
      *  FormalParameterListNovarargs = [ FormalParameterListNovarargs , ] FormalParameter
      */
-    List<JCVariableDecl> formalParameters() {
-        return formalParameters(false, false);
-    }
-    List<JCVariableDecl> formalParameters(boolean lambdaParameters, boolean recordComponents) {
+    List<JCVariableDecl> formalParameters(FormalParameterKind parameterKind) {
         ListBuffer<JCVariableDecl> params = new ListBuffer<>();
         JCVariableDecl lastParam;
         accept(LPAREN);
         if (token.kind != RPAREN) {
-            this.allowThisIdent = !lambdaParameters && !recordComponents;
-            lastParam = formalParameter(lambdaParameters, recordComponents);
+            this.allowThisIdent = parameterKind != FormalParameterKind.LAMBDA && parameterKind != FormalParameterKind.RECORD;
+            lastParam = formalParameter(parameterKind);
             if (lastParam.nameexpr != null) {
                 this.receiverParam = lastParam;
             } else {
@@ -4433,7 +4528,7 @@ List<JCVariableDecl> formalParameters(boolean lambdaParameters, boolean recordCo
                     log.error(DiagnosticFlag.SYNTAX, lastParam, Errors.VarargsMustBeLast);
                 }
                 nextToken();
-                params.append(lastParam = formalParameter(lambdaParameters, recordComponents));
+                params.append(lastParam = formalParameter(parameterKind));
             }
         }
         if (token.kind == RPAREN) {
@@ -4544,18 +4639,18 @@ private JCExpression insertAnnotationsToMostInner(
     /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
      *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
      */
-    protected JCVariableDecl formalParameter(boolean lambdaParameter, boolean recordComponent) {
-        JCModifiers mods = !recordComponent ? optFinal(Flags.PARAMETER) : modifiersOpt();
-        if (recordComponent && mods.flags != 0) {
+    protected JCVariableDecl formalParameter(FormalParameterKind parameterKind) {
+        JCModifiers mods = parameterKind != FormalParameterKind.RECORD ? optFinal(Flags.PARAMETER) : modifiersOpt();
+        if (parameterKind == FormalParameterKind.RECORD && mods.flags != 0) {
             log.error(mods.pos, Errors.RecordCantDeclareFieldModifiers);
         }
-        if (recordComponent) {
+        if (parameterKind == FormalParameterKind.RECORD) {
             mods.flags |= Flags.RECORD | Flags.FINAL | Flags.PRIVATE | Flags.GENERATED_MEMBER;
         }
         // need to distinguish between vararg annos and array annos
         // look at typeAnnotationsPushedBack comment
         this.permitTypeAnnotationsPushBack = true;
-        JCExpression type = parseType(lambdaParameter);
+        JCExpression type = parseType(parameterKind == FormalParameterKind.LAMBDA);
         this.permitTypeAnnotationsPushBack = false;
 
         if (token.kind == ELLIPSIS) {
@@ -4572,12 +4667,12 @@ protected JCVariableDecl formalParameter(boolean lambdaParameter, boolean record
             }
             typeAnnotationsPushedBack = List.nil();
         }
-        return variableDeclaratorId(mods, type, lambdaParameter, recordComponent);
+        return variableDeclaratorId(mods, type, parameterKind);
     }
 
     protected JCVariableDecl implicitParameter() {
         JCModifiers mods = F.at(token.pos).Modifiers(Flags.PARAMETER);
-        return variableDeclaratorId(mods, null, true, false);
+        return variableDeclaratorId(mods, null, FormalParameterKind.LAMBDA);
     }
 
 /* ---------- auxiliary methods -------------- */
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
index 01edf5eb90a..3acebee5cdd 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -2944,6 +2944,9 @@ compiler.misc.feature.pattern.matching.instanceof=\
 compiler.misc.feature.reifiable.types.instanceof=\
     reifiable types in instanceof
 
+compiler.misc.feature.deconstruction.patterns=\
+    deconstruction patterns
+
 compiler.misc.feature.records=\
     records
 
@@ -2956,10 +2959,20 @@ compiler.warn.underscore.as.identifier=\
 compiler.err.underscore.as.identifier=\
     as of release 9, ''_'' is a keyword, and may not be used as an identifier
 
+compiler.err.underscore.not.allowed=\
+    as of release 10, '_' can only be used as an unused formal parameter.
+
+compiler.err.underscore.cant.be.followed.by.dimensions=\
+    parameter name ''_'' cannot be followed by dimensions
+
 compiler.err.underscore.as.identifier.in.lambda=\
     ''_'' used as an identifier\n\
     (use of ''_'' as an identifier is forbidden for lambda parameters)
 
+compiler.err.underscore.as.identifier.in.method=\
+    ''_'' used as an identifier\n\
+    (use of ''_'' as an identifier is forbidden for method parameters)
+
 compiler.err.enum.as.identifier=\
     as of release 5, ''enum'' is a keyword, and may not be used as an identifier
 
@@ -3742,3 +3755,13 @@ compiler.err.preview.not.latest=\
 
 compiler.err.preview.without.source.or.release=\
     --enable-preview must be used with either -source or --release
+
+# 0: symbol
+compiler.err.deconstruction.pattern.only.records=\
+    deconstruction patterns can only be applied to records, {0} is not a record
+
+# 0: list of type, 1: list of type
+compiler.err.incorrect.number.of.nested.patterns=\
+    incorrect number of nested patterns\n\
+    required: {0}\n\
+    found: {1}
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java
index 7a237840852..b786f4cfd51 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/DocTreeMaker.java
@@ -161,14 +161,14 @@ public DocTreeMaker at(DiagnosticPosition pos) {
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
-    public DCAttribute newAttributeTree(javax.lang.model.element.Name name, ValueKind vkind, java.util.List<? extends DocTree> value) {
+    public DCAttribute newAttributeTree(Name name, ValueKind vkind, List<? extends DocTree> value) {
         DCAttribute tree = new DCAttribute(name, vkind, cast(value));
         tree.pos = pos;
         return tree;
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
-    public DCAuthor newAuthorTree(java.util.List<? extends DocTree> name) {
+    public DCAuthor newAuthorTree(List<? extends DocTree> name) {
         DCAuthor tree = new DCAuthor(cast(name));
         tree.pos = pos;
         return tree;
@@ -197,11 +197,7 @@ public DCDeprecated newDeprecatedTree(List<? extends DocTree> text) {
 
     @Override @DefinedBy(Api.COMPILER_TREE)
     public DCDocComment newDocCommentTree(List<? extends DocTree> fullBody, List<? extends DocTree> tags) {
-        Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody);
-        List<DCTree> preamble = Collections.emptyList();
-        List<DCTree> postamble = Collections.emptyList();
-
-        return newDocCommentTree(fullBody, tags, preamble, postamble);
+        return newDocCommentTree(fullBody, tags, Collections.emptyList(), Collections.emptyList());
     }
 
     public DCDocComment newDocCommentTree(Comment comment,
@@ -503,7 +499,7 @@ public DCVersion newVersionTree(List<? extends DocTree> text) {
     }
 
     @Override @DefinedBy(Api.COMPILER_TREE)
-    public java.util.List<DocTree> getFirstSentence(java.util.List<? extends DocTree> list) {
+    public List<DocTree> getFirstSentence(List<? extends DocTree> list) {
         Pair<List<DCTree>, List<DCTree>> pair = splitBody(list);
         return new ArrayList<>(pair.fst);
     }
@@ -693,7 +689,7 @@ private int getSentenceBreak(String s, DocTree dt) {
         return -1; // indeterminate at this time
     }
 
-    private boolean isSentenceBreak(javax.lang.model.element.Name tagName) {
+    private boolean isSentenceBreak(Name tagName) {
         return sentenceBreakTags.contains(get(tagName));
     }
 
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java
index 743f46af459..019a94925bf 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java
@@ -241,6 +241,8 @@ public enum Tag {
          */
         BINDINGPATTERN,
 
+        DECONSTRUCTIONPATTERN,
+
         /** Indexed array expressions, of type Indexed.
          */
         INDEXED,
@@ -2237,6 +2239,55 @@ public Tag getTag() {
         }
     }
 
+    public static class JCDeconstructionPattern extends JCPattern
+            implements DeconstructionPatternTree {
+        public JCExpression deconstructor;
+        public List<JCPattern> nested;
+        public ClassSymbol record;
+        public List<Type> innerTypes;
+
+        protected JCDeconstructionPattern(JCExpression deconstructor, List<JCPattern> nested) {
+            this.deconstructor = deconstructor;
+            this.nested = nested;
+        }
+
+        @DefinedBy(Api.COMPILER_TREE)
+        public Name getBinding() {
+            return null;
+        }
+
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        public Tree getDeconstructor() {
+            return deconstructor;
+        }
+
+        @Override @DefinedBy(Api.COMPILER_TREE)
+        public List<? extends JCPattern> getNestedPatterns() {
+            return nested;
+        }
+
+        @Override
+        public void accept(Visitor v) {
+            v.visitDeconstructionPattern(this);
+        }
+
+        @DefinedBy(Api.COMPILER_TREE)
+        public Kind getKind() {
+            return Kind.DECONSTRUCTION_PATTERN;
+        }
+
+        @Override
+        @DefinedBy(Api.COMPILER_TREE)
+        public <R, D> R accept(TreeVisitor<R, D> v, D d) {
+            return v.visitDeconstructionPattern(this, d);
+        }
+
+        @Override
+        public Tag getTag() {
+            return DECONSTRUCTIONPATTERN;
+        }
+    }
+
     /**
      * An array selection
      */
@@ -3277,6 +3328,7 @@ public static abstract class Visitor {
         public void visitTypeCast(JCTypeCast that)           { visitTree(that); }
         public void visitTypeTest(JCInstanceOf that)         { visitTree(that); }
         public void visitBindingPattern(JCBindingPattern that) { visitTree(that); }
+        public void visitDeconstructionPattern(JCDeconstructionPattern that) { visitTree(that); }
         public void visitIndexed(JCArrayAccess that)         { visitTree(that); }
         public void visitSelect(JCFieldAccess that)          { visitTree(that); }
         public void visitReference(JCMemberReference that)   { visitTree(that); }
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java
index 48aa07d56e6..de7c1f6f663 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/Pretty.java
@@ -903,6 +903,18 @@ public void visitBindingPattern(JCBindingPattern patt) {
         }
     }
 
+    @Override
+    public void visitDeconstructionPattern(JCDeconstructionPattern tree) {
+        try {
+            printExpr(tree.deconstructor);
+            print("(");
+            printExprs(tree.nested);
+            print(")");
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
     public void visitSynchronized(JCSynchronized tree) {
         try {
             print("synchronized ");
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java
index 5c1edf76096..717216d1691 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeCopier.java
@@ -497,6 +497,14 @@ public JCTree visitBindingPattern(BindingPatternTree node, P p) {
         return M.at(t.pos).BindingPattern(t.name, vartype);
     }
 
+    @DefinedBy(Api.COMPILER_TREE)
+    public JCTree visitDeconstructionPattern(DeconstructionPatternTree node, P p) {
+        JCDeconstructionPattern t = (JCDeconstructionPattern) node;
+        JCExpression deconstructor = copy(t.deconstructor, p);
+        List<JCPattern> nested = copy(t.nested, p);
+        return M.at(t.pos).DeconstructionPattern(deconstructor, nested);
+    }
+
     @DefinedBy(Api.COMPILER_TREE)
     public JCTree visitUnary(UnaryTree node, P p) {
         JCUnary t = (JCUnary) node;
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java
index 8da7b73fbbc..13856ce7e20 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java
@@ -482,6 +482,12 @@ public JCBindingPattern BindingPattern(Name name, JCTree vartype) {
         return tree;
     }
 
+    public JCDeconstructionPattern DeconstructionPattern(JCExpression deconstructor, List<JCPattern> nested) {
+        JCDeconstructionPattern tree = new JCDeconstructionPattern(deconstructor, nested);
+        tree.pos = pos;
+        return tree;
+    }
+
     public JCArrayAccess Indexed(JCExpression indexed, JCExpression index) {
         JCArrayAccess tree = new JCArrayAccess(indexed, index);
         tree.pos = pos;
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java
index e1c2d5595c1..92aac7fd7de 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeScanner.java
@@ -308,6 +308,12 @@ public void visitBindingPattern(JCBindingPattern tree) {
             scan(tree.vartype);
     }
 
+    @Override
+    public void visitDeconstructionPattern(JCDeconstructionPattern that) {
+        scan(that.deconstructor);
+        scan(that.nested);
+    }
+
     public void visitIndexed(JCArrayAccess tree) {
         scan(tree.indexed);
         scan(tree.index);
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
index 26fea8f0e47..19d6908e9a3 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeTranslator.java
@@ -457,6 +457,13 @@ public void visitAnnotatedType(JCAnnotatedType tree) {
         result = tree;
     }
 
+    @Override
+    public void visitDeconstructionPattern(JCDeconstructionPattern tree) {
+        tree.deconstructor = translate(tree.deconstructor);
+        tree.nested = translate(tree.nested);
+        result = tree;
+    }
+
     public void visitTree(JCTree tree) {
         throw new AssertionError(tree);
     }
diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java
index 90e9c685ad7..42dd43a8158 100644
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java
@@ -186,6 +186,7 @@ public static Names instance(Context context) {
     public final Name module_info;
     public final Name package_info;
     public final Name requireNonNull;
+    public final Name underscore;
 
     // lambda-related
     public final Name lambda;
@@ -360,6 +361,7 @@ public Names(Context context) {
         module_info = fromString("module-info");
         package_info = fromString("package-info");
         requireNonNull = fromString("requireNonNull");
+        underscore = fromString("_");
 
         //lambda-related
         lambda = fromString("lambda$");
diff --git a/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java b/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java
index 9c9d36b507a..fb031ae3f77 100644
--- a/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java
+++ b/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocFormatter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,6 @@
 import com.sun.source.util.DocTreeScanner;
 import com.sun.source.util.DocTrees;
 import com.sun.source.util.JavacTask;
-import com.sun.tools.doclint.Entity;
 import com.sun.tools.doclint.HtmlTag;
 import com.sun.tools.javac.util.DefinedBy;
 import com.sun.tools.javac.util.DefinedBy.Api;
@@ -128,6 +127,7 @@ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOExcept
     private class FormatJavadocScanner extends DocTreeScanner<Object, Object> {
         private final StringBuilder result;
         private final JavacTask task;
+        private final DocTrees trees;
         private int reflownTo;
         private int indent;
         private int limit = Math.min(lineLimit, MAX_LINE_LENGTH);
@@ -137,6 +137,7 @@ private class FormatJavadocScanner extends DocTreeScanner<Object, Object> {
         public FormatJavadocScanner(StringBuilder result, JavacTask task) {
             this.result = result;
             this.task = task;
+            this.trees = DocTrees.instance(task);
         }
 
         @Override @DefinedBy(Api.COMPILER_TREE)
@@ -511,31 +512,10 @@ private void handleEndElement(Name name) {
 
         @Override @DefinedBy(Api.COMPILER_TREE)
         public Object visitEntity(EntityTree node, Object p) {
-            String name = node.getName().toString();
-            int code = -1;
-            String value = null;
-            if (name.startsWith("#")) {
-                try {
-                    int v = StringUtils.toLowerCase(name).startsWith("#x")
-                            ? Integer.parseInt(name.substring(2), 16)
-                            : Integer.parseInt(name.substring(1), 10);
-                    if (Entity.isValid(v)) {
-                        code = v;
-                    }
-                } catch (NumberFormatException ex) {
-                    //ignore
-                }
-            } else {
-                value = Entity.getValue(name);
-            }
-            if (code != (-1)) {
-                result.appendCodePoint(code);
-            } else if (value != null) {
-                result.append(value);
-            } else {
-                result.append(node.toString());
-            }
+            String value = trees.getCharacters(node);
+            result.append(value == null ? node.toString() : value);
             return super.visitEntity(node, p);
+
         }
 
         private DocTree lastNode;
diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java
index 5f34d123a4a..41c18e91f7b 100644
--- a/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java
+++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/ECDSASignature.java
@@ -46,12 +46,20 @@
  *   . "SHA256withECDSA"
  *   . "SHA384withECDSA"
  *   . "SHA512withECDSA"
+ *   . "SHA3-224withECDSA"
+ *   . "SHA3-256withECDSA"
+ *   . "SHA3-384withECDSA"
+ *   . "SHA3-512withECDSA"
  *   . "NONEwithECDSAinP1363Format"
  *   . "SHA1withECDSAinP1363Format"
  *   . "SHA224withECDSAinP1363Format"
  *   . "SHA256withECDSAinP1363Format"
  *   . "SHA384withECDSAinP1363Format"
  *   . "SHA512withECDSAinP1363Format"
+ *   . "SHA3-224withECDSAinP1363Format"
+ *   . "SHA3-256withECDSAinP1363Format"
+ *   . "SHA3-384withECDSAinP1363Format"
+ *   . "SHA3-512withECDSAinP1363Format"
  *
  * @since   1.7
  */
@@ -278,6 +286,62 @@ public SHA512inP1363Format() {
         }
     }
 
+    // Nested class for SHA3_224withECDSA signatures
+    public static final class SHA3_224 extends ECDSASignature {
+        public SHA3_224() {
+           super("SHA3-224");
+        }
+    }
+
+    // Nested class for SHA3_224withECDSAinP1363Format signatures
+    public static final class SHA3_224inP1363Format extends ECDSASignature {
+        public SHA3_224inP1363Format() {
+            super("SHA3-224", true);
+        }
+    }
+
+    // Nested class for SHA3_256withECDSA signatures
+    public static final class SHA3_256 extends ECDSASignature {
+        public SHA3_256() {
+            super("SHA3-256");
+        }
+    }
+
+    // Nested class for SHA3_256withECDSAinP1363Format signatures
+    public static final class SHA3_256inP1363Format extends ECDSASignature {
+        public SHA3_256inP1363Format() {
+            super("SHA3-256", true);
+        }
+    }
+
+    // Nested class for SHA3_384withECDSA signatures
+    public static final class SHA3_384 extends ECDSASignature {
+        public SHA3_384() {
+            super("SHA3-384");
+        }
+    }
+
+    // Nested class for SHA3_384withECDSAinP1363Format signatures
+    public static final class SHA3_384inP1363Format extends ECDSASignature {
+        public SHA3_384inP1363Format() {
+            super("SHA3-384", true);
+        }
+    }
+
+    // Nested class for SHA3_512withECDSA signatures
+    public static final class SHA3_512 extends ECDSASignature {
+        public SHA3_512() {
+            super("SHA3-512");
+        }
+    }
+
+    // Nested class for SHA3_512withECDSAinP1363Format signatures
+    public static final class SHA3_512inP1363Format extends ECDSASignature {
+        public SHA3_512inP1363Format() {
+            super("SHA3-512", true);
+        }
+    }
+
     // initialize for verification. See JCA doc
     @Override
     protected void engineInitVerify(PublicKey publicKey)
diff --git a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java
index d84ffaa815c..e5c7d404c53 100644
--- a/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java
+++ b/src/jdk.crypto.ec/share/classes/sun/security/ec/SunEC.java
@@ -157,8 +157,20 @@ public Object newInstance(Object ctrParamObj)
                     } else if (algo.equals("NONEwithECDSA")) {
                         return (inP1363? new ECDSASignature.RawinP1363Format() :
                             new ECDSASignature.Raw());
-                    }
-                } else  if (type.equals("KeyFactory")) {
+                    } else if (algo.equals("SHA3-224withECDSA")) {
+                        return (inP1363? new ECDSASignature.SHA3_224inP1363Format() :
+                            new ECDSASignature.SHA3_224());
+                    } else if (algo.equals("SHA3-256withECDSA")) {
+                        return (inP1363? new ECDSASignature.SHA3_256inP1363Format() :
+                            new ECDSASignature.SHA3_256());
+                    } else if (algo.equals("SHA3-384withECDSA")) {
+                        return (inP1363? new ECDSASignature.SHA3_384inP1363Format() :
+                            new ECDSASignature.SHA3_384());
+                    } else if (algo.equals("SHA3-512withECDSA")) {
+                        return (inP1363? new ECDSASignature.SHA3_512inP1363Format() :
+                            new ECDSASignature.SHA3_512());
+                     }
+                } else if (type.equals("KeyFactory")) {
                     if (algo.equals("EC")) {
                         return new ECKeyFactory();
                     } else if (algo.equals("XDH")) {
@@ -304,6 +316,18 @@ void putEntries() {
         putService(new ProviderServiceA(this, "Signature",
             "SHA512withECDSA", "sun.security.ec.ECDSASignature$SHA512",
             ATTRS));
+        putService(new ProviderServiceA(this, "Signature",
+            "SHA3-224withECDSA", "sun.security.ec.ECDSASignature$SHA3_224",
+            ATTRS));
+        putService(new ProviderServiceA(this, "Signature",
+            "SHA3-256withECDSA", "sun.security.ec.ECDSASignature$SHA3_256",
+            ATTRS));
+        putService(new ProviderServiceA(this, "Signature",
+            "SHA3-384withECDSA", "sun.security.ec.ECDSASignature$SHA3_384",
+            ATTRS));
+        putService(new ProviderServiceA(this, "Signature",
+            "SHA3-512withECDSA", "sun.security.ec.ECDSASignature$SHA3_512",
+            ATTRS));
 
         putService(new ProviderService(this, "Signature",
              "NONEwithECDSAinP1363Format",
@@ -324,6 +348,19 @@ void putEntries() {
             "SHA512withECDSAinP1363Format",
             "sun.security.ec.ECDSASignature$SHA512inP1363Format"));
 
+        putService(new ProviderService(this, "Signature",
+             "SHA3-224withECDSAinP1363Format",
+             "sun.security.ec.ECDSASignature$SHA3_224inP1363Format"));
+        putService(new ProviderService(this, "Signature",
+             "SHA3-256withECDSAinP1363Format",
+             "sun.security.ec.ECDSASignature$SHA3_256inP1363Format"));
+        putService(new ProviderService(this, "Signature",
+            "SHA3-384withECDSAinP1363Format",
+            "sun.security.ec.ECDSASignature$SHA3_384inP1363Format"));
+        putService(new ProviderService(this, "Signature",
+            "SHA3-512withECDSAinP1363Format",
+            "sun.security.ec.ECDSASignature$SHA3_512inP1363Format"));
+
         /*
          *  Key Pair Generator engine
          */
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectMonitor.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectMonitor.java
index 563827fe020..373db9a9868 100644
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectMonitor.java
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/ObjectMonitor.java
@@ -100,8 +100,8 @@ public int contentions() {
   }
 
   // FIXME
-  //  void*     object_addr();
-  //  void      set_object(void* obj);
+  //  oop*      object_addr();
+  //  void      set_object(oop obj);
 
   // The following four either aren't expressed as typed fields in
   // vmStructs.cpp because they aren't strongly typed in the VM, or
diff --git a/src/jdk.incubator.jpackage/linux/native/applauncher/LinuxLauncher.cpp b/src/jdk.incubator.jpackage/linux/native/applauncher/LinuxLauncher.cpp
index 43d45eba025..69d3c30ae01 100644
--- a/src/jdk.incubator.jpackage/linux/native/applauncher/LinuxLauncher.cpp
+++ b/src/jdk.incubator.jpackage/linux/native/applauncher/LinuxLauncher.cpp
@@ -44,8 +44,6 @@ size_t hash(const std::string& str) {
 }
 
 void launchApp() {
-    setlocale(LC_ALL, "en_US.utf8");
-
     const tstring launcherPath = SysInfo::getProcessModulePath();
 
     const Package ownerPackage = Package::findOwnerOfFile(launcherPath);
diff --git a/src/jdk.incubator.jpackage/macosx/native/applauncher/MacLauncher.cpp b/src/jdk.incubator.jpackage/macosx/native/applauncher/MacLauncher.cpp
index b9f8f17d5d8..3949716e514 100644
--- a/src/jdk.incubator.jpackage/macosx/native/applauncher/MacLauncher.cpp
+++ b/src/jdk.incubator.jpackage/macosx/native/applauncher/MacLauncher.cpp
@@ -67,7 +67,6 @@ void initJvmLauncher() {
 
 
 int main(int argc, char *argv[]) {
-    setlocale(LC_ALL, "en_US.utf8");
     if (jvmLauncher) {
         // This is the call from the thread spawned by JVM.
         // Skip initialization phase as we have done this already in the first
diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java
index 7a6d56e7f63..b323b69ea52 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/CompilerToVM.java
@@ -999,9 +999,9 @@ HotSpotResolvedObjectTypeImpl getResolvedJavaType(long displacement, boolean com
     /**
      * Adds phases in HotSpot JFR.
      *
-     * @see JFR.CompilerPhaseEvent#registerPhases and JFR.CompilerPhaseEvent#write
+     * @see JFR.CompilerPhaseEvent#write
      */
-    native int registerCompilerPhases(String[] phases);
+    native int registerCompilerPhase(String phaseName);
 
     /**
      * @see JFR.CompilerPhaseEvent#write
diff --git a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java
index 29fc59111df..7f6b99a2f43 100644
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/JFR.java
@@ -21,7 +21,6 @@
  * questions.
  */
 
-
 package jdk.vm.ci.hotspot;
 
 import static jdk.vm.ci.hotspot.CompilerToVM.compilerToVM;
@@ -33,8 +32,9 @@
 import jdk.vm.ci.meta.ResolvedJavaMethod;
 
 /**
- * Helper methods for interacting with the Java Flight Recorder (JFR) to register events and notify it when events occur.
- * The JFR events are defined in {see @code src/share/jfr/metadata/metadata.xml}.
+ * Helper methods for interacting with the Java Flight Recorder (JFR) to register events and notify
+ * it when events occur. The JFR events are defined in {see @code
+ * src/share/jfr/metadata/metadata.xml}.
  */
 public final class JFR {
 
@@ -60,22 +60,7 @@ public static final class CompilerPhaseEvent {
         private static final ConcurrentHashMap<String, Integer> phaseToId = new ConcurrentHashMap<>();
 
         private static int getPhaseToId(String phaseName) {
-            String[] phaseNames = { phaseName };
-            return phaseToId.computeIfAbsent(phaseName, k -> compilerToVM().registerCompilerPhases(phaseNames));
-        }
-
-        /**
-         * Registers new compiler phases with JFR. This should be called during compiler initialization.
-         *
-         * @param phaseNames compiler phase names
-         */
-        public static synchronized void registerPhases(String[] phaseNames) {
-            ArrayList<String> toProcess = new ArrayList<>(Arrays.asList(phaseNames));
-            toProcess.removeAll(phaseToId.keySet());
-            int pid = compilerToVM().registerCompilerPhases(toProcess.toArray(new String[toProcess.size()]));
-            for (String phase : toProcess) {
-                phaseToId.put(phase, pid++);
-            }
+            return phaseToId.computeIfAbsent(phaseName, k -> compilerToVM().registerCompilerPhase(phaseName));
         }
 
         /**
@@ -92,8 +77,8 @@ public static void write(long startTime, String phaseName, int compileId, int ph
     }
 
     /**
-     * Helper methods for managing JFR CompilerInlining events.
-     * The events are defined in {see @code src/share/jfr/metadata/metadata.xml}.
+     * Helper methods for managing JFR CompilerInlining events. The events are defined in {see @code
+     * src/share/jfr/metadata/metadata.xml}.
      */
     public static final class CompilerInliningEvent {
 
@@ -112,4 +97,3 @@ public static void write(int compileId, ResolvedJavaMethod caller, ResolvedJavaM
         }
     }
 }
-
diff --git a/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java b/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java
index f714e22a529..31ad7e48320 100644
--- a/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java
+++ b/src/jdk.jdi/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java
@@ -586,12 +586,14 @@ void validateAssignment(ValueContainer destination)
          */
 
         JNITypeParser destSig = new JNITypeParser(destination.signature());
-        JNITypeParser sourceSig = new JNITypeParser(type().signature());
         if (destSig.isPrimitive()) {
             throw new InvalidTypeException("Can't assign object value to primitive");
         }
-        if (destSig.isArray() && !sourceSig.isArray()) {
-            throw new InvalidTypeException("Can't assign non-array value to an array");
+        if (destSig.isArray()) {
+            JNITypeParser sourceSig = new JNITypeParser(type().signature());
+            if (!sourceSig.isArray()) {
+                throw new InvalidTypeException("Can't assign non-array value to an array");
+            }
         }
         if (destSig.isVoid()) {
             throw new InvalidTypeException("Can't assign object value to a void");
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Disassemble.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Disassemble.java
index f6fd0110592..aaa11b64c40 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Disassemble.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/tool/Disassemble.java
@@ -182,19 +182,13 @@ private List<Long> combineChunkSizes(List<Long> sizes, int maxChunks, long maxSi
         long fileSize = sizes.get(0);
         for (int i = 1; i < sizes.size(); i++) {
             long size = sizes.get(i);
-            if (fileSize + size > maxSize) {
+            if (fileSize + size > maxSize || chunks == maxChunks) {
                 reduced.add(fileSize);
                 chunks = 1;
                 fileSize = size;
                 continue;
             }
             fileSize += size;
-            if (chunks == maxChunks) {
-                reduced.add(fileSize);
-                fileSize = 0;
-                chunks = 1;
-                continue;
-            }
             chunks++;
         }
         if (fileSize != 0) {
diff --git a/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp b/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp
index 448295122bd..f143e28feee 100644
--- a/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp
+++ b/test/hotspot/gtest/metaprogramming/test_primitiveConversions.cpp
@@ -95,6 +95,51 @@ TEST(PrimitiveConversionsTest, round_trip_int) {
   EXPECT_EQ(ufive, PrimitiveConversions::cast<uint>(PrimitiveConversions::cast<UI>(ufive)));
 }
 
+TEST(PrimitiveConversionsTest, round_trip_int_constexpr) {
+  constexpr int  sfive = 5;
+  constexpr int  mfive = -5;
+  constexpr uint ufive = 5u;
+
+  typedef PrimitiveConversionsTestSupport::Signed<int>::type SI;
+  typedef PrimitiveConversionsTestSupport::Unsigned<int>::type UI;
+
+  {
+    constexpr SI i = PrimitiveConversions::cast<SI>(sfive);
+    constexpr int r = PrimitiveConversions::cast<int>(i);
+    EXPECT_EQ(sfive, r);
+  }
+
+  {
+    constexpr UI i = PrimitiveConversions::cast<UI>(sfive);
+    constexpr int r = PrimitiveConversions::cast<int>(i);
+    EXPECT_EQ(sfive, r);
+  }
+
+  {
+    constexpr SI i = PrimitiveConversions::cast<SI>(mfive);
+    constexpr int r = PrimitiveConversions::cast<int>(i);
+    EXPECT_EQ(mfive, r);
+  }
+
+  {
+    constexpr UI i = PrimitiveConversions::cast<UI>(mfive);
+    constexpr int r = PrimitiveConversions::cast<int>(i);
+    EXPECT_EQ(mfive, r);
+  }
+
+  {
+    constexpr SI i = PrimitiveConversions::cast<SI>(ufive);
+    constexpr uint r = PrimitiveConversions::cast<uint>(i);
+    EXPECT_EQ(ufive, r);
+  }
+
+  {
+    constexpr UI i = PrimitiveConversions::cast<UI>(ufive);
+    constexpr uint r = PrimitiveConversions::cast<uint>(i);
+    EXPECT_EQ(ufive, r);
+  }
+}
+
 TEST(PrimitiveConversionsTest, round_trip_float) {
   float  ffive = 5.0f;
   double dfive = 5.0;
diff --git a/test/hotspot/gtest/runtime/test_arguments.cpp b/test/hotspot/gtest/runtime/test_arguments.cpp
index b6121ba3aba..81bae6c468a 100644
--- a/test/hotspot/gtest/runtime/test_arguments.cpp
+++ b/test/hotspot/gtest/runtime/test_arguments.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -153,7 +153,7 @@ static intx calc_expected(julong small_xss_input) {
   assert(small_xss_input <= max_julong / 2, "Sanity");
 
   // Match code in arguments.cpp
-  julong julong_ret = align_up_(small_xss_input, K) / K;
+  julong julong_ret = align_up(small_xss_input, K) / K;
   assert(julong_ret <= (julong)max_intx, "Overflow: " JULONG_FORMAT, julong_ret);
   return (intx)julong_ret;
 }
diff --git a/test/hotspot/gtest/utilities/test_align.cpp b/test/hotspot/gtest/utilities/test_align.cpp
index e522acc5f01..1097dd6c4f7 100644
--- a/test/hotspot/gtest/utilities/test_align.cpp
+++ b/test/hotspot/gtest/utilities/test_align.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,21 +25,82 @@
 #include "utilities/align.hpp"
 #include "utilities/formatBuffer.hpp"
 #include "utilities/globalDefinitions.hpp"
-#include "unittest.hpp"
-
 #include <limits>
+#include "unittest.hpp"
 
 // A few arbitrarily chosen values to test the align functions on.
-static uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, uint64_t(-1)};
+static constexpr uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, uint64_t(-1)};
 
 template <typename T>
-static T max_alignment() {
+static constexpr T max_alignment() {
   T max = std::numeric_limits<T>::max();
   return max ^ (max >> 1);
 }
 
 #define log(...) SCOPED_TRACE(err_msg(__VA_ARGS__).buffer())
 
+struct StaticTestAlignmentsResult {
+  uint64_t _value;
+  uint64_t _alignment;
+  int _status;            // 0: success, > 0 indicates which failure case
+  constexpr StaticTestAlignmentsResult(uint64_t value, uint64_t alignment, int status) :
+    _value(value), _alignment(alignment), _status(status) {}
+};
+
+// Structure copied from test_alignments runtime test (below).
+template<typename T, typename A>
+static constexpr StaticTestAlignmentsResult
+static_test_alignments_aux(A alignment) {
+  using Result = StaticTestAlignmentsResult;
+
+  for ( ; alignment > 0; alignment >>= 1) {
+    for (size_t i = 0; i < ARRAY_SIZE(values); ++i) {
+      // Test align up
+      uint64_t up = align_up(values[i], alignment);
+      if (0 < up && up < uint64_t(std::numeric_limits<T>::max())) {
+        T value = T(values[i]);
+        if (align_up(uint64_t(value), alignment) != up) {
+          return Result(values[i], alignment, 1);
+        } else if (align_up(value, alignment) < value) {
+          return Result(values[i], alignment, 2);
+        }
+      }
+
+      // Test align down
+      uint64_t down = align_down(values[i], alignment);
+      if (down <= uint64_t(std::numeric_limits<T>::max())) {
+        T value = T(values[i]);
+        if (uint64_t(align_down(value, alignment)) != down) {
+          return Result(values[i], alignment, 3);
+        } else if (align_down(value, alignment) > value) {
+          return Result(values[i], alignment, 4);
+        }
+      }
+
+      // Test is aligned
+      bool is = is_aligned(values[i], alignment);
+      if (values[i] <= uint64_t(std::numeric_limits<T>::max())) {
+        T value = T(values[i]);
+        if (is_aligned(value, alignment) != is) {
+          return Result(values[i], alignment, 5);
+        }
+      }
+    }
+  }
+  return Result(T(), A(), 0);
+}
+
+template<typename T, typename A>
+static void static_test_alignments() {
+  constexpr StaticTestAlignmentsResult result
+    = static_test_alignments_aux<T>(max_alignment<A>());
+
+  EXPECT_EQ(0, result._status)
+    << "value = " << result._value
+    << ", alignment = " << result._alignment
+    << ", status = " << result._status;
+}
+
 template <typename T, typename A>
 static void test_alignments() {
   log("### Test: %c" SIZE_FORMAT " " UINT64_FORMAT " : %c" SIZE_FORMAT " " UINT64_FORMAT " ###\n",
@@ -54,7 +115,7 @@ static void test_alignments() {
       log("--- Value: " UINT64_FORMAT "\n", values[i]);
 
       // Test align up
-      const uint64_t up = align_up_(values[i], (uint64_t)alignment);
+      const uint64_t up = align_up(values[i], alignment);
       if (0 < up && up <= (uint64_t)std::numeric_limits<T>::max()) {
         log("Testing align_up:   alignment: 0x" UINT64_FORMAT_X " value: 0x" UINT64_FORMAT_X " expected: 0x" UINT64_FORMAT_X "\n", (uint64_t)alignment, values[i], up);
 
@@ -62,14 +123,12 @@ static void test_alignments() {
 
         // Check against uint64_t version
         ASSERT_EQ(align_up((uint64_t)value, alignment), up);
-        // Check inline function vs macro
-        ASSERT_EQ(align_up(value, alignment), align_up_(value, alignment));
         // Sanity check
         ASSERT_GE(align_up(value, alignment), value);
       }
 
       // Test align down
-      const uint64_t down = align_down_(values[i], (uint64_t)alignment);
+      const uint64_t down = align_down(values[i], alignment);
       if (down <= (uint64_t)std::numeric_limits<T>::max()) {
         log("Testing align_down: alignment: 0x" UINT64_FORMAT_X " value: 0x" UINT64_FORMAT_X " expected: 0x" UINT64_FORMAT_X "\n", (uint64_t)alignment, values[i], down);
 
@@ -77,14 +136,12 @@ static void test_alignments() {
 
         // Check against uint64_t version
         ASSERT_EQ((uint64_t)align_down(value, alignment), down);
-        // Check inline function vs macro
-        ASSERT_EQ(align_down(value, alignment), align_down_(value, alignment));
         // Sanity check
         ASSERT_LE(align_down(value, alignment), value);
       }
 
       // Test is aligned
-      const bool is = is_aligned_(values[i], (uint64_t)alignment);
+      const bool is = is_aligned(values[i], alignment);
       if (values[i] <= (uint64_t)std::numeric_limits<T>::max()) {
         log("Testing is_aligned: alignment: 0x" UINT64_FORMAT_X " value: 0x" UINT64_FORMAT_X " expected: %s\n", (uint64_t)alignment, values[i], is ? "true" : "false");
 
@@ -92,14 +149,14 @@ static void test_alignments() {
 
         // Check against uint64_t version
         ASSERT_EQ(is_aligned(value, alignment), is);
-        // Check inline function vs macro
-        ASSERT_EQ(is_aligned(value, alignment), is_aligned_(value, alignment));
       }
     }
   }
+
+  static_test_alignments<T, A>();
 }
 
-TEST(Align, functions_and_macros) {
+TEST(Align, alignments) {
   // Test the alignment functions with different type combinations.
 
   test_alignments<int64_t, uint8_t>();
diff --git a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp
index a920351ee78..e82eea051ae 100644
--- a/test/hotspot/gtest/utilities/test_globalDefinitions.cpp
+++ b/test/hotspot/gtest/utilities/test_globalDefinitions.cpp
@@ -23,9 +23,10 @@
 
 #include "precompiled.hpp"
 #include "runtime/os.hpp"
-#include "unittest.hpp"
 #include "utilities/align.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include <type_traits>
+#include "unittest.hpp"
 
 static ::testing::AssertionResult testPageAddress(
   const char* expected_addr_expr,
@@ -192,7 +193,7 @@ TEST(globalDefinitions, byte_size_in_exact_unit) {
 #define EXPECT_EQ_LOG2(fn, type)                                \
 {                                                               \
   int limit = sizeof (type) * BitsPerByte;                      \
-  if (IsSigned<type>::value) {                                  \
+  if (std::is_signed<type>::value) {                            \
     EXPECT_EQ(limit - 1, fn(std::numeric_limits<type>::min())); \
     EXPECT_EQ(limit - 1, fn((type)-1));                         \
     limit--;                                                    \
diff --git a/test/hotspot/gtest/utilities/test_population_count.cpp b/test/hotspot/gtest/utilities/test_population_count.cpp
index a5320817ac2..4ed6513ec13 100644
--- a/test/hotspot/gtest/utilities/test_population_count.cpp
+++ b/test/hotspot/gtest/utilities/test_population_count.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 #include "utilities/population_count.hpp"
 #include "utilities/powerOfTwo.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include <limits>
 #include "unittest.hpp"
 
 #define BITS_IN_BYTE_ARRAY_SIZE 256
@@ -51,8 +52,8 @@ const uint8_t test_popcnt_bitsInByte[BITS_IN_BYTE_ARRAY_SIZE] = {
 };
 
 template <typename T>
-void sparse() {
-  const T max_val = max_value<T>();
+static void sparse() {
+  const T max_val = std::numeric_limits<T>::max();
 
   // Step through the entire input range from a random starting point,
   // verify population_count return values against the lookup table
@@ -95,4 +96,4 @@ TEST(population_count, sparse32) {
 }
 TEST(population_count, sparse64) {
   sparse<uint64_t>();
-}
\ No newline at end of file
+}
diff --git a/test/hotspot/gtest/utilities/test_powerOfTwo.cpp b/test/hotspot/gtest/utilities/test_powerOfTwo.cpp
index 795918d144f..54802a37b7b 100644
--- a/test/hotspot/gtest/utilities/test_powerOfTwo.cpp
+++ b/test/hotspot/gtest/utilities/test_powerOfTwo.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,20 +25,57 @@
 
 #include "utilities/globalDefinitions.hpp"
 #include "utilities/powerOfTwo.hpp"
+#include <limits>
+#include <type_traits>
 #include "unittest.hpp"
 
-template <typename T> T max_pow2() {
-  T max_val = max_value<T>();
+template <typename T> static constexpr T max_pow2() {
+  T max_val = std::numeric_limits<T>::max();
   return max_val - (max_val >> 1);
 }
 
+struct StaticTestIsPowerOf2Result {
+  uint64_t _value;
+  int _status;            // 0: success, > 0 indicates which failure case
+  constexpr StaticTestIsPowerOf2Result(uint64_t value, int status) :
+    _value(value), _status(status) {}
+};
+
+// Structure copied from test_is_power_of_2 runtime test (below).
+template<typename T>
+static constexpr StaticTestIsPowerOf2Result static_test_is_power_of_2_aux(T v) {
+  using Result = StaticTestIsPowerOf2Result;
+  for ( ; v > 0; v >>= 1) {
+    if (!is_power_of_2(v)) {
+      return Result(v, 1);
+    } else if ((v > 2) && is_power_of_2(T(v - 1))) {
+      return Result(v, 2);
+    } else if ((v > 1) && is_power_of_2(T(v + 1))) {
+      return Result(v, 3);
+    }
+  }
+  return Result(v, 0);
+}
+
+template<typename T>
+static void static_test_is_power_of_2() {
+  constexpr StaticTestIsPowerOf2Result result
+    = static_test_is_power_of_2_aux(max_pow2<T>());
+
+  EXPECT_EQ(0, result._status)
+    << "value = " << result._value << ", status = " << result._status;
+}
+
 template <typename T> static void test_is_power_of_2() {
   EXPECT_FALSE(is_power_of_2(T(0)));
   EXPECT_FALSE(is_power_of_2(~T(0)));
 
-  if (IsSigned<T>::value) {
-    EXPECT_FALSE(is_power_of_2(std::numeric_limits<T>::min()));
-  }
+  static_assert(!is_power_of_2(T(0)), "");
+  static_assert(!is_power_of_2(~T(0)), "");
+
+  // Should be false regardless of whether T is signed or unsigned.
+  EXPECT_FALSE(is_power_of_2(std::numeric_limits<T>::min()));
+  static_assert(!is_power_of_2(std::numeric_limits<T>::min()), "");
 
   // Test true
   for (T i = max_pow2<T>(); i > 0; i = (i >> 1)) {
@@ -54,6 +91,8 @@ template <typename T> static void test_is_power_of_2() {
   for (T i = max_pow2<T>(); i > 1; i = (i >> 1)) {
     EXPECT_FALSE(is_power_of_2(i + 1)) << "value = " << T(i + 1);
   }
+
+  static_test_is_power_of_2<T>();
 }
 
 TEST(power_of_2, is_power_of_2) {
diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt
index 6fb0bcbde76..2cb5991b41d 100644
--- a/test/hotspot/jtreg/ProblemList.txt
+++ b/test/hotspot/jtreg/ProblemList.txt
@@ -82,6 +82,7 @@ gc/metaspace/CompressedClassSpaceSizeInJmapHeap.java 8241293 macosx-x64
 
 # :hotspot_runtime
 
+runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java 8253081 generic-all
 runtime/jni/terminatedThread/TestTerminatedThread.java 8219652 aix-ppc64
 runtime/ReservedStack/ReservedStackTest.java 8231031 generic-all
 containers/docker/TestMemoryAwareness.java 8250984 linux-5.4.0-1019-oracle
diff --git a/test/hotspot/jtreg/gc/z/TestUncommit.java b/test/hotspot/jtreg/gc/z/TestUncommit.java
index 17cb65dda6d..7b3374c2dfe 100644
--- a/test/hotspot/jtreg/gc/z/TestUncommit.java
+++ b/test/hotspot/jtreg/gc/z/TestUncommit.java
@@ -68,12 +68,12 @@ private static void reclaim() {
 
     private static void test(int objectSize) throws Exception {
         final var beforeAlloc = capacity();
+        final var timeBeforeAlloc = System.nanoTime();
 
         // Allocate memory
         log("Allocating");
         allocate(objectSize);
 
-        final var timeAfterAlloc = System.nanoTime();
         final var afterAlloc = capacity();
 
         // Reclaim memory
@@ -87,7 +87,7 @@ private static void test(int objectSize) throws Exception {
 
         log("Uncommit started");
         final var timeUncommitStart = System.nanoTime();
-        final var actualDelay = (timeUncommitStart - timeAfterAlloc) / 1_000_000;
+        final var actualDelay = (timeUncommitStart - timeBeforeAlloc) / 1_000_000;
 
         log("Waiting for uncommit to complete");
         while (capacity() > beforeAlloc) {
diff --git a/test/hotspot/jtreg/runtime/NMT/CheckForProperDetailStackTrace.java b/test/hotspot/jtreg/runtime/NMT/CheckForProperDetailStackTrace.java
index ed8709cda65..1d84f4aaf9c 100644
--- a/test/hotspot/jtreg/runtime/NMT/CheckForProperDetailStackTrace.java
+++ b/test/hotspot/jtreg/runtime/NMT/CheckForProperDetailStackTrace.java
@@ -28,12 +28,15 @@
  * @library /test/lib
  * @modules java.base/jdk.internal.misc
  *          java.management
+ * @compile ../modules/CompilerUtils.java
  * @run driver CheckForProperDetailStackTrace
  */
 
 import jdk.test.lib.Platform;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
+import java.nio.file.Path;
+import java.nio.file.Paths;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -49,6 +52,11 @@
  * through this test and update it accordingly.
  */
 public class CheckForProperDetailStackTrace {
+    private static final String TEST_SRC = System.getProperty("test.src");
+    private static final String TEST_CLASSES = System.getProperty("test.classes");
+
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
+    private static final Path MODS_DIR = Paths.get(TEST_CLASSES, "mods");
 
     /* The stack trace we look for by default. Note that :: has been replaced by .*
        to make sure it matches even if the symbol is not unmangled.
@@ -83,11 +91,24 @@ public class CheckForProperDetailStackTrace {
     private static String expectedSymbol = "locked_create_entry";
 
     public static void main(String args[]) throws Exception {
+        boolean compiled;
+        // Compile module jdk.test declaration
+        compiled = CompilerUtils.compile(
+            SRC_DIR.resolve("jdk.test"),
+            MODS_DIR.resolve("jdk.test"));
+        if (!compiled) {
+            throw new RuntimeException("Test failed to compile module jdk.test");
+        }
+
+        // If modules in the system image have been archived in CDS, they will not be
+        // created again at run time. Explicitly use an external module to make sure
+        // we have a runtime-defined ModuleEntry
         ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
             "-XX:+UnlockDiagnosticVMOptions",
             "-XX:NativeMemoryTracking=detail",
             "-XX:+PrintNMTStatistics",
-            "-version");
+            "-p", MODS_DIR.toString(),
+            "-m", "jdk.test/test.Main");
         OutputAnalyzer output = new OutputAnalyzer(pb.start());
 
         output.shouldHaveExitValue(0);
diff --git a/test/hotspot/jtreg/runtime/NMT/src/jdk.test/module-info.java b/test/hotspot/jtreg/runtime/NMT/src/jdk.test/module-info.java
new file mode 100644
index 00000000000..0afe2ab71f7
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/NMT/src/jdk.test/module-info.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+module jdk.test {
+}
diff --git a/test/hotspot/jtreg/runtime/NMT/src/jdk.test/test/Main.java b/test/hotspot/jtreg/runtime/NMT/src/jdk.test/test/Main.java
new file mode 100644
index 00000000000..52168d73b78
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/NMT/src/jdk.test/test/Main.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 test;
+
+public class Main {
+    public static void main(String[] args) throws Exception {
+        System.out.println("jdk.test/test/Main: hello");
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/PrimitiveClassMirrors.java b/test/hotspot/jtreg/runtime/cds/PrimitiveClassMirrors.java
new file mode 100644
index 00000000000..50f769cd50d
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/PrimitiveClassMirrors.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8244778
+ * @summary Make sure the archived mirrors of the primitive classes have the proper module (java.base)
+ * @requires vm.cds
+ * @library /test/lib
+ * @run driver PrimitiveClassMirrors
+ */
+
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class PrimitiveClassMirrors {
+    public static void main(String[] args) throws Exception {
+        CDSOptions opts = new CDSOptions();
+
+        CDSTestUtils.createArchiveAndCheck(opts);
+        opts.setUseVersion(false);
+        opts.addSuffix("-Xlog:cds=warning", "PrimitiveClassMirrors$TestApp");
+        OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
+        out.shouldHaveExitValue(0);
+
+        // The test should have same results if CDS is turned off
+        opts.setXShareMode("off");
+        OutputAnalyzer out2 = CDSTestUtils.runWithArchive(opts);
+        out2.shouldHaveExitValue(0);
+    }
+
+    static class TestApp {
+        public static void main(String args[]) throws Exception {
+            Class classes[] = {
+                int.class,
+                float.class,
+                double.class,
+                byte.class,
+                boolean.class,
+                char.class,
+                long.class,
+                short.class,
+                void.class,
+
+                int[].class,
+                float[].class,
+                double[].class,
+                byte[].class,
+                boolean[].class,
+                char[].class,
+                long[].class,
+                short[].class,
+            };
+
+            for (Class c : classes) {
+                test(c);
+            }
+        }
+    }
+
+    static void test(Class c) throws Exception {
+        Module m = c.getModule();
+        boolean unexpected = (m == null || !("java.base".equals(m.getName())));
+        System.out.println("Module for " + c + " = " + m + (unexpected ? " *** Error" : ""));
+        if (unexpected) {
+            throw new RuntimeException("Unexpected: " + m);
+        }
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/ServiceLoaderTest.java b/test/hotspot/jtreg/runtime/cds/ServiceLoaderTest.java
new file mode 100644
index 00000000000..efaa18b9734
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/ServiceLoaderTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8244778
+ * @summary Make sure that the ServicesCatalogs for boot/platform/app loaders are properly archived.
+ * @requires vm.cds
+ * @modules java.naming
+ * @library /test/lib
+ * @run driver ServiceLoaderTest
+ */
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.ServiceLoader;
+import java.util.spi.ToolProvider;
+import javax.naming.spi.InitialContextFactory;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.cds.CDSOptions;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class ServiceLoaderTest {
+    public static void main(String[] args) throws Exception {
+        CDSOptions opts = new CDSOptions();
+
+        CDSTestUtils.createArchiveAndCheck(opts);
+
+        // Some mach5 tiers run with -vmoptions:-Xlog:cds=debug. This would cause the outputs to mismatch.
+        // Force -Xlog:cds=warning to supress the CDS logs.
+        opts.setUseVersion(false);
+        opts.addSuffix("-showversion", "-Xlog:cds=warning", "ServiceLoaderApp");
+        OutputAnalyzer out1 = CDSTestUtils.runWithArchive(opts);
+
+        opts.setXShareMode("off");
+        OutputAnalyzer out2 = CDSTestUtils.runWithArchive(opts);
+
+        compare(out1, out2);
+    }
+
+    static void compare(OutputAnalyzer out1, OutputAnalyzer out2) {
+        String[] arr1 = splitLines(out1);
+        String[] arr2 = splitLines(out2);
+
+        int max = arr1.length > arr2.length ? arr1.length : arr2.length;
+        for (int i = 0; i < max; i++) {
+            if (i >= arr1.length) {
+                mismatch(i, "<EOF>", arr2[i]);
+            }
+            if (i >= arr2.length) {
+                mismatch(i, arr1[i], "<EOF>");
+            }
+            if (!arr1[i].equals(arr2[i])) {
+                mismatch(i, arr1[i], arr2[i]);
+            }
+        }
+    }
+
+    static String[] splitLines(OutputAnalyzer out) {
+        return out.getStdout().split("\n");
+    }
+
+    static void mismatch(int i, String s1, String s2) {
+        System.out.println("Mismatched line: " + i);
+        System.out.println("cds on : " + s1);
+        System.out.println("cds off: " + s2);
+        throw new RuntimeException("Mismatched line " + i + ": \"" + s1 + "\" vs \"" + s2 + "\"");
+    }
+}
+
+class ServiceLoaderApp {
+    public static void main(String args[]) throws Exception {
+        doTest(ToolProvider.class);
+        doTest(InitialContextFactory.class);
+    }
+
+    static void doTest(Class c) throws Exception {
+        System.out.println("============================================================");
+        System.out.println("Testing : " + c.getName());
+        System.out.println("============================================================");
+
+        print_loader("default",         ServiceLoader.load(c));
+        print_loader("null loader",     ServiceLoader.load(c, null));
+        print_loader("platform loader", ServiceLoader.load(c, ServiceLoaderApp.class.getClassLoader().getParent()));
+        print_loader("system loader",   ServiceLoader.load(c, ServiceLoaderApp.class.getClassLoader()));
+    }
+
+    static void print_loader(String testCase, ServiceLoader loader) throws Exception {
+        System.out.println("[TEST CASE] " + testCase);
+        System.out.println("[svcloader] " + asString(loader));
+        Iterator it = loader.iterator();
+        ArrayList<String> list = new ArrayList<>();
+        while (it.hasNext()) {
+            list.add(asString(it.next().toString()));
+        }
+        Collections.sort(list);
+        for (String s : list) {
+            System.out.println(s);
+        }
+    }
+
+    static String asString(Object o) {
+        String s = o.toString();
+        int n = s.indexOf("@");
+        if (n >= 0) {
+            s = s.substring(0, n);
+        }
+        return s;
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/SpecifySysLoaderProp.java b/test/hotspot/jtreg/runtime/cds/appcds/SpecifySysLoaderProp.java
index 97b23507c9b..82acc8fb3cc 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/SpecifySysLoaderProp.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/SpecifySysLoaderProp.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,6 +72,7 @@ public static void main(String[] args) throws Exception {
     TestCommon.run(
         "-verbose:class",
         "-cp", appJar,
+        "-Xlog:cds",
         "-Djava.system.class.loader=TestClassLoader",
         "ReportMyLoader")
       .assertNormalExit("ReportMyLoader's loader = jdk.internal.loader.ClassLoaders$AppClassLoader@", //<-this is still printed because TestClassLoader simply delegates to Launcher$AppLoader, but ...
@@ -80,6 +81,7 @@ public static void main(String[] args) throws Exception {
       .assertNormalExit(output -> {
         output.shouldMatch(".class,load. TestClassLoader source: file:");
         output.shouldMatch(".class,load. ReportMyLoader source: file:.*" + jarFileName);
+        output.shouldContain("full module graph: disabled due to incompatible property: java.system.class.loader=");
         });
 
     // (3) Try to change the java.system.class.loader programmatically after
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/NewModuleFinderTest.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/NewModuleFinderTest.java
new file mode 100644
index 00000000000..93c50b2a459
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/NewModuleFinderTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8244778
+ * @requires vm.cds
+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
+ * @run driver NewModuleFinderTest
+ * @summary Make sure the archived module graph can co-exist with modules that are
+ *          dynamically defined at runtime using the ModuleFinder API.
+ */
+
+import java.lang.module.Configuration;
+import java.lang.module.ModuleFinder;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Set;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class NewModuleFinderTest {
+
+    private static final Path USER_DIR = Paths.get(System.getProperty("user.dir"));
+    private static final String TEST_SRC = System.getProperty("test.src");
+    private static final Path SRC_DIR = Paths.get(TEST_SRC, "modulepath/src");
+    private static final Path MODS_DIR = Paths.get("mods");
+
+    // the module name of the test module
+    private static final String TEST_MODULE = "com.simple";
+
+    // the module main class
+    private static final String MAIN_CLASS = "com.simple.Main";
+
+    private static final Set<String> modules = Set.of(TEST_MODULE);
+
+    public static void buildTestModule() throws Exception {
+        // javac -d mods/$TESTMODULE --module-path MOD_DIR modulepath/src/$TESTMODULE/**
+        JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE),
+                                 MODS_DIR.resolve(TEST_MODULE),
+                                 MODS_DIR.toString());
+    }
+
+    public static void main(String... args) throws Exception {
+        // compile the modules and create the modular jar files
+        buildTestModule();
+
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-Xlog:cds",
+            "-Xlog:module=debug",
+            "NewModuleFinderTest$Helper");
+        OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "exec");
+        out.shouldHaveExitValue(0);
+        out.shouldContain("define_module(): creation of module: com.simple,");
+    }
+
+    static class Helper {
+        public static void main(String... args) {
+            ModuleFinder finder = ModuleFinder.of(MODS_DIR);
+            Configuration parent = ModuleLayer.boot().configuration();
+            Configuration cf = parent.resolveAndBind(ModuleFinder.of(),
+                                                     finder,
+                                                     modules);
+
+            ClassLoader scl = ClassLoader.getSystemClassLoader();
+            ModuleLayer layer = ModuleLayer.boot().defineModulesWithManyLoaders(cf, scl);
+
+            Module m1 = layer.findModule(TEST_MODULE).get();
+            System.out.println("Module = " + m1);
+            if (m1 != null) {
+                System.out.println("Success");
+            } else {
+                throw new RuntimeException("Module should not be null");
+            }
+        }
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraph.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraph.java
new file mode 100644
index 00000000000..c42b922b340
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraph.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8249276
+ * @summary Make sure that archived module graph is not loaded if critical classes have been redefined.
+ * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
+ * @requires vm.cds
+ * @requires vm.flavor != "minimal"
+ * @modules java.instrument
+ * @run driver RedefineClassesInModuleGraph
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class RedefineClassesInModuleGraph {
+    public static String appClasses[] = {
+        RedefineClassesInModuleGraphApp.class.getName(),
+    };
+    public static String agentClasses[] = {
+        RedefineClassesInModuleGraphAgent.class.getName(),
+        RedefineClassesInModuleGraphTransformer.class.getName(),
+    };
+
+    private static final String MANIFEST =
+        "Manifest-Version: 1.0\n" +
+        "Premain-Class: RedefineClassesInModuleGraphAgent\n" +
+        "Can-Retransform-Classes: true\n" +
+        "Can-Redefine-Classes: true\n";
+
+    public static void main(String[] args) throws Throwable {
+        String agentJar =
+            ClassFileInstaller.writeJar("RedefineClassesInModuleGraphAgent.jar",
+                                        ClassFileInstaller.Manifest.fromString(MANIFEST),
+                                        agentClasses);
+
+        String appJar =
+            ClassFileInstaller.writeJar("RedefineClassesInModuleGraphApp.jar", appClasses);
+
+        TestCommon.testDump(appJar, agentClasses);
+
+        TestCommon.run(
+            "-cp", appJar,
+            "-javaagent:" + agentJar,
+            RedefineClassesInModuleGraphApp.class.getName())
+          .assertNormalExit();
+    }
+}
+
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraphAgent.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraphAgent.java
new file mode 100644
index 00000000000..f4a6d38a8fb
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraphAgent.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.lang.instrument.Instrumentation;
+
+public class RedefineClassesInModuleGraphAgent {
+    private static Instrumentation savedInstrumentation;
+
+    public static void premain(String agentArguments, Instrumentation instrumentation) {
+        instrumentation.addTransformer(new RedefineClassesInModuleGraphTransformer(), /*canRetransform=*/true);
+        savedInstrumentation = instrumentation;
+    }
+
+    public static Instrumentation getInstrumentation() {
+        return savedInstrumentation;
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraphApp.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraphApp.java
new file mode 100644
index 00000000000..0cc54d1f1e8
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraphApp.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 RedefineClassesInModuleGraphApp {
+    public static void main(String args[]) {
+        Module m = Object.class.getModule();
+        ModuleLayer ml = m.getLayer();
+        System.out.println(m);
+        System.out.println(ml);
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraphTransformer.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraphTransformer.java
new file mode 100644
index 00000000000..1b77f69c38c
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraphTransformer.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.security.ProtectionDomain;
+
+public class RedefineClassesInModuleGraphTransformer implements ClassFileTransformer {
+    public byte[] transform(ClassLoader loader, String name, Class<?> classBeingRedefined,
+                            ProtectionDomain pd, byte[] buffer) throws IllegalClassFormatException {
+        System.out.println("transforming " + name);
+
+        if (name.equals("java/lang/Module")  ||
+            name.equals("java/lang/ModuleLayer")  ||
+            name.equals("java/lang/module/ResolvedModule")) {
+            throw new RuntimeException("Classes used by the module graph should never be transformed by Java agent");
+        }
+        return null;
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java
index 836f0d444e6..f16982c7b1e 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java
@@ -24,7 +24,7 @@
 
 /**
  * @test
- * @requires vm.cds & !vm.jvmci
+ * @requires vm.cds & !vm.graal.enabled
  * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds
  * @run driver OptimizeModuleHandlingTest
  * @summary test module path changes for optimization of
@@ -63,8 +63,8 @@ public class OptimizeModuleHandlingTest {
 
     private static String CLASS_FOUND_MESSAGE = "com.foos.Test found";
     private static String CLASS_NOT_FOUND_MESSAGE = "java.lang.ClassNotFoundException: com.foos.Test";
-    private static String OPTIMIZE_ENABLED = "Using optimized module handling enabled";
-    private static String OPTIMIZE_DISABLED = "Using optimized module handling disabled";
+    private static String OPTIMIZE_ENABLED = "optimized module handling: enabled";
+    private static String OPTIMIZE_DISABLED = "optimized module handling: disabled";
     private static String MAIN_FROM_JAR = "class,load.*com.bars.Main.*[.]jar";
     private static String MAIN_FROM_CDS = "class,load.*com.bars.Main.*shared objects file";
     private static String TEST_FROM_JAR = "class,load.*com.foos.Test.*[.]jar";
diff --git a/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClasses.java b/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClasses.java
index e70021c4ef8..84c17c331f3 100644
--- a/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClasses.java
+++ b/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClasses.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -53,7 +53,8 @@ public void process(String args[]) throws Throwable {
                 .setXShareMode("dump")
                 .setArchiveName(ReplaceCriticalClasses.class.getName() + ".jsa")
                 .setUseVersion(false)
-                .addSuffix("-showversion");
+                .addSuffix("-showversion")
+                .addSuffix("-Xlog:cds");
             CDSTestUtils.run(opts).assertNormalExit("");
 
             launchChildProcesses(getTests());
@@ -80,6 +81,8 @@ public String[] getTests() {
             "-early -notshared java/lang/String",
             "-early -notshared java/lang/Cloneable",
             "-early -notshared java/io/Serializable",
+            "-early -notshared java/lang/Module",
+            "-early -notshared java/lang/ModuleLayer",
 
             // CDS should not be disabled -- these critical classes cannot be replaced because
             // JvmtiExport::early_class_hook_env() is false.
@@ -87,13 +90,8 @@ public String[] getTests() {
             "java/lang/String",
             "java/lang/Cloneable",
             "java/io/Serializable",
-
-            /* Try to replace classes that are used by the archived subgraph graphs.
-               The following test cases are in ReplaceCriticalClassesForSubgraphs.java.
-            "-early -notshared -subgraph java/lang/module/ResolvedModule jdk.internal.module.ArchivedModuleGraph",
-            "-early -notshared -subgraph java/lang/Long java.lang.Long$LongCache",
-            "-subgraph java/lang/Long java.lang.Long$LongCache",
-            */
+            "java/lang/Module",
+            "java/lang/ModuleLayer",
 
             // Replace classes that are loaded after JVMTI_PHASE_PRIMORDIAL. It's OK to replace
             // such
@@ -116,12 +114,13 @@ static void launchChildProcesses(String tests[]) throws Throwable {
 
     static void launchChild(String args[]) throws Throwable {
         if (args.length < 1) {
-            throw new RuntimeException("Invalid test case. Should be <-early> <-subgraph> <-notshared> klassName subgraphKlass");
+            throw new RuntimeException("Invalid test case. Should be <-early> <-subgraph> <-notshared> <-nowhitebox> klassName subgraphKlass");
         }
         String klassName = null;
         String subgraphKlass = null;
         String early = "";
         boolean subgraph = false;
+        boolean whitebox = true;
         String shared = "-shared";
 
         for (int i=0; i<args.length-1; i++) {
@@ -130,6 +129,8 @@ static void launchChild(String args[]) throws Throwable {
                 early = "-early,";
             } else if (opt.equals("-subgraph")) {
                 subgraph = true;
+            } else if (opt.equals("-nowhitebox")) {
+                whitebox = false;
             } else if (opt.equals("-notshared")) {
                 shared = opt;
             } else {
@@ -166,10 +167,11 @@ static void launchChild(String args[]) throws Throwable {
             .addSuffix("-showversion",
                        "-Xlog:cds",
                        "-XX:+UnlockDiagnosticVMOptions",
-                       agent,
-                       "-XX:+WhiteBoxAPI",
-                       "-Xbootclasspath/a:" + ClassFileInstaller.getJarPath("whitebox.jar"));
-
+                       agent);
+        if (whitebox) {
+            opts.addSuffix("-XX:+WhiteBoxAPI",
+                           "-Xbootclasspath/a:" + ClassFileInstaller.getJarPath("whitebox.jar"));
+        }
         if (subgraph) {
             opts.addSuffix("-Xlog:cds,cds+heap");
         }
@@ -191,6 +193,8 @@ static void launchChild(String args[]) throws Throwable {
                     if (expectShared) {
                         if (!out.getOutput().contains("UseSharedSpaces: Unable to map at required address in java heap")) {
                             out.shouldContain(subgraphInit);
+                            // If the subgraph is successfully initialized, the specified shared class must not be rewritten.
+                            out.shouldNotContain("Rewriting done.");
                         }
                     } else {
                       out.shouldNotContain(subgraphInit);
@@ -200,15 +204,19 @@ static void launchChild(String args[]) throws Throwable {
     }
 
     static void testInChild(boolean shouldBeShared, Class klass) {
-        WhiteBox wb = WhiteBox.getWhiteBox();
+        try {
+            WhiteBox wb = WhiteBox.getWhiteBox();
 
-        if (shouldBeShared && !wb.isSharedClass(klass)) {
-            throw new RuntimeException(klass + " should be shared but but actually is not.");
-        }
-        if (!shouldBeShared && wb.isSharedClass(klass)) {
-            throw new RuntimeException(klass + " should not be shared but actually is.");
+            if (shouldBeShared && !wb.isSharedClass(klass)) {
+                throw new RuntimeException(klass + " should be shared but but actually is not.");
+            }
+            if (!shouldBeShared && wb.isSharedClass(klass)) {
+                throw new RuntimeException(klass + " should not be shared but actually is.");
+            }
+            System.out.println("wb.isSharedClass(" + klass + "): " + wb.isSharedClass(klass) + " == " + shouldBeShared);
+        } catch (UnsatisfiedLinkError e) {
+            System.out.println("WhiteBox is disabled -- because test has -nowhitebox");
         }
-        System.out.println("wb.isSharedClass(klass): " + wb.isSharedClass(klass) + " == " + shouldBeShared);
 
         String strings[] = {
             // interned strings from j.l.Object
diff --git a/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java b/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java
index 68efc0af1de..fe081b49078 100644
--- a/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java
+++ b/test/hotspot/jtreg/runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,10 +40,21 @@ public static void main(String args[]) throws Throwable {
 
     public String[] getTests() {
         String tests[] = {
-            // Try to replace classes that are used by the archived subgraph graphs.
+            // Try to replace classes that are used by the archived subgraph graphs. (CDS should be disabled)
             "-early -notshared -subgraph java/lang/module/ResolvedModule jdk.internal.module.ArchivedModuleGraph",
             "-early -notshared -subgraph java/lang/Long java.lang.Long$LongCache",
+
+            // CDS should not be disabled -- these critical classes cannot be replaced because
+            // JvmtiExport::early_class_hook_env() is false.
+            "-subgraph java/lang/module/ResolvedModule jdk.internal.module.ArchivedModuleGraph",
             "-subgraph java/lang/Long java.lang.Long$LongCache",
+
+            // Tests for archived full module graph. We cannot use whitebox, which requires appending to bootclasspath.
+            // VM will disable full module graph if bootclasspath is appended.
+            "-nowhitebox -early -notshared -subgraph java/lang/Module jdk.internal.module.ArchivedBootLayer",
+            "-nowhitebox -early -notshared -subgraph java/lang/ModuleLayer jdk.internal.module.ArchivedBootLayer",
+            "-nowhitebox -subgraph java/lang/Module jdk.internal.module.ArchivedBootLayer",
+            "-nowhitebox -subgraph java/lang/ModuleLayer jdk.internal.module.ArchivedBootLayer",
         };
         return tests;
     }
diff --git a/test/hotspot/jtreg/runtime/logging/ModulesTest.java b/test/hotspot/jtreg/runtime/logging/ModulesTest.java
index 20962e1f103..6ebb73cf20f 100644
--- a/test/hotspot/jtreg/runtime/logging/ModulesTest.java
+++ b/test/hotspot/jtreg/runtime/logging/ModulesTest.java
@@ -34,13 +34,18 @@
 import jdk.test.lib.process.ProcessTools;
 
 public class ModulesTest {
+    // If modules in the system image have been archived in CDS, no Modules will
+    // be dynamically created at runtime. Disable CDS so all of the expected messages
+    // are printed.
+    private static String XSHARE_OFF = "-Xshare:off";
+
     public static void main(String[] args) throws Exception {
-        testModuleTrace("-Xlog:module=trace", "-version");
-        testModuleLoad("-Xlog:module+load", "-version");
-        testModuleUnload("-Xlog:module+unload", "-version");
+        testModuleTrace("-Xlog:module=trace", XSHARE_OFF, "-version");
+        testModuleLoad("-Xlog:module+load", XSHARE_OFF, "-version");
+        testModuleUnload("-Xlog:module+unload", XSHARE_OFF, "-version");
 
         // same as -Xlog:module+load -Xlog:module+unload
-        testModuleLoad("-verbose:module", "-version");
+        testModuleLoad("-verbose:module", XSHARE_OFF, "-version");
     }
 
     static void testModuleTrace(String... args) throws Exception {
diff --git a/test/hotspot/jtreg/serviceability/jvmti/GetLocalVariable/libGetLocalWithoutSuspendTest.cpp b/test/hotspot/jtreg/serviceability/jvmti/GetLocalVariable/libGetLocalWithoutSuspendTest.cpp
index 5ae223aed5d..fe5e8c992fc 100644
--- a/test/hotspot/jtreg/serviceability/jvmti/GetLocalVariable/libGetLocalWithoutSuspendTest.cpp
+++ b/test/hotspot/jtreg/serviceability/jvmti/GetLocalVariable/libGetLocalWithoutSuspendTest.cpp
@@ -154,7 +154,7 @@ void test_GetLocalObject(jvmtiEnv* jvmti, JNIEnv* env, int depth) {
   jobject obj;
   char* errMsg;
 
-  printf("AGENT: calling GetLocalObject()\n");
+  printf("AGENT: calling GetLocalObject() with depth %d\n", depth);
   err = jvmti->GetLocalObject(target_thread, depth, 0, &obj);
   errMsg = GetErrorMessage(jvmti, err);
   printf("AGENT: GetLocalObject() result code %s (%d)\n", errMsg != NULL ? errMsg : "N/A", err);
@@ -166,9 +166,13 @@ void test_GetLocalObject(jvmtiEnv* jvmti, JNIEnv* env, int depth) {
   // If the target thread wins the race we can get errors because we
   // don't find a frame at the given depth or we find a non-java frame
   // there (e.g. native frame). This is expected.
+  // JVMTI_ERROR_INVALID_SLOT can occur also because the target thread is
+  // running and the GetLocalObject() call might coincidentally refer to the
+  // frame of a static method without parameters.
   if (err != JVMTI_ERROR_NONE &&
       err != JVMTI_ERROR_NO_MORE_FRAMES &&
-      err != JVMTI_ERROR_OPAQUE_FRAME) {
+      err != JVMTI_ERROR_OPAQUE_FRAME &&
+      err != JVMTI_ERROR_INVALID_SLOT) {
     ShowErrorMessage(jvmti, err, "AgentThreadLoop: error in JVMTI GetLocalObject");
     env->FatalError("AgentThreadLoop: error in JVMTI GetLocalObject\n");
   }
@@ -260,7 +264,7 @@ AgentThreadLoop(jvmtiEnv * jvmti, JNIEnv* env, void * arg) {
 // It notifies the agent to do the GetLocalObject() call and then races
 // it to make its stack not walkable by returning from the native call.
 JNIEXPORT void JNICALL
-Java_GetLocalWithoutSuspendTest_notifyAgentToGetLocal(JNIEnv *env, jclass cls, jint depth, jlong waitCycles) {
+Java_GetLocalWithoutSuspendTest_notifyAgentToGetLocal(JNIEnv *env, jclass cls, jint depth, jint waitCycles) {
   monitor_enter(jvmti, env, AT_LINE);
 
   // Set depth_for_get_local and notify agent that the target thread is ready for the GetLocalObject() call
diff --git a/test/hotspot/jtreg/test_env.sh b/test/hotspot/jtreg/test_env.sh
deleted file mode 100644
index 10b4630df1e..00000000000
--- a/test/hotspot/jtreg/test_env.sh
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/bin/sh
-#
-#  Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
-#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-# 
-#  This code is free software; you can redistribute it and/or modify it
-#  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 Environment script was written to capture typically used environment
-# setup for a given shell test. 
-#
-
-# TESTJAVA can be a JDK or JRE. If JRE you need to set COMPILEJAVA
-if [ "${TESTJAVA}" = "" ]
-then
-  echo "TESTJAVA not set.  Test cannot execute.  Failed."
-  exit 1
-fi
-echo "TESTJAVA=${TESTJAVA}"
-
-# COMPILEJAVA requires a JDK, some shell test use javac,jar,etc 
-if [ "${COMPILEJAVA}" = "" ]
-then
- echo "COMPILEJAVA not set.  Using TESTJAVA as default"
- COMPILEJAVA=${TESTJAVA}
-fi
-echo "COMPILEJAVA=${COMPILEJAVA}"
-
-if [ "${TESTCLASSES}" = "" ]
-then
-  echo "TESTCLASES not set.  Using "." as default"
-  TESTCLASSES=.
-fi
-echo "TESTCLASSES=${TESTCLASSES}"
-
-TESTOPTS="${TESTVMOPTS} ${TESTJAVAOPTS}"
-echo "TESTOPTS=${TESTOPTS}"
-
-# set platform-dependent variables
-OS=`uname -s`
-case "$OS" in
-  AIX | Darwin | Linux )
-    NULL=/dev/null
-    PS=":"
-    FS="/"
-    RM=/bin/rm
-    CP=/bin/cp
-    MV=/bin/mv
-    ;;
-  Windows_* )
-    NULL=NUL
-    PS=";"
-    FS="\\"
-    RM=rm
-    CP=cp
-    MV=mv
-    ;;
-  CYGWIN_* )
-    NULL=/dev/null
-    PS=";"
-    FS="/"
-    RM=rm
-    CP=cp
-    MV=mv
-    ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
-esac
-
-export NULL PS FS RM CP MV
-echo "NULL =${NULL}"
-echo "PS =${PS}"
-echo "FS =${FS}"
-echo "RM =${RM}"
-echo "CP =${CP}"
-echo "MV =${MV}"
-
-# jtreg -classpathappend:<path>
-JEMMYPATH=${CPAPPEND}
-CLASSPATH=.${PS}${TESTCLASSES}${PS}${JEMMYPATH} ; export CLASSPATH
-echo "CLASSPATH =${CLASSPATH}"
-
-# Current directory is scratch directory 
-THIS_DIR=.
-echo "THIS_DIR=${THIS_DIR}"
-
-# Check to ensure the java defined actually works
-${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} -version
-if [ $? != 0 ]; then
-  echo "Wrong TESTJAVA or TESTJAVAOPTS or TESTVMOPTS:"
-  echo ''$TESTJAVA'' ''$TESTJAVAOPTS'' ''$TESTVMOPTS''
-  exit 1
-fi
-
-${TESTJAVA}${FS}bin${FS}java ${TESTOPTS} -Xinternalversion | sed -e 's/[(][^)]*[)]//g' -e 's/ by "[^"]*"//g' > vm_version.out 2>&1
-echo "INT_VERSION=`cat vm_version.out 2>&1`"
-
-VM_TYPE="unknown"
-grep "Server" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_TYPE="server"
-fi
-grep "Client" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_TYPE="client"
-fi
-
-VM_BITS="32"
-grep "64-Bit" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_BITS="64"
-fi
-
-VM_OS="unknown"
-grep "aix" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_OS="aix"
-fi
-grep "bsd" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_OS="bsd"
-fi
-grep "linux" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_OS="linux"
-fi
-grep "windows" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_OS="windows"
-fi
-
-VM_CPU="unknown"
-grep "x86" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_CPU="i386"
-fi
-grep "amd64" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_CPU="amd64"
-fi
-grep "arm" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_CPU="arm"
-fi
-grep "ppc" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_CPU="ppc"
-  if [ $VM_BITS = "64" ]
-  then
-    VM_CPU="ppc64"
-    grep "ppc64le" vm_version.out > ${NULL}
-    if [ $? = 0 ]
-    then
-      VM_CPU="ppc64le"
-    fi
-  fi
-fi
-grep "ia64" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_CPU="ia64"
-fi
-grep "s390x" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_CPU="s390x"
-fi
-grep "aarch64" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_CPU="aarch64"
-fi
-grep "arm64" vm_version.out > ${NULL}
-if [ $? = 0 ]
-then
-  VM_CPU="aarch64"
-fi
-export VM_TYPE VM_BITS VM_OS VM_CPU
-echo "VM_TYPE=${VM_TYPE}"
-echo "VM_BITS=${VM_BITS}"
-echo "VM_OS=${VM_OS}"
-echo "VM_CPU=${VM_CPU}"
diff --git a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack017.java b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack017.java
index da9dae6377b..fcb18ed216e 100644
--- a/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack017.java
+++ b/test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack017.java
@@ -41,10 +41,10 @@
  *     See the bug:
  *     4366625 (P4/S4) multiple stack overflow causes HS crash
  *
- * @requires (vm.opt.DeoptimizeALot != true & vm.compMode != "Xcomp")
+ * @requires (vm.opt.DeoptimizeALot != true & vm.compMode != "Xcomp" & vm.pageSize == 4096)
  * @library /vmTestbase
  * @build nsk.share.Terminator
- * @run main/othervm/timeout=900 -Xss448K nsk.stress.stack.stack017 -eager
+ * @run main/othervm/timeout=900 -Xss220K nsk.stress.stack.stack017 -eager
  */
 
 package nsk.stress.stack;
diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index 0d5c75221d7..cbae666f145 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -836,7 +836,6 @@ javax/swing/JMenuItem/4171437/bug4171437.java 8233641 macosx-all
 javax/swing/JMenu/4692443/bug4692443.java 8171998 macosx-all
 javax/swing/plaf/synth/7158712/bug7158712.java 8238720 windows-all
 javax/swing/plaf/basic/BasicComboPopup/JComboBoxPopupLocation/JComboBoxPopupLocation.java 8238720 windows-all
-javax/swing/plaf/basic/BasicComboPopup/7072653/bug7072653.java 8238720 windows-all
 
 sanity/client/SwingSet/src/ToolTipDemoTest.java 8225012 windows-all,macosx-all
 sanity/client/SwingSet/src/ScrollPaneDemoTest.java 8225013 linux-all
diff --git a/test/jdk/java/awt/ColorClass/AlphaColorTest.java b/test/jdk/java/awt/ColorClass/AlphaColorTest.java
index b26bb0616f4..e3478c961fc 100644
--- a/test/jdk/java/awt/ColorClass/AlphaColorTest.java
+++ b/test/jdk/java/awt/ColorClass/AlphaColorTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -84,8 +84,8 @@ public void paint(Graphics g) {
         Color color = new Color(255, 255, 255, 127);
         frame.add("Center", new AlphaColorTest(color));
         frame.setUndecorated(true);
-        frame.setLocationRelativeTo(null);
         frame.pack();
+        frame.setLocationRelativeTo(null);
         frame.setVisible(true);
     }
 }
diff --git a/test/jdk/java/lang/annotation/typeAnnotations/TypeVariableBoundParameterIndex.java b/test/jdk/java/lang/annotation/typeAnnotations/TypeVariableBoundParameterIndex.java
new file mode 100644
index 00000000000..12dc344a002
--- /dev/null
+++ b/test/jdk/java/lang/annotation/typeAnnotations/TypeVariableBoundParameterIndex.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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     8202473
+ * @summary Annotations on type variables with multiple bounds should be placed on their respective bound
+ * @compile  TypeVariableBoundParameterIndex.java
+ * @run main TypeVariableBoundParameterIndex
+ */
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.reflect.AnnotatedParameterizedType;
+import java.lang.reflect.AnnotatedType;
+import java.lang.reflect.TypeVariable;
+import java.util.concurrent.Callable;
+
+/*
+ * A class might have multiple bounds as parameterized types with type annotations on these bounds.
+ * This test assures that these bound annotations are resolved correctly.
+ */
+public class TypeVariableBoundParameterIndex {
+
+    public static void main(String[] args) throws Exception {
+        TypeVariable<?>[] variables = Sample.class.getTypeParameters();
+
+        for (int i = 0; i < 2; i++) {
+            TypeVariable<?> variable = variables[i];
+            AnnotatedType[] bounds = variable.getAnnotatedBounds();
+            AnnotatedType bound = bounds[0];
+            AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) bound;
+            AnnotatedType[] actualTypeArguments = parameterizedType.getAnnotatedActualTypeArguments();
+            Annotation[] annotations = actualTypeArguments[0].getAnnotations();
+            if (annotations.length != 1 || annotations[0].annotationType() != TypeAnnotation.class) {
+                throw new AssertionError();
+            }
+        }
+
+        TypeVariable<?> variable = variables[2];
+        AnnotatedType[] bounds = variable.getAnnotatedBounds();
+        AnnotatedType bound = bounds[0];
+        AnnotatedParameterizedType parameterizedType = (AnnotatedParameterizedType) bound;
+        AnnotatedType[] actualTypeArguments = parameterizedType.getAnnotatedActualTypeArguments();
+        Annotation[] annotations = actualTypeArguments[0].getAnnotations();
+        if (annotations.length != 0) {
+            throw new AssertionError();
+        }
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target(ElementType.TYPE_USE)
+    @interface TypeAnnotation { }
+
+    static class Sample<T extends Callable<@TypeAnnotation ?>, S extends Callable<@TypeAnnotation ?>, U extends Callable<?>> { }
+}
diff --git a/test/jdk/java/lang/lang-runtime/PatternHandleTest.java b/test/jdk/java/lang/lang-runtime/PatternHandleTest.java
deleted file mode 100755
index e7643c5a1dc..00000000000
--- a/test/jdk/java/lang/lang-runtime/PatternHandleTest.java
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  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.
- */
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.runtime.PatternHandle;
-import java.lang.runtime.PatternHandles;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-import org.testng.annotations.Test;
-
-import static java.util.Map.entry;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
-import static org.testng.Assert.assertNotSame;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertSame;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-/**
- * @test
- * @run testng PatternHandleTest
- * @summary Smoke tests for java.lang.runtime.Extractor
- */
-@Test
-public class PatternHandleTest {
-
-    enum MatchKind {
-        /** Match succeeds, with a carrier object different form the target */
-        MATCH_CARRIER,
-        /** Match succeeds, with self-carrier */
-        MATCH_SELF,
-        /** Match succeeds, carrier provenance unknown */
-        MATCH,
-        /** Match fails */
-        NO_MATCH,
-        /** Match fails with a runtime exception */
-        ERROR;
-    }
-
-    // We have to resort to the subterfuge of laundering the tryMatch invocation
-    // through an ancillary object, because the only way to control the static
-    // signature is through the static types.  So we have a bunch of invokers,
-    // each of which embeds different assumptions about the target type.  This
-    // way we can test mismatches between the expected and actual types.
-
-    interface TryMatchInvoker<T> {
-        Object tryMatch(MethodHandle mh, T target) throws Throwable;
-    }
-
-    static final TryMatchInvoker<Object> objectInvoker = (MethodHandle mh, Object x) -> mh.invokeExact(x);
-    static final TryMatchInvoker<Number> numberInvoker = (MethodHandle mh, Number x) -> mh.invokeExact(x);
-    static final TryMatchInvoker<Integer> integerInvoker = (MethodHandle mh, Integer x) -> mh.invokeExact(x);
-    static final TryMatchInvoker<Integer> intInvoker = (MethodHandle mh, Integer x) -> mh.invokeExact((int) x);
-    static final TryMatchInvoker<String> stringInvoker = (MethodHandle mh, String x) -> mh.invokeExact(x);
-    static final TryMatchInvoker<List> listInvoker = (MethodHandle mh, List x) -> mh.invokeExact(x);
-    static final TryMatchInvoker<TestClass> testClassInvoker = (MethodHandle mh, TestClass x) -> mh.invokeExact(x);
-    static final TryMatchInvoker<TestClass2> testClass2Invoker = (MethodHandle mh, TestClass2 x) -> mh.invokeExact(x);
-
-    static final Map<Class<?>, TryMatchInvoker<?>> invokers
-            = Map.ofEntries(entry(Object.class, objectInvoker),
-                            entry(Number.class, numberInvoker),
-                            entry(Integer.class, integerInvoker),
-                            entry(int.class, intInvoker),
-                            entry(String.class, stringInvoker),
-                            entry(List.class, listInvoker),
-                            entry(TestClass.class, testClassInvoker),
-                            entry(TestClass2.class, testClass2Invoker));
-
-    interface Throwing {
-        public void run() throws Throwable;
-    }
-
-    static void assertThrows(Class<? extends Throwable> exception, Throwing r) {
-        try {
-            r.run();
-            fail("Expected exception: " + exception);
-        }
-        catch (Throwable t) {
-            if (!exception.isAssignableFrom(t.getClass()))
-                fail(String.format("Expected exception %s, got %s", exception, t.getClass()), t);
-        }
-    }
-
-    static void assertMatch(MatchKind expected,
-                            PatternHandle e,
-                            Object target,
-                            Object... expectedBindings) throws Throwable {
-        int count = e.descriptor().parameterCount();
-        Object[] bindings = new Object[count];
-        Object carrier;
-        try {
-            TryMatchInvoker inv = invokers.get(e.descriptor().returnType());
-            // @@@ temporary hack until we break out the assert-match machinery
-            if (inv == null)
-                inv = (MethodHandle mh, Object x) -> mh.invoke(x);
-            // @@@ end temporary hack
-            carrier = inv.tryMatch(e.tryMatch(), target);
-        }
-        catch (Throwable t) {
-            carrier = null;
-            if (expected == MatchKind.ERROR)
-                return;
-            else
-                fail("Unexpected exception in tryMatch", t);
-        }
-
-        if (carrier != null) {
-            for (int i = 0; i < count; i++)
-                bindings[i] = e.component(i).invoke(carrier);
-        }
-
-        if (expected == MatchKind.NO_MATCH)
-            assertNull(carrier);
-        else {
-            assertNotNull(carrier);
-            assertEquals(bindings.length, expectedBindings.length);
-            for (int i = 0; i < expectedBindings.length; i++)
-                assertEquals(bindings[i], expectedBindings[i]);
-
-            if (expected == MatchKind.MATCH_SELF)
-                assertSame(carrier, target);
-            else if (expected == MatchKind.MATCH_CARRIER)
-                assertNotSame(carrier, target);
-        }
-    }
-
-    private static class TestClass {
-        static TestClass INSTANCE_A = new TestClass("foo", 3, 4L, (byte) 5);
-        static TestClass INSTANCE_B = new TestClass(null, 0, 0L, (byte) 0);
-        static TestClass INSTANCE_C = new TestClass("foo", 2, 4L, (byte) 5);
-        static Object[] COMPONENTS_A = new Object[] { "foo", 3, 4L, (byte) 5 };
-        static Object[] COMPONENTS_B = new Object[] { null, 0, 0L, (byte) 0 };
-        static Object[] COMPONENTS_C = new Object[] { "foo", 2, 4L, (byte) 5 };
-
-        static Map<TestClass, Object[]> INSTANCES = Map.of(INSTANCE_A, COMPONENTS_A,
-                                                           INSTANCE_B, COMPONENTS_B,
-                                                           INSTANCE_C, COMPONENTS_C);
-
-        static MethodHandle MH_S, MH_I, MH_L, MH_B, MH_PRED;
-        static MethodHandle CONSTRUCTOR;
-        static MethodHandle DIGESTER;
-        static MethodHandle DIGESTER_PARTIAL;
-        static MethodType TYPE = MethodType.methodType(TestClass.class, String.class, int.class, long.class, byte.class);
-        static {
-            try {
-                MH_B = MethodHandles.lookup().findGetter(TestClass.class, "b", byte.class);
-                MH_S = MethodHandles.lookup().findGetter(TestClass.class, "s", String.class);
-                MH_I = MethodHandles.lookup().findGetter(TestClass.class, "i", int.class);
-                MH_L = MethodHandles.lookup().findGetter(TestClass.class, "l", long.class);
-                MH_PRED = MethodHandles.lookup().findVirtual(TestClass.class, "matches", MethodType.methodType(boolean.class));
-                CONSTRUCTOR = MethodHandles.lookup().findConstructor(TestClass.class, TYPE.changeReturnType(void.class));
-                DIGESTER = MethodHandles.lookup().findVirtual(TestClass.class, "digest", MethodType.methodType(Object.class, MethodHandle.class));
-                DIGESTER_PARTIAL = MethodHandles.lookup().findVirtual(TestClass.class, "digestPartial", MethodType.methodType(Object.class, MethodHandle.class));
-            }
-            catch (ReflectiveOperationException e) {
-                throw new ExceptionInInitializerError(e);
-            }
-        }
-        static MethodHandle[] COMPONENT_MHS = {TestClass.MH_S, TestClass.MH_I, TestClass.MH_L, TestClass.MH_B };
-
-        String s;
-        int i;
-        long l;
-        byte b;
-
-        TestClass(String s, int i, long l, byte b) {
-            this.s = s;
-            this.i = i;
-            this.l = l;
-            this.b = b;
-        }
-
-        TestClass copy() {
-            return new TestClass(s, i, l, b);
-        }
-
-        boolean matches() { return s != null && s.length() == i; }
-
-        Object digest(MethodHandle target) throws Throwable {
-            return target.invoke(s, i, l, b);
-        }
-
-        Object digestPartial(MethodHandle target) throws Throwable {
-            return matches() ? target.invoke(s, i, l, b) : null;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (o == null || getClass() != o.getClass()) return false;
-            TestClass aClass = (TestClass) o;
-            return i == aClass.i &&
-                   l == aClass.l &&
-                   b == aClass.b &&
-                   Objects.equals(s, aClass.s);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(s, i, l, b);
-        }
-    }
-
-    private static class TestClass2 {
-        static MethodHandle MH_X;
-        static MethodType TYPE = MethodType.methodType(TestClass2.class, Object.class);
-        static {
-            try {
-                MH_X = MethodHandles.lookup().findGetter(TestClass2.class, "x", Object.class);
-            }
-            catch (ReflectiveOperationException e) {
-                throw new ExceptionInInitializerError(e);
-            }
-        }
-
-        Object x;
-
-        public TestClass2(Object x) {
-            this.x = x;
-        }
-    }
-
-    PatternHandle TYPE_STRING = PatternHandles.ofType(String.class);
-    PatternHandle TYPE_LIST = PatternHandles.ofType(List.class);
-    PatternHandle TYPE_INTEGER = PatternHandles.ofType(Integer.class);
-    PatternHandle TYPE_NUMBER = PatternHandles.ofType(Number.class);
-    PatternHandle TYPE_OBJECT = PatternHandles.ofType(Object.class);
-    PatternHandle TYPE_INT = PatternHandles.ofType(int.class);
-    PatternHandle TYPE_STRING_NULLABLE = PatternHandles.ofTypeNullable(String.class);
-
-    public void testType() throws Throwable {
-        assertMatch(MatchKind.MATCH_SELF, TYPE_STRING, "Foo", "Foo");
-        assertMatch(MatchKind.NO_MATCH, TYPE_STRING, null);
-        assertMatch(MatchKind.ERROR, TYPE_STRING, List.of());
-        assertMatch(MatchKind.ERROR, TYPE_STRING, 3);
-
-        assertMatch(MatchKind.MATCH_SELF, TYPE_LIST, List.of(3), List.of(3));
-        assertMatch(MatchKind.MATCH_SELF, TYPE_LIST, List.of(), List.of());
-        assertMatch(MatchKind.MATCH_SELF, TYPE_LIST, new ArrayList<>(), List.of());
-        assertMatch(MatchKind.NO_MATCH, TYPE_LIST, null);
-
-        assertMatch(MatchKind.MATCH_SELF, TYPE_INTEGER, 3, 3);
-        assertMatch(MatchKind.MATCH_SELF, TYPE_NUMBER, 3, 3);
-        assertMatch(MatchKind.MATCH_SELF, TYPE_OBJECT, 3, 3);
-        assertMatch(MatchKind.NO_MATCH, TYPE_OBJECT, null);
-
-        assertMatch(MatchKind.ERROR, TYPE_INTEGER, 3.14f);
-        assertMatch(MatchKind.ERROR, TYPE_INTEGER, "foo");
-    }
-
-    public void testPrimitiveType() throws Throwable {
-        assertMatch(MatchKind.MATCH_SELF, TYPE_INT, 3, 3);
-        assertMatch(MatchKind.ERROR, TYPE_INT, 3.14f);
-
-        PatternHandle asObject = PatternHandles.adaptTarget(TYPE_INT, Object.class);
-        assertMatch(MatchKind.MATCH_SELF, asObject, 3, 3);
-        assertMatch(MatchKind.NO_MATCH, asObject, 3.14f);
-        assertMatch(MatchKind.NO_MATCH, asObject, null);
-
-        PatternHandle asInteger = PatternHandles.adaptTarget(TYPE_INT, Integer.class);
-        assertMatch(MatchKind.MATCH_SELF, asInteger, 3, 3);
-        assertMatch(MatchKind.NO_MATCH, asInteger, null);
-        assertMatch(MatchKind.ERROR, asInteger, 3.14f);
-    }
-
-    public void testNullableType() throws Throwable {
-        assertMatch(MatchKind.MATCH_SELF, TYPE_STRING_NULLABLE, "Foo", "Foo");
-        assertMatch(MatchKind.MATCH, TYPE_STRING_NULLABLE, null, (Object) null);
-        assertMatch(MatchKind.ERROR, TYPE_STRING_NULLABLE, 3);
-
-        PatternHandle asObjectNullable = PatternHandles.adaptTarget(TYPE_STRING_NULLABLE, Object.class);
-        assertMatch(MatchKind.MATCH_SELF, asObjectNullable, "Foo", "Foo");
-        assertMatch(MatchKind.MATCH, asObjectNullable, null, (Object) null);
-        assertMatch(MatchKind.NO_MATCH, asObjectNullable, 3);
-    }
-
-    public void testAdapt() throws Throwable {
-        PatternHandle e = PatternHandles.ofTypeNullable(Number.class);
-        PatternHandle n = PatternHandles.adaptTarget(e, Integer.class);
-        PatternHandle w = PatternHandles.adaptTarget(e, Object.class);
-
-        assertEquals(e.descriptor().returnType(), Number.class);
-        assertEquals(n.descriptor().returnType(), Integer.class);
-        assertEquals(w.descriptor().returnType(), Object.class);
-
-        assertMatch(MatchKind.MATCH_SELF, e, 1, 1);
-        assertMatch(MatchKind.MATCH_SELF, n, 1, 1);
-        assertMatch(MatchKind.MATCH_SELF, w, 1, 1);
-
-        assertMatch(MatchKind.MATCH_SELF, e, 3.14f, 3.14f);
-        assertMatch(MatchKind.ERROR, n, 3.14f);
-        assertMatch(MatchKind.MATCH_SELF, w, 3.14f, 3.14f);
-
-        assertMatch(MatchKind.MATCH, e, null, (Object) null);
-        assertMatch(MatchKind.MATCH, n, null, (Object) null);
-        assertMatch(MatchKind.MATCH, w, null, (Object) null);
-
-        e = PatternHandles.ofType(Number.class);
-        n = PatternHandles.adaptTarget(e, Integer.class);
-        w = PatternHandles.adaptTarget(e, Object.class);
-
-        assertMatch(MatchKind.MATCH_SELF, e, 1, 1);
-        assertMatch(MatchKind.MATCH_SELF, n, 1, 1);
-        assertMatch(MatchKind.MATCH_SELF, w, 1, 1);
-        assertMatch(MatchKind.NO_MATCH, e, null);
-        assertMatch(MatchKind.NO_MATCH, n, null);
-        assertMatch(MatchKind.NO_MATCH, w, null);
-
-        PatternHandle widenNarrow = PatternHandles.adaptTarget(PatternHandles.adaptTarget(TYPE_STRING, Object.class), String.class);
-        assertMatch(MatchKind.MATCH_SELF, widenNarrow, "Foo", "Foo");
-        assertMatch(MatchKind.NO_MATCH, widenNarrow, null);
-        assertMatch(MatchKind.ERROR, widenNarrow, List.of());
-        assertMatch(MatchKind.ERROR, widenNarrow, 3);
-
-        PatternHandle widenNarrowNullable = PatternHandles.adaptTarget(PatternHandles.adaptTarget(TYPE_STRING_NULLABLE, Object.class), String.class);
-        assertMatch(MatchKind.MATCH_SELF, widenNarrowNullable, "Foo", "Foo");
-        assertMatch(MatchKind.MATCH, widenNarrowNullable, null, (Object) null);
-        assertMatch(MatchKind.ERROR, widenNarrowNullable, List.of());
-        assertMatch(MatchKind.ERROR, widenNarrowNullable, 3);
-    }
-
-    public void testConstant() throws Throwable {
-        PatternHandle constantFoo = PatternHandles.ofConstant("foo");
-        assertMatch(MatchKind.MATCH, constantFoo, "foo");
-        assertMatch(MatchKind.NO_MATCH, constantFoo, "bar");
-        assertMatch(MatchKind.ERROR, constantFoo, 3);
-        assertMatch(MatchKind.NO_MATCH, constantFoo, null);
-
-        PatternHandle constantThree = PatternHandles.ofConstant(3);
-        assertMatch(MatchKind.MATCH, constantThree, 3);
-        assertMatch(MatchKind.NO_MATCH, constantThree, 4);
-        assertMatch(MatchKind.NO_MATCH, constantThree, null);
-    }
-
-    public void testNullConstant() throws Throwable {
-        PatternHandle constantNull = PatternHandles.ofConstant(null);
-        assertMatch(MatchKind.MATCH, constantNull, null);
-        assertMatch(MatchKind.NO_MATCH, constantNull, "foo");
-        assertMatch(MatchKind.NO_MATCH, constantNull, 3);
-    }
-
-    public void testProjections() throws Throwable {
-        Map<PatternHandle, MatchKind> m
-                = Map.of(PatternHandles.ofLazyProjection(TestClass.class, TestClass.COMPONENT_MHS), MatchKind.MATCH_SELF,
-                         PatternHandles.ofEagerProjection(TestClass.class, TestClass.COMPONENT_MHS), MatchKind.MATCH_CARRIER);
-        for (var ps : m.entrySet()) {
-            for (var entry : TestClass.INSTANCES.entrySet()) {
-                assertMatch(ps.getValue(), ps.getKey(), entry.getKey(), entry.getValue());
-            }
-            assertMatch(MatchKind.NO_MATCH, ps.getKey(), null);
-
-            PatternHandle asObject = PatternHandles.adaptTarget(ps.getKey(), Object.class);
-            for (var entry : TestClass.INSTANCES.entrySet())
-                assertMatch(ps.getValue(), asObject, entry.getKey(), entry.getValue());
-            assertMatch(MatchKind.NO_MATCH, asObject, null);
-
-            PatternHandle asTestClassAgain = PatternHandles.adaptTarget(asObject, TestClass.class);
-            for (var entry : TestClass.INSTANCES.entrySet())
-                assertMatch(ps.getValue(), asTestClassAgain, entry.getKey(), entry.getValue());
-            assertMatch(MatchKind.NO_MATCH, asTestClassAgain, null);
-        }
-    }
-
-    public void testDigest() throws Throwable {
-        PatternHandle e = PatternHandles.ofImperative(TestClass.TYPE, TestClass.DIGESTER);
-        for (var entry : TestClass.INSTANCES.entrySet())
-            assertMatch(MatchKind.MATCH_CARRIER, e, entry.getKey(), entry.getValue());
-        assertMatch(MatchKind.NO_MATCH, e, null);
-    }
-
-    public void testDigestPartial() throws Throwable {
-        PatternHandle e = PatternHandles.ofImperative(TestClass.TYPE, TestClass.DIGESTER_PARTIAL);
-        for (var entry : TestClass.INSTANCES.entrySet()) {
-            if (entry.getKey().matches())
-                assertMatch(MatchKind.MATCH_CARRIER, e, entry.getKey(), entry.getValue());
-            else
-                assertMatch(MatchKind.NO_MATCH, e, entry.getKey());
-        }
-        assertMatch(MatchKind.NO_MATCH, e, null);
-    }
-
-    public void testCompose() throws Throwable {
-        PatternHandle e = PatternHandles.ofLazyProjection(TestClass.class, TestClass.COMPONENT_MHS);
-        MethodHandle mh = PatternHandles.compose(e, TestClass.CONSTRUCTOR);
-        TestClass target = TestClass.INSTANCE_A;
-        Object o = mh.invoke(target);
-        assertTrue(o instanceof TestClass);
-        assertNotSame(target, o);
-        assertEquals(target, o);
-
-        assertNull(mh.invoke((Object) null));
-    }
-
-    public void testDropBindings() throws Throwable {
-        PatternHandle e = PatternHandles.ofEagerProjection(TestClass.class, TestClass.COMPONENT_MHS);
-        assertMatch(MatchKind.MATCH_CARRIER, e, TestClass.INSTANCE_A,
-                    TestClass.COMPONENTS_A);
-        assertMatch(MatchKind.MATCH_CARRIER, PatternHandles.dropBindings(e, 0), TestClass.INSTANCE_A,
-                    3, 4L, (byte) 5);
-        assertMatch(MatchKind.MATCH_CARRIER, PatternHandles.dropBindings(e, 0, 0), TestClass.INSTANCE_A,
-                    3, 4L, (byte) 5);
-        assertMatch(MatchKind.MATCH_CARRIER, PatternHandles.dropBindings(e, 3), TestClass.INSTANCE_A,
-                    "foo", 3, 4L);
-        assertMatch(MatchKind.MATCH_CARRIER, PatternHandles.dropBindings(e, 0, 1, 2, 3), TestClass.INSTANCE_A);
-
-        assertThrows(IndexOutOfBoundsException.class,
-                     () -> assertMatch(MatchKind.MATCH_CARRIER, PatternHandles.dropBindings(e, -1), TestClass.INSTANCE_A,
-                                       3, 4L, (byte) 5));
-        assertThrows(IndexOutOfBoundsException.class,
-                     () -> assertMatch(MatchKind.MATCH_CARRIER, PatternHandles.dropBindings(e, 4), TestClass.INSTANCE_A,
-                                       3, 4L, (byte) 5));
-    }
-
-    public void testNested() throws Throwable {
-        PatternHandle TC2 = PatternHandles.ofLazyProjection(TestClass2.class, TestClass2.MH_X);
-        PatternHandle TC2_STRING = PatternHandles.nested(TC2, TYPE_STRING);
-        PatternHandle TC2_OBJECT = PatternHandles.nested(TC2, TYPE_OBJECT);
-
-        assertMatch(MatchKind.MATCH_CARRIER, PatternHandles.dropBindings(TC2_STRING, 0), new TestClass2("foo"),
-                    "foo");
-        assertMatch(MatchKind.MATCH_CARRIER, PatternHandles.dropBindings(TC2_OBJECT, 0), new TestClass2("foo"),
-                    "foo");
-        assertMatch(MatchKind.NO_MATCH, PatternHandles.dropBindings(TC2_STRING, 0), new TestClass2(List.of(3)),
-                    "foo");
-
-        assertMatch(MatchKind.MATCH_CARRIER, PatternHandles.dropBindings(PatternHandles.nested(TC2, TC2_STRING), 0, 1), new TestClass2(new TestClass2("foo")),
-                    "foo");
-    }
-}
diff --git a/test/jdk/java/lang/lang-runtime/SwitchBootstrapsTest.java b/test/jdk/java/lang/lang-runtime/SwitchBootstrapsTest.java
deleted file mode 100755
index 2915302cf3b..00000000000
--- a/test/jdk/java/lang/lang-runtime/SwitchBootstrapsTest.java
+++ /dev/null
@@ -1,466 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * 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.
- */
-
-import java.io.Serializable;
-import java.lang.invoke.CallSite;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.runtime.SwitchBootstraps;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-import jdk.test.lib.RandomFactory;
-
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.fail;
-
-/**
- * @test
- * @key randomness
- * @library /test/lib
- * @build jdk.test.lib.RandomFactory
- * @run testng SwitchBootstrapsTest
- */
-@Test
-public class SwitchBootstrapsTest {
-    private final static Set<Class<?>> BOOLEAN_TYPES = Set.of(boolean.class, Boolean.class);
-    private final static Set<Class<?>> ALL_INT_TYPES = Set.of(int.class, short.class, byte.class, char.class,
-                                                              Integer.class, Short.class, Byte.class, Character.class);
-    private final static Set<Class<?>> SIGNED_NON_BYTE_TYPES = Set.of(int.class, Integer.class, short.class, Short.class);
-    private final static Set<Class<?>> CHAR_TYPES = Set.of(char.class, Character.class);
-    private final static Set<Class<?>> BYTE_TYPES = Set.of(byte.class, Byte.class);
-    private final static Set<Class<?>> SIGNED_TYPES
-            = Set.of(int.class, short.class, byte.class,
-                     Integer.class, Short.class, Byte.class);
-
-    public static final MethodHandle BSM_BOOLEAN_SWITCH;
-    public static final MethodHandle BSM_INT_SWITCH;
-    public static final MethodHandle BSM_LONG_SWITCH;
-    public static final MethodHandle BSM_FLOAT_SWITCH;
-    public static final MethodHandle BSM_DOUBLE_SWITCH;
-    public static final MethodHandle BSM_STRING_SWITCH;
-    public static final MethodHandle BSM_ENUM_SWITCH;
-    public static final MethodHandle BSM_TYPE_SWITCH;
-
-    private final static Random random = RandomFactory.getRandom();
-
-    static {
-        try {
-            BSM_BOOLEAN_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "booleanSwitch",
-                                                                   MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, boolean[].class));
-            BSM_INT_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "intSwitch",
-                                                               MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, int[].class));
-            BSM_LONG_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "longSwitch",
-                                                                MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, long[].class));
-            BSM_FLOAT_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "floatSwitch",
-                                                                 MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, float[].class));
-            BSM_DOUBLE_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "doubleSwitch",
-                                                                  MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, double[].class));
-            BSM_STRING_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "stringSwitch",
-                                                                  MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String[].class));
-            BSM_ENUM_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "enumSwitch",
-                                                                MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, Class.class, String[].class));
-            BSM_TYPE_SWITCH = MethodHandles.lookup().findStatic(SwitchBootstraps.class, "typeSwitch",
-                                                                MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, Class[].class));
-        }
-        catch (NoSuchMethodException | IllegalAccessException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    private MethodType switchType(Class<?> target) {
-        return MethodType.methodType(int.class, target);
-    }
-
-    private Object box(Class<?> clazz, int i) {
-        if (clazz == Integer.class)
-            return i;
-        else if (clazz == Short.class)
-            return (short) i;
-        else if (clazz == Character.class)
-            return (char) i;
-        else if (clazz == Byte.class)
-            return (byte) i;
-        else
-            throw new IllegalArgumentException(clazz.toString());
-    }
-
-    private void testBoolean(boolean... labels) throws Throwable {
-        Map<Class<?>, MethodHandle> mhs
-                = Map.of(boolean.class, ((CallSite) BSM_BOOLEAN_SWITCH.invoke(MethodHandles.lookup(), "", switchType(boolean.class), labels)).dynamicInvoker(),
-                         Boolean.class, ((CallSite) BSM_BOOLEAN_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Boolean.class), labels)).dynamicInvoker());
-
-        List<Boolean> labelList = new ArrayList<>();
-        for (boolean label : labels)
-            labelList.add(label);
-
-        for (int i=0; i<labels.length; i++) {
-            assertEquals(i, (int) mhs.get(boolean.class).invokeExact((boolean) labels[i]));
-            assertEquals(i, (int) mhs.get(Boolean.class).invokeExact((Boolean) labels[i]));
-        }
-
-        boolean[] booleans = { false, true };
-        for (boolean b : booleans) {
-            if (!labelList.contains(b)) {
-                assertEquals(labels.length, mhs.get(boolean.class).invoke((boolean) b));
-                assertEquals(labels.length, mhs.get(Boolean.class).invoke((boolean) b));
-            }
-        }
-
-        assertEquals(-1, (int) mhs.get(Boolean.class).invoke(null));
-    }
-
-    private void testInt(Set<Class<?>> targetTypes, int... labels) throws Throwable {
-        Map<Class<?>, MethodHandle> mhs
-                = Map.of(char.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(char.class), labels)).dynamicInvoker(),
-                         byte.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(byte.class), labels)).dynamicInvoker(),
-                         short.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(short.class), labels)).dynamicInvoker(),
-                         int.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(int.class), labels)).dynamicInvoker(),
-                         Character.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Character.class), labels)).dynamicInvoker(),
-                         Byte.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Byte.class), labels)).dynamicInvoker(),
-                         Short.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Short.class), labels)).dynamicInvoker(),
-                         Integer.class, ((CallSite) BSM_INT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Integer.class), labels)).dynamicInvoker());
-
-        List<Integer> labelList = IntStream.of(labels)
-                                           .boxed()
-                                           .collect(Collectors.toList());
-
-        for (int i=0; i<labels.length; i++) {
-            // test with invokeExact
-            if (targetTypes.contains(char.class))
-                assertEquals(i, (int) mhs.get(char.class).invokeExact((char) labels[i]));
-            if (targetTypes.contains(byte.class))
-                assertEquals(i, (int) mhs.get(byte.class).invokeExact((byte) labels[i]));
-            if (targetTypes.contains(short.class))
-                assertEquals(i, (int) mhs.get(short.class).invokeExact((short) labels[i]));
-            if (targetTypes.contains(int.class))
-                assertEquals(i, (int) mhs.get(int.class).invokeExact(labels[i]));
-            if (targetTypes.contains(Integer.class))
-                assertEquals(i, (int) mhs.get(Integer.class).invokeExact((Integer) labels[i]));
-            if (targetTypes.contains(Short.class))
-                assertEquals(i, (int) mhs.get(Short.class).invokeExact((Short) (short) labels[i]));
-            if (targetTypes.contains(Byte.class))
-                assertEquals(i, (int) mhs.get(Byte.class).invokeExact((Byte) (byte) labels[i]));
-            if (targetTypes.contains(Character.class))
-                assertEquals(i, (int) mhs.get(Character.class).invokeExact((Character) (char) labels[i]));
-
-            // and with invoke
-            assertEquals(i, (int) mhs.get(int.class).invoke(labels[i]));
-            assertEquals(i, (int) mhs.get(Integer.class).invoke(labels[i]));
-        }
-
-        for (int i=-1000; i<1000; i++) {
-            if (!labelList.contains(i)) {
-                assertEquals(labels.length, mhs.get(short.class).invoke((short) i));
-                assertEquals(labels.length, mhs.get(Short.class).invoke((short) i));
-                assertEquals(labels.length, mhs.get(int.class).invoke(i));
-                assertEquals(labels.length, mhs.get(Integer.class).invoke(i));
-                if (i >= 0) {
-                    assertEquals(labels.length, mhs.get(char.class).invoke((char)i));
-                    assertEquals(labels.length, mhs.get(Character.class).invoke((char)i));
-                }
-                if (i >= -128 && i <= 127) {
-                    assertEquals(labels.length, mhs.get(byte.class).invoke((byte)i));
-                    assertEquals(labels.length, mhs.get(Byte.class).invoke((byte)i));
-                }
-            }
-        }
-
-        assertEquals(-1, (int) mhs.get(Integer.class).invoke(null));
-        assertEquals(-1, (int) mhs.get(Short.class).invoke(null));
-        assertEquals(-1, (int) mhs.get(Byte.class).invoke(null));
-        assertEquals(-1, (int) mhs.get(Character.class).invoke(null));
-    }
-
-    private void testFloat(float... labels) throws Throwable {
-        Map<Class<?>, MethodHandle> mhs
-                = Map.of(float.class, ((CallSite) BSM_FLOAT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(float.class), labels)).dynamicInvoker(),
-                         Float.class, ((CallSite) BSM_FLOAT_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Float.class), labels)).dynamicInvoker());
-
-        List<Float> labelList = new ArrayList<>();
-        for (float label : labels)
-            labelList.add(label);
-
-        for (int i=0; i<labels.length; i++) {
-            assertEquals(i, (int) mhs.get(float.class).invokeExact((float) labels[i]));
-            assertEquals(i, (int) mhs.get(Float.class).invokeExact((Float) labels[i]));
-        }
-
-        float[] someFloats = { 1.0f, Float.MIN_VALUE, 3.14f };
-        for (float f : someFloats) {
-            if (!labelList.contains(f)) {
-                assertEquals(labels.length, mhs.get(float.class).invoke((float) f));
-                assertEquals(labels.length, mhs.get(Float.class).invoke((float) f));
-            }
-        }
-
-        assertEquals(-1, (int) mhs.get(Float.class).invoke(null));
-    }
-
-    private void testDouble(double... labels) throws Throwable {
-        Map<Class<?>, MethodHandle> mhs
-                = Map.of(double.class, ((CallSite) BSM_DOUBLE_SWITCH.invoke(MethodHandles.lookup(), "", switchType(double.class), labels)).dynamicInvoker(),
-                         Double.class, ((CallSite) BSM_DOUBLE_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Double.class), labels)).dynamicInvoker());
-
-        var labelList = new ArrayList<Double>();
-        for (double label : labels)
-            labelList.add(label);
-
-        for (int i=0; i<labels.length; i++) {
-            assertEquals(i, (int) mhs.get(double.class).invokeExact((double) labels[i]));
-            assertEquals(i, (int) mhs.get(Double.class).invokeExact((Double) labels[i]));
-        }
-
-        double[] someDoubles = { 1.0, Double.MIN_VALUE, 3.14 };
-        for (double f : someDoubles) {
-            if (!labelList.contains(f)) {
-                assertEquals(labels.length, mhs.get(double.class).invoke((double) f));
-                assertEquals(labels.length, mhs.get(Double.class).invoke((double) f));
-            }
-        }
-
-        assertEquals(-1, (int) mhs.get(Double.class).invoke(null));
-    }
-
-    private void testLong(long... labels) throws Throwable {
-        Map<Class<?>, MethodHandle> mhs
-                = Map.of(long.class, ((CallSite) BSM_LONG_SWITCH.invoke(MethodHandles.lookup(), "", switchType(long.class), labels)).dynamicInvoker(),
-                         Long.class, ((CallSite) BSM_LONG_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Long.class), labels)).dynamicInvoker());
-
-        List<Long> labelList = new ArrayList<>();
-        for (long label : labels)
-            labelList.add(label);
-
-        for (int i=0; i<labels.length; i++) {
-            assertEquals(i, (int) mhs.get(long.class).invokeExact((long) labels[i]));
-            assertEquals(i, (int) mhs.get(Long.class).invokeExact((Long) labels[i]));
-        }
-
-        long[] someLongs = { 1L, Long.MIN_VALUE, Long.MAX_VALUE };
-        for (long l : someLongs) {
-            if (!labelList.contains(l)) {
-                assertEquals(labels.length, mhs.get(long.class).invoke((long) l));
-                assertEquals(labels.length, mhs.get(Long.class).invoke((long) l));
-            }
-        }
-
-        assertEquals(-1, (int) mhs.get(Long.class).invoke(null));
-    }
-
-    private void testString(String... targets) throws Throwable {
-        MethodHandle indy = ((CallSite) BSM_STRING_SWITCH.invoke(MethodHandles.lookup(), "", switchType(String.class), targets)).dynamicInvoker();
-        List<String> targetList = Stream.of(targets)
-                                        .collect(Collectors.toList());
-
-        for (int i=0; i<targets.length; i++) {
-            String s = targets[i];
-            int result = (int) indy.invoke(s);
-            assertEquals((s == null) ? -1 : i, result);
-        }
-
-        for (String s : List.of("", "A", "AA", "AAA", "AAAA")) {
-            if (!targetList.contains(s)) {
-                assertEquals(targets.length, indy.invoke(s));
-            }
-        }
-        assertEquals(-1, (int) indy.invoke(null));
-    }
-
-    private<E extends Enum<E>> void testEnum(Class<E> enumClass, String... targets) throws Throwable {
-        MethodHandle indy = ((CallSite) BSM_ENUM_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Enum.class), enumClass, targets)).dynamicInvoker();
-        List<E> targetList = Stream.of(targets)
-                                   .map(s -> Enum.valueOf(enumClass, s))
-                                   .collect(Collectors.toList());
-
-        for (int i=0; i<targets.length; i++) {
-            String s = targets[i];
-            E e = Enum.valueOf(enumClass, s);
-            int result = (int) indy.invoke(e);
-            assertEquals((s == null) ? -1 : i, result);
-        }
-
-        for (E e : enumClass.getEnumConstants()) {
-            int index = (int) indy.invoke(e);
-            if (targetList.contains(e))
-                assertEquals(e.name(), targets[index]);
-            else
-                assertEquals(targets.length, index);
-        }
-
-        assertEquals(-1, (int) indy.invoke(null));
-    }
-
-    public void testBoolean() throws Throwable {
-        testBoolean(new boolean[0]);
-        testBoolean(false);
-        testBoolean(true);
-        testBoolean(false, true);
-    }
-
-    public void testInt() throws Throwable {
-        testInt(ALL_INT_TYPES, 8, 6, 7, 5, 3, 0, 9);
-        testInt(ALL_INT_TYPES, 1, 2, 4, 8, 16);
-        testInt(ALL_INT_TYPES, 5, 4, 3, 2, 1, 0);
-        testInt(SIGNED_TYPES, 5, 4, 3, 2, 1, 0, -1);
-        testInt(SIGNED_TYPES, -1);
-        testInt(ALL_INT_TYPES, new int[] { });
-
-        for (int i=0; i<5; i++) {
-            int len = 50 + random.nextInt(800);
-            int[] arr = IntStream.generate(() -> random.nextInt(10000) - 5000)
-                                 .distinct()
-                                 .limit(len)
-                                 .toArray();
-            testInt(SIGNED_NON_BYTE_TYPES, arr);
-
-            arr = IntStream.generate(() -> random.nextInt(10000))
-                    .distinct()
-                    .limit(len)
-                    .toArray();
-            testInt(CHAR_TYPES, arr);
-
-            arr = IntStream.generate(() -> random.nextInt(127) - 64)
-                           .distinct()
-                           .limit(120)
-                           .toArray();
-            testInt(BYTE_TYPES, arr);
-        }
-    }
-
-    public void testLong() throws Throwable {
-        testLong(1L, Long.MIN_VALUE, Long.MAX_VALUE);
-        testLong(8L, 2L, 5L, 4L, 3L, 9L, 1L);
-        testLong(new long[] { });
-
-        // @@@ Random tests
-        // @@@ More tests for weird values
-    }
-
-    public void testFloat() throws Throwable {
-        testFloat(0.0f, -0.0f, -1.0f, 1.0f, 3.14f, Float.MIN_VALUE, Float.MAX_VALUE, Float.POSITIVE_INFINITY, Float.NEGATIVE_INFINITY);
-        testFloat(new float[] { });
-        testFloat(0.0f, 1.0f, 3.14f, Float.NaN);
-
-        // @@@ Random tests
-        // @@@ More tests for weird values
-    }
-
-    public void testDouble() throws Throwable {
-        testDouble(0.0, -0.0, -1.0, 1.0, 3.14, Double.MIN_VALUE, Double.MAX_VALUE,
-                   Double.POSITIVE_INFINITY, Double.NEGATIVE_INFINITY);
-        testDouble(new double[] { });
-        testDouble(0.0f, 1.0f, 3.14f, Double.NaN);
-
-        // @@@ Random tests
-        // @@@ More tests for weird values
-    }
-
-    public void testString() throws Throwable {
-        testString("a", "b", "c");
-        testString("c", "b", "a");
-        testString("cow", "pig", "horse", "orangutan", "elephant", "dog", "frog", "ant");
-        testString("a", "b", "c", "A", "B", "C");
-        testString("C", "B", "A", "c", "b", "a");
-
-        // Tests with hash collisions; Ba/CB, Ca/DB
-        testString("Ba", "CB");
-        testString("Ba", "CB", "Ca", "DB");
-
-        // Test with null
-        try {
-            testString("a", null, "c");
-            fail("expected failure");
-        }
-        catch (IllegalArgumentException t) {
-            // success
-        }
-    }
-
-    enum E1 { A, B }
-    enum E2 { C, D, E, F, G, H }
-
-    public void testEnum() throws Throwable {
-        testEnum(E1.class);
-        testEnum(E1.class, "A");
-        testEnum(E1.class, "A", "B");
-        testEnum(E1.class, "B", "A");
-        testEnum(E2.class, "C");
-        testEnum(E2.class, "C", "D", "E", "F", "H");
-        testEnum(E2.class, "H", "C", "G", "D", "F", "E");
-
-        // Bad enum class
-        try {
-            testEnum((Class) String.class, "A");
-            fail("expected failure");
-        }
-        catch (IllegalArgumentException t) {
-            // success
-        }
-
-        // Bad enum constants
-        try {
-            testEnum(E1.class, "B", "A", "FILE_NOT_FOUND");
-            fail("expected failure");
-        }
-        catch (IllegalArgumentException t) {
-            // success
-        }
-
-        // Null enum constant
-        try {
-            testEnum(E1.class, "A", null, "B");
-            fail("expected failure");
-        }
-        catch (IllegalArgumentException t) {
-            // success
-        }
-    }
-
-    private void testType(Object target, int result, Class... labels) throws Throwable {
-        MethodHandle indy = ((CallSite) BSM_TYPE_SWITCH.invoke(MethodHandles.lookup(), "", switchType(Object.class), labels)).dynamicInvoker();
-        assertEquals((int) indy.invoke(target), result);
-        assertEquals(-1, (int) indy.invoke(null));
-    }
-
-    public void testTypes() throws Throwable {
-        testType("", 0, String.class, Object.class);
-        testType("", 0, Object.class);
-        testType("", 1, Integer.class);
-        testType("", 1, Integer.class, Serializable.class);
-        testType(E1.A, 0, E1.class, Object.class);
-        testType(E2.C, 1, E1.class, Object.class);
-        testType(new Serializable() { }, 1, Comparable.class, Serializable.class);
-
-        // test failures: duplicates, nulls, dominance inversion
-    }
-}
diff --git a/test/jdk/java/lang/lang-runtime/boottest/TEST.properties b/test/jdk/java/lang/lang-runtime/boottest/TEST.properties
deleted file mode 100755
index 4d7d0f90d06..00000000000
--- a/test/jdk/java/lang/lang-runtime/boottest/TEST.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# This file identifies root(s) of the test-ng hierarchy.
-
-TestNG.dirs = .
diff --git a/test/jdk/java/lang/lang-runtime/boottest/java.base/java/lang/runtime/CarrierTest.java b/test/jdk/java/lang/lang-runtime/boottest/java.base/java/lang/runtime/CarrierTest.java
deleted file mode 100755
index 5d50e23acef..00000000000
--- a/test/jdk/java/lang/lang-runtime/boottest/java.base/java/lang/runtime/CarrierTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
- * 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.runtime;
-
-import java.lang.invoke.MethodType;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.assertEquals;
-
-/**
- * @test
- * @key randomness
- * @run testng CarrierTest
- * @summary unit tests for java.lang.runtime.ExtractorCarriers
- */
-@Test
-public class CarrierTest {
-    static final int N_ITER = 1000;
-    static final Class<?>[] TYPES = { byte.class, short.class, char.class, int.class, long.class, float.class, double.class, boolean.class, Object.class };
-
-    static Object[] byteVals = { Byte.MIN_VALUE, Byte.MAX_VALUE, (byte) -1, (byte) 0, (byte) 1, (byte) 42 };
-    static Object[] shortVals = { Short.MIN_VALUE, Short.MAX_VALUE, (short) -1, (short) 0, (short) 1, (short) 42 };
-    static Object[] charVals = { Character.MIN_VALUE, Character.MAX_VALUE, (char) 0, 'a', 'Z' };
-    static Object[] intVals = { Integer.MIN_VALUE, Integer.MAX_VALUE, -1, 0, 1, 42 };
-    static Object[] longVals = { Long.MIN_VALUE, Long.MAX_VALUE, -1L, 0L, 1L, 42L };
-    static Object[] floatVals = { Float.MIN_VALUE, Float.MAX_VALUE, -1.0f, 0.0f, 1.0f, Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY, Float.NaN };
-    static Object[] doubleVals = { Double.MIN_VALUE, Double.MAX_VALUE, -1.0d, 0.0d, 1.0d, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, Double.NaN };
-    static Object[] booleanVals = { true, false };
-    static Object[] objectVals = {null, "", "Foo", "foo", List.of(), Collections.EMPTY_SET };
-
-    // @@@ Should use RandomFactory, but can't get that to link
-    private static final Random random = new Random(System.nanoTime());
-
-    static Map<Class<?>, Object[]> primVals = Map.of(byte.class, byteVals,
-                                                     short.class, shortVals,
-                                                     char.class, charVals,
-                                                     int.class, intVals,
-                                                     long.class, longVals,
-                                                     float.class, floatVals,
-                                                     double.class, doubleVals,
-                                                     boolean.class, booleanVals);
-
-    void testCarrier(MethodType type, Object[] values) throws Throwable {
-        for (PatternCarriers.CarrierFactory cf : PatternCarriers.CarrierFactories.values()) {
-            assertEquals(type.parameterCount(), values.length);
-            Object carrier = cf.constructor(type).invokeWithArguments(values);
-            for (int i = 0; i < values.length; i++)
-                assertEquals(values[i], cf.component(type, i).invoke(carrier));
-        }
-    }
-
-    void testCarrier(MethodType type) throws Throwable {
-        // generate data, in a loop
-        for (int i=0; i<N_ITER; i++) {
-            Object[] values = new Object[type.parameterCount()];
-            for (int j=0; j<type.parameterCount(); j++) {
-                Class<?> c = type.parameterType(j);
-                Object[] vals = c.isPrimitive() ? primVals.get(c) : objectVals;
-                values[j] = vals[random.nextInt(vals.length)];
-            }
-            testCarrier(type, values);
-        }
-    }
-
-    public void testCarrier() throws Throwable {
-        Class[] lotsOfInts = new Class[252];
-        Arrays.fill(lotsOfInts, int.class);
-
-        // known types
-        for (MethodType mt : List.of(
-                MethodType.methodType(Object.class),
-                MethodType.methodType(Object.class, int.class),
-                MethodType.methodType(Object.class, int.class, int.class),
-                MethodType.methodType(Object.class, Object.class),
-                MethodType.methodType(Object.class, Object.class, Object.class),
-                MethodType.methodType(Object.class, byte.class, short.class, char.class, int.class, long.class, float.class, double.class, boolean.class),
-                MethodType.methodType(Object.class, lotsOfInts))) {
-            testCarrier(mt);
-        }
-
-        // random types
-        for (int i=0; i<N_ITER; i++) {
-            int nTypes = random.nextInt(10);
-            Class[] paramTypes = new Class[nTypes];
-            Arrays.setAll(paramTypes, ix -> TYPES[random.nextInt(TYPES.length)]);
-            testCarrier(MethodType.methodType(Object.class, paramTypes));
-        }
-    }
-}
diff --git a/test/jdk/java/security/SignedObject/Chain.java b/test/jdk/java/security/SignedObject/Chain.java
index 71fd79dd4c3..b4a5ea794e6 100644
--- a/test/jdk/java/security/SignedObject/Chain.java
+++ b/test/jdk/java/security/SignedObject/Chain.java
@@ -1,5 +1,5 @@
-/**
- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
+/*
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -71,6 +71,13 @@ static enum SigAlg {
         SHA1withDSA("SHA1withDSA"),
         SHA224withDSA("SHA224withDSA"),
         SHA256withDSA("SHA256withDSA"),
+        SHA384withDSA("SHA384withDSA"),
+        SHA512withDSA("SHA512withDSA"),
+
+        SHA3_224withDSA("SHA3-224withDSA"),
+        SHA3_256withDSA("SHA3-256withDSA"),
+        SHA3_384withDSA("SHA3-384withDSA"),
+        SHA3_512withDSA("SHA3-512withDSA"),
 
         SHA1withRSA("Sha1withrSA"),
         SHA224withRSA("SHA224withRSA"),
@@ -79,12 +86,20 @@ static enum SigAlg {
         SHA512withRSA("SHA512withRSA"),
         SHA512_224withRSA("SHA512/224withRSA"),
         SHA512_256withRSA("SHA512/256withRSA"),
+        SHA3_224withRSA("SHA3-224withRSA"),
+        SHA3_256withRSA("SHA3-256withRSA"),
+        SHA3_384withRSA("SHA3-384withRSA"),
+        SHA3_512withRSA("SHA3-512withRSA"),
 
         SHA1withECDSA("SHA1withECDSA"),
-        SHA256withECDSA("SHA256withECDSA"),
         SHA224withECDSA("SHA224withECDSA"),
+        SHA256withECDSA("SHA256withECDSA"),
         SHA384withECDSA("SHA384withECDSA"),
         SHA512withECDSA("SHA512withECDSA"),
+        SHA3_224withECDSA("SHA3-224withECDSA"),
+        SHA3_256withECDSA("SHA3-256withECDSA"),
+        SHA3_384withECDSA("SHA3-384withECDSA"),
+        SHA3_512withECDSA("SHA3-512withECDSA"),
 
         MD5andSHA1withRSA("MD5andSHA1withRSA"),
 
@@ -147,7 +162,10 @@ public String toString() {
         new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Default, 1024),
         new Test(SigAlg.MD2withRSA, KeyAlg.RSA, Provider.Default),
         new Test(SigAlg.MD5withRSA, KeyAlg.RSA, Provider.Default),
-        new Test(SigAlg.SHA1withRSA, KeyAlg.RSA, Provider.Default),
+        new Test(SigAlg.SHA3_224withRSA, KeyAlg.RSA, Provider.Default),
+        new Test(SigAlg.SHA3_256withRSA, KeyAlg.RSA, Provider.Default),
+        new Test(SigAlg.SHA3_384withRSA, KeyAlg.RSA, Provider.Default),
+        new Test(SigAlg.SHA3_512withRSA, KeyAlg.RSA, Provider.Default),
         new Test(SigAlg.SHA1withDSA, KeyAlg.DSA, Provider.Sun, 1024),
         new Test(SigAlg.SHA224withDSA, KeyAlg.DSA, Provider.Sun, 2048),
         new Test(SigAlg.SHA256withDSA, KeyAlg.DSA, Provider.Sun, 2048),
diff --git a/test/jdk/java/util/StringJoiner/MergeTest.java b/test/jdk/java/util/StringJoiner/MergeTest.java
index 181a25d4447..a2511961016 100644
--- a/test/jdk/java/util/StringJoiner/MergeTest.java
+++ b/test/jdk/java/util/StringJoiner/MergeTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
  * @summary test  StringJoiner::merge
  * @modules java.base/jdk.internal.util
  * @requires os.maxMemory > 4G
- * @run testng/othervm -Xmx4g MergeTest
+ * @run testng/othervm -Xmx4g -XX:+CompactStrings MergeTest
  */
 
 import java.util.StringJoiner;
diff --git a/test/jdk/java/util/StringJoiner/StringJoinerTest.java b/test/jdk/java/util/StringJoiner/StringJoinerTest.java
index 918823d23e9..f40179f3057 100644
--- a/test/jdk/java/util/StringJoiner/StringJoinerTest.java
+++ b/test/jdk/java/util/StringJoiner/StringJoinerTest.java
@@ -26,7 +26,7 @@
  * @summary tests StringJoinerTest
  * @modules java.base/jdk.internal.util
  * @requires os.maxMemory > 4G
- * @run testng/othervm -Xmx4g StringJoinerTest
+ * @run testng/othervm -Xmx4g -XX:+CompactStrings StringJoinerTest
  * @author Jim Gish
  */
 import java.util.ArrayList;
diff --git a/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java b/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java
new file mode 100644
index 00000000000..93c2e91fea8
--- /dev/null
+++ b/test/jdk/java/util/zip/GZIP/GZIPOutputStreamHeaderTest.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * @test
+ * @bug 8244706
+ * @summary Verify that the OS header flag in the stream written out by java.util.zip.GZIPOutputStream
+ * has the correct expected value
+ * @run testng GZIPOutputStreamHeaderTest
+ */
+public class GZIPOutputStreamHeaderTest {
+
+    private static final int OS_HEADER_INDEX = 9;
+    private static final int HEADER_VALUE_OS_UNKNOWN = 255;
+
+    /**
+     * Test that the {@code OS} header field in the GZIP output stream
+     * has a value of {@code 255} which represents "unknown"
+     */
+    @Test
+    public void testOSHeader() throws Exception {
+        final String data = "Hello world!!!";
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (final GZIPOutputStream gzipOutputStream = new GZIPOutputStream(baos);) {
+            gzipOutputStream.write(data.getBytes(StandardCharsets.UTF_8));
+        }
+        final byte[] compressed = baos.toByteArray();
+        Assert.assertNotNull(compressed, "Compressed data is null");
+        Assert.assertEquals(toUnsignedByte(compressed[OS_HEADER_INDEX]), HEADER_VALUE_OS_UNKNOWN,
+                "Unexpected value for OS header");
+        // finally verify that the compressed data is readable back to the original
+        final String uncompressed;
+        try (final ByteArrayOutputStream os = new ByteArrayOutputStream();
+             final ByteArrayInputStream bis = new ByteArrayInputStream(compressed);
+             final GZIPInputStream gzipInputStream = new GZIPInputStream(bis)) {
+            gzipInputStream.transferTo(os);
+            uncompressed = new String(os.toByteArray(), StandardCharsets.UTF_8);
+        }
+        Assert.assertEquals(uncompressed, data, "Unexpected data read from GZIPInputStream");
+    }
+
+    private static int toUnsignedByte(final byte b) {
+        return b & 0xff;
+    }
+}
diff --git a/test/jdk/javax/swing/Box/TestBoxFiller.java b/test/jdk/javax/swing/Box/TestBoxFiller.java
new file mode 100644
index 00000000000..e1dd269be0c
--- /dev/null
+++ b/test/jdk/javax/swing/Box/TestBoxFiller.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8253016
+   @key headful
+   @summary Verifies Box.Filler components should be unfocusable by default
+   @run main TestBoxFiller
+ */
+import java.awt.ContainerOrderFocusTraversalPolicy;
+import java.awt.KeyboardFocusManager;
+import java.beans.PropertyChangeEvent;
+import javax.swing.Box;
+import javax.swing.JFrame;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import java.awt.Robot;
+import java.awt.event.KeyEvent;
+
+public class TestBoxFiller
+{
+    private static JFrame frame;
+    private static void showFocusOwner(PropertyChangeEvent e)
+    {
+        Object c = e.getNewValue();
+        if (c instanceof Box.Filler) {
+            throw new RuntimeException("Box.Filler having focus");
+        }
+    }
+
+    public static void main(String[] args) throws Exception
+    {
+        try {
+            Robot robot = new Robot();
+            robot.setAutoDelay(100);
+            SwingUtilities.invokeAndWait(() -> {
+                frame = new JFrame();
+                KeyboardFocusManager m = KeyboardFocusManager.getCurrentKeyboardFocusManager();
+                m.addPropertyChangeListener("focusOwner", TestBoxFiller::showFocusOwner);
+
+                Box box = Box.createHorizontalBox();
+                JTextField tf1 = new JTextField("Test");
+                tf1.setColumns(40);
+                JTextField tf2 = new JTextField("Test");
+                tf2.setColumns(40);
+                box.add(tf1);
+                box.add(Box.createHorizontalStrut(20));
+                box.add(tf2);
+                frame.setContentPane(box);
+                frame.setFocusTraversalPolicy(new ContainerOrderFocusTraversalPolicy());
+                frame.pack();
+                frame.setVisible(true);
+                frame.setLocationRelativeTo(null);
+                tf1.requestFocusInWindow();
+            });
+            robot.waitForIdle();
+            robot.keyPress(KeyEvent.VK_TAB);
+            robot.keyRelease(KeyEvent.VK_TAB);
+        } finally {
+            if (frame != null) {
+                SwingUtilities.invokeAndWait(frame::dispose);
+            }
+        }
+    }
+}
diff --git a/test/jdk/javax/swing/JPopupMenu/7154841/bug7154841.java b/test/jdk/javax/swing/JPopupMenu/7154841/bug7154841.java
index 69508b93a3c..b7a7494c992 100644
--- a/test/jdk/javax/swing/JPopupMenu/7154841/bug7154841.java
+++ b/test/jdk/javax/swing/JPopupMenu/7154841/bug7154841.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@ public class bug7154841 {
 
     private static void initAndShowUI() {
         popupMenu = new JPopupMenu();
-        for (int i = 0; i < 100; i++) {
+        for (int i = 0; i < 400; i++) {
             JRadioButtonMenuItem item = new JRadioButtonMenuItem(" Test " + i);
             item.addMouseMotionListener(new MouseMotionAdapter() {
                 @Override
diff --git a/test/jdk/javax/swing/plaf/basic/BasicComboPopup/7072653/bug7072653.java b/test/jdk/javax/swing/plaf/basic/BasicComboPopup/7072653/bug7072653.java
index 7835c3c4da4..78160283a4a 100644
--- a/test/jdk/javax/swing/plaf/basic/BasicComboPopup/7072653/bug7072653.java
+++ b/test/jdk/javax/swing/plaf/basic/BasicComboPopup/7072653/bug7072653.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -104,11 +104,11 @@ public Object getElementAt(int index) {
 
             @Override
             public int getSize() {
-                return 100;
+                return 400;
             }
         });
 
-        combobox.setMaximumRowCount(100);
+        combobox.setMaximumRowCount(400);
         combobox.putClientProperty("JComboBox.isPopDown", true);
         frame.getContentPane().add(combobox);
         frame.setVisible(true);
diff --git a/test/jdk/jdk/jfr/tool/TestDisassemble.java b/test/jdk/jdk/jfr/tool/TestDisassemble.java
index 29d28531a02..94d2d7b4346 100644
--- a/test/jdk/jdk/jfr/tool/TestDisassemble.java
+++ b/test/jdk/jdk/jfr/tool/TestDisassemble.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
 
 /**
  * @test
+ * @bug 8253050
  * @summary Test jfr split
  * @key jfr
  * @requires vm.hasJFR
@@ -55,13 +56,16 @@ public static void main(String[] args) throws Throwable {
         Path recordingFileA = Paths.get("many-chunks-A-" + dateText + ".jfr");
         Path recordingFileB = Paths.get("many-chunks-B-" + dateText + ".jfr");
         Path recordingFileC = Paths.get("many-chunks-C-" + dateText + ".jfr");
+        Path recordingFileD = Paths.get("many-chunks-D-" + dateText + ".jfr");
         makeRecordingWithChunks(6, recordingFileA);
         Files.copy(recordingFileA, recordingFileB);
         Files.copy(recordingFileA, recordingFileC);
+        Files.copy(recordingFileA, recordingFileD);
 
         String fileAText = recordingFileA.toAbsolutePath().toString();
         String fileBText = recordingFileB.toAbsolutePath().toString();
         String fileCText = recordingFileC.toAbsolutePath().toString();
+        String fileDText = recordingFileD.toAbsolutePath().toString();
 
         OutputAnalyzer output = ExecuteHelper.jfr("disassemble");
         output.shouldContain("missing file");
@@ -97,6 +101,15 @@ public static void main(String[] args) throws Throwable {
         // sanity check
         output = ExecuteHelper.jfr("disassemble", "--max-size", "10000", fileCText);
         verifyRecording(fileCText.substring(0, fileCText.length() - 4) + "_01.jfr");
+
+        // test JDK-8253050
+        output = ExecuteHelper.jfr("disassemble", "--max-chunks", "1", fileDText);
+        String chunks = output.firstMatch("File consists of (\\d+) chunks", 1);
+        output.shouldContain("The recording will be split into " + chunks + " files");
+        String chunkFilePrefix = fileDText.substring(0, fileDText.length() - 4) + "_";
+        for (long i = 0; i < Long.parseLong(chunks); i++) {
+            verifyRecording(chunkFilePrefix + String.format("%0" + chunks.length() + "d", i) + ".jfr");
+        }
     }
 
     private static void verifyRecording(String name) throws IOException {
diff --git a/test/jdk/sun/security/ec/SignatureKAT.java b/test/jdk/sun/security/ec/SignatureKAT.java
new file mode 100644
index 00000000000..d1fa6f702cf
--- /dev/null
+++ b/test/jdk/sun/security/ec/SignatureKAT.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import jdk.test.lib.Convert;
+
+import java.security.*;
+import java.security.spec.*;
+import java.math.*;
+import java.util.*;
+
+/*
+ * @test
+ * @bug 8172366
+ * @summary Known Answer Test for ECDSA signature
+ * @library /test/lib
+ * @build jdk.test.lib.Convert
+ * @run main/othervm SignatureKAT
+ */
+public class SignatureKAT {
+
+    private static String checkHex(String hex) {
+        // if hex length is odd, need to prepend 0
+        if (hex.length() % 2 != 0) {
+            hex = "0" + hex;
+        }
+        return hex;
+    }
+
+    private static class CurveData {
+        private String name;
+        private byte[] msgBytes;
+        private BigInteger priv;
+        private BigInteger pubX;
+        private BigInteger pubY;
+
+        private static BigInteger toBigInteger(String hex) {
+            byte[] bytes = Convert.hexStringToByteArray(checkHex(hex));
+            return new BigInteger(1, bytes);
+        }
+        CurveData(String name, String msg, String priv, String pubX,
+                String pubY) {
+            this.name = name;
+            this.msgBytes = msg.getBytes();
+            this.priv = toBigInteger(priv);
+            this.pubX = toBigInteger(pubX);
+            this.pubY = toBigInteger(pubY);
+        }
+    }
+
+    private static class TestData {
+        private String sigName;
+        private CurveData cd;
+        private byte[] expSig;
+
+        TestData(String sigName, CurveData cd, String r, String s) {
+            this.sigName = sigName;
+            this.cd = cd;
+            if (r.length() != s.length() || r != checkHex(r) ||
+                s != checkHex(s)) {
+                throw new RuntimeException("Error: invalid r, s");
+            }
+            this.expSig = Convert.hexStringToByteArray(r + s);
+        }
+    }
+
+    // These test values are from the examples shown in the page below:
+    // https://csrc.nist.gov/projects/cryptographic-standards-and-guidelines/example-values
+    private static final CurveData P_256 = new CurveData(
+        "secp256r1", "Example of ECDSA with P-256",
+        "C477F9F65C22CCE20657FAA5B2D1D8122336F851A508A1ED04E479C34985BF96",
+        "B7E08AFDFE94BAD3F1DC8C734798BA1C62B3A0AD1E9EA2A38201CD0889BC7A19",
+        "3603F747959DBF7A4BB226E41928729063ADC7AE43529E61B563BBC606CC5E09"
+    );
+
+    private static final CurveData P_384 = new CurveData(
+        "secp384r1", "Example of ECDSA with P-384",
+        "F92C02ED629E4B48C0584B1C6CE3A3E3B4FAAE4AFC6ACB0455E73DFC392E6A0AE393A8565E6B9714D1224B57D83F8A08",
+        "3BF701BC9E9D36B4D5F1455343F09126F2564390F2B487365071243C61E6471FB9D2AB74657B82F9086489D9EF0F5CB5",
+        "D1A358EAFBF952E68D533855CCBDAA6FF75B137A5101443199325583552A6295FFE5382D00CFCDA30344A9B5B68DB855"
+    );
+
+    private static final CurveData P_521 = new CurveData(
+        "secp521r1", "Example of ECDSA with P-521",
+        "100085F47B8E1B8B11B7EB33028C0B2888E304BFC98501955B45BBA1478DC184EEEDF09B86A5F7C21994406072787205E69A63709FE35AA93BA333514B24F961722",
+        "98E91EEF9A68452822309C52FAB453F5F117C1DA8ED796B255E9AB8F6410CCA16E59DF403A6BDC6CA467A37056B1E54B3005D8AC030DECFEB68DF18B171885D5C4",
+        "164350C321AECFC1CCA1BA4364C9B15656150B4B78D6A48D7D28E7F31985EF17BE8554376B72900712C4B83AD668327231526E313F5F092999A4632FD50D946BC2E"
+    );
+
+    private static TestData[] TEST_DATUM = {
+        // secp256r1, secp384r1, and secp521r1 remain enabled
+        new TestData("SHA256withECDSAinP1363Format", P_256,
+            "2B42F576D07F4165FF65D1F3B1500F81E44C316F1F0B3EF57325B69ACA46104F",
+            "DC42C2122D6392CD3E3A993A89502A8198C1886FE69D262C4B329BDB6B63FAF1"),
+        new TestData("SHA3-256withECDSAinP1363Format", P_256,
+            "2B42F576D07F4165FF65D1F3B1500F81E44C316F1F0B3EF57325B69ACA46104F",
+            "0A861C2526900245C73BACB9ADAEC1A5ACB3BA1F7114A3C334FDCD5B7690DADD"),
+        new TestData("SHA384withECDSAinP1363Format", P_384,
+            "30EA514FC0D38D8208756F068113C7CADA9F66A3B40EA3B313D040D9B57DD41A332795D02CC7D507FCEF9FAF01A27088",
+            "CC808E504BE414F46C9027BCBF78ADF067A43922D6FCAA66C4476875FBB7B94EFD1F7D5DBE620BFB821C46D549683AD8"),
+        new TestData("SHA3-384withECDSAinP1363Format", P_384,
+            "30EA514FC0D38D8208756F068113C7CADA9F66A3B40EA3B313D040D9B57DD41A332795D02CC7D507FCEF9FAF01A27088",
+            "691B9D4969451A98036D53AA725458602125DE74881BBC333012CA4FA55BDE39D1BF16A6AAE3FE4992C567C6E7892337"),
+        new TestData("SHA512withECDSAinP1363Format", P_521,
+            "0140C8EDCA57108CE3F7E7A240DDD3AD74D81E2DE62451FC1D558FDC79269ADACD1C2526EEEEF32F8C0432A9D56E2B4A8A732891C37C9B96641A9254CCFE5DC3E2BA",
+            "00D72F15229D0096376DA6651D9985BFD7C07F8D49583B545DB3EAB20E0A2C1E8615BD9E298455BDEB6B61378E77AF1C54EEE2CE37B2C61F5C9A8232951CB988B5B1"),
+        new TestData("SHA3-512withECDSAinP1363Format", P_521,
+            "0140C8EDCA57108CE3F7E7A240DDD3AD74D81E2DE62451FC1D558FDC79269ADACD1C2526EEEEF32F8C0432A9D56E2B4A8A732891C37C9B96641A9254CCFE5DC3E2BA",
+            "00B25188492D58E808EDEBD7BF440ED20DB771CA7C618595D5398E1B1C0098E300D8C803EC69EC5F46C84FC61967A302D366C627FCFA56F87F241EF921B6E627ADBF"),
+    };
+
+    private static void runTest(TestData td) throws Exception {
+        System.out.println("Testing " + td.sigName + " with " + td.cd.name);
+
+        AlgorithmParameters params =
+            AlgorithmParameters.getInstance("EC", "SunEC");
+        params.init(new ECGenParameterSpec(td.cd.name));
+        ECParameterSpec ecParams =
+            params.getParameterSpec(ECParameterSpec.class);
+
+        KeyFactory kf = KeyFactory.getInstance("EC", "SunEC");
+        PrivateKey privKey = kf.generatePrivate
+                (new ECPrivateKeySpec(td.cd.priv, ecParams));
+
+        Signature sig = Signature.getInstance(td.sigName, "SunEC");
+        sig.initSign(privKey);
+        sig.update(td.cd.msgBytes);
+        // NOTE: there is no way to set the nonce value into current SunEC
+        // ECDSA signature, thus the output signature bytes likely won't
+        // match the expected signature bytes
+        byte[] ov = sig.sign();
+
+        ECPublicKeySpec pubKeySpec = new ECPublicKeySpec
+                (new ECPoint(td.cd.pubX, td.cd.pubY), ecParams);
+        PublicKey pubKey = kf.generatePublic(pubKeySpec);
+
+        sig.initVerify(pubKey);
+        sig.update(td.cd.msgBytes);
+        if (!sig.verify(ov)) {
+            throw new RuntimeException("Error verifying actual sig bytes");
+        }
+
+        sig.update(td.cd.msgBytes);
+        if (!sig.verify(td.expSig)) {
+            throw new RuntimeException("Error verifying expected sig bytes");
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        for (TestData td : TEST_DATUM) {
+            runTest(td);
+        }
+    }
+}
diff --git a/test/jdk/sun/security/ec/SignatureOffsets.java b/test/jdk/sun/security/ec/SignatureOffsets.java
index 3570258c861..3ea886a3f2a 100644
--- a/test/jdk/sun/security/ec/SignatureOffsets.java
+++ b/test/jdk/sun/security/ec/SignatureOffsets.java
@@ -43,6 +43,10 @@
  * @run main SignatureOffsets SunEC SHA224withECDSA
  * @run main SignatureOffsets SunEC SHA384withECDSA
  * @run main SignatureOffsets SunEC SHA512withECDSA
+ * @run main SignatureOffsets SunEC SHA3-256withECDSA
+ * @run main SignatureOffsets SunEC SHA3-224withECDSA
+ * @run main SignatureOffsets SunEC SHA3-384withECDSA
+ * @run main SignatureOffsets SunEC SHA3-512withECDSA
  */
 public class SignatureOffsets {
 
diff --git a/test/jdk/sun/security/ec/SignedObjectChain.java b/test/jdk/sun/security/ec/SignedObjectChain.java
index 6a5b7c93f66..cfeff8c1ad5 100644
--- a/test/jdk/sun/security/ec/SignedObjectChain.java
+++ b/test/jdk/sun/security/ec/SignedObjectChain.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8050374 8146293
+ * @bug 8050374 8146293 8172366
  * @summary Verify a chain of signed objects
  * @library /test/lib
  * @build jdk.test.lib.SigTestUtil
@@ -41,10 +41,14 @@ public Test(Chain.SigAlg sigAlg) {
 
     private static final Test[] tests = {
         new Test(Chain.SigAlg.SHA1withECDSA),
-        new Test(Chain.SigAlg.SHA256withECDSA),
         new Test(Chain.SigAlg.SHA224withECDSA),
+        new Test(Chain.SigAlg.SHA256withECDSA),
         new Test(Chain.SigAlg.SHA384withECDSA),
         new Test(Chain.SigAlg.SHA512withECDSA),
+        new Test(Chain.SigAlg.SHA3_224withECDSA),
+        new Test(Chain.SigAlg.SHA3_256withECDSA),
+        new Test(Chain.SigAlg.SHA3_384withECDSA),
+        new Test(Chain.SigAlg.SHA3_512withECDSA),
     };
 
     public static void main(String argv[]) {
diff --git a/test/jdk/sun/security/rsa/SignatureOffsets.java b/test/jdk/sun/security/rsa/SignatureOffsets.java
index 1db628cac31..15df99c4665 100644
--- a/test/jdk/sun/security/rsa/SignatureOffsets.java
+++ b/test/jdk/sun/security/rsa/SignatureOffsets.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
 
 /*
  * @test
- * @bug 8050374 8146293
+ * @bug 8050374 8146293 8172366
  * @key randomness
  * @summary This test validates signature verification
  *          Signature.verify(byte[], int, int). The test uses RandomFactory to
@@ -46,6 +46,10 @@
  * @run main SignatureOffsets SunRsaSign SHA512withRSA
  * @run main SignatureOffsets SunRsaSign SHA512/224withRSA
  * @run main SignatureOffsets SunRsaSign SHA512/256withRSA
+ * @run main SignatureOffsets SunRsaSign SHA3-224withRSA
+ * @run main SignatureOffsets SunRsaSign SHA3-256withRSA
+ * @run main SignatureOffsets SunRsaSign SHA3-384withRSA
+ * @run main SignatureOffsets SunRsaSign SHA3-512withRSA
  */
 public class SignatureOffsets {
 
diff --git a/test/jdk/sun/security/rsa/pss/PSSParametersTest.java b/test/jdk/sun/security/rsa/pss/PSSParametersTest.java
index 2fde948fdc9..c71e5bb34a4 100644
--- a/test/jdk/sun/security/rsa/pss/PSSParametersTest.java
+++ b/test/jdk/sun/security/rsa/pss/PSSParametersTest.java
@@ -31,7 +31,7 @@
 
 /**
  * @test
- * @bug 8146293 8242556
+ * @bug 8146293 8242556 8172366
  * @summary Test RSASSA-PSS AlgorithmParameters impl of SunRsaSign provider.
  * @run main PSSParametersTest
  */
@@ -50,6 +50,8 @@ public static void main(String[] args) throws Exception {
         System.out.println("Testing against custom parameters");
         test(new PSSParameterSpec("SHA-512/224", "MGF1",
                 MGF1ParameterSpec.SHA384, 100, 1));
+        test(new PSSParameterSpec("SHA3-256", "MGF1",
+            new MGF1ParameterSpec("SHA3-256"), 256>>3, 1));
         System.out.println("Test Passed");
     }
 
@@ -57,6 +59,7 @@ public static void main(String[] args) throws Exception {
     // bytes, then initialize w/ the DER bytes, retrieve the spec.
     // compare both spec for equality and throw exception if the check failed.
     private static void test(PSSParameterSpec spec) throws Exception {
+        System.out.println("Testing PSS spec: " + spec);
         String ALGORITHMS[] = { PSS_ALGO, PSS_OID };
         for (String alg : ALGORITHMS) {
             AlgorithmParameters params = AlgorithmParameters.getInstance
@@ -67,9 +70,9 @@ private static void test(PSSParameterSpec spec) throws Exception {
                     (alg, PROVIDER);
             params2.init(encoded);
             PSSParameterSpec spec2 = params2.getParameterSpec
-                (PSSParameterSpec.class);
+                    (PSSParameterSpec.class);
             if (!isEqual(spec, spec2)) {
-                throw new RuntimeException("Spec check Failed for " +  alg);
+                throw new RuntimeException("Spec check Failed for " + alg);
             }
         }
     }
diff --git a/test/jdk/sun/security/rsa/pss/SignatureTest2.java b/test/jdk/sun/security/rsa/pss/SignatureTest2.java
index f5104842001..ea548d04dad 100644
--- a/test/jdk/sun/security/rsa/pss/SignatureTest2.java
+++ b/test/jdk/sun/security/rsa/pss/SignatureTest2.java
@@ -31,7 +31,7 @@
 
 /**
  * @test
- * @bug 8146293 8238448
+ * @bug 8146293 8238448 8172366
  * @summary Create a signature for RSASSA-PSS and get its signed data.
  *          re-initiate the signature with the public key. The signature
  *          can be verified by acquired signed data.
@@ -68,7 +68,8 @@ public class SignatureTest2 {
      */
     private static final String[] DIGEST_ALG = {
         "SHA-1", "SHA-224", "SHA-256", "SHA-384",
-        "SHA-512", "SHA-512/224", "SHA-512/256"
+        "SHA-512", "SHA-512/224", "SHA-512/256",
+        "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512"
     };
 
     private static final String SIG_ALG = "RSASSA-PSS";
diff --git a/test/jdk/sun/security/rsa/pss/TestPSSKeySupport.java b/test/jdk/sun/security/rsa/pss/TestPSSKeySupport.java
index c9c7a27e186..7db7774870c 100644
--- a/test/jdk/sun/security/rsa/pss/TestPSSKeySupport.java
+++ b/test/jdk/sun/security/rsa/pss/TestPSSKeySupport.java
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 8146293 8242556
+ * @bug 8146293 8242556 8172366
  * @summary Test RSASSA-PSS Key related support such as KeyPairGenerator
  * and KeyFactory of the SunRsaSign provider
  */
@@ -145,11 +145,18 @@ public static void main(String[] args) throws Exception {
         KeyPair kp2 = kpg.generateKeyPair();
         checkKeyPair(kp2);
 
+        params = new PSSParameterSpec("SHA3-256", "MGF1",
+            new MGF1ParameterSpec("SHA3-256"), 32, 1);
+        kpg.initialize(new RSAKeyGenParameterSpec(2048, pubExp, params));
+        KeyPair kp3 = kpg.generateKeyPair();
+        checkKeyPair(kp3);
+
         KeyFactory kf = KeyFactory.getInstance(ALGO, "SunRsaSign");
         test(kf, kp.getPublic());
         test(kf, kp.getPrivate());
         test(kf, kp2.getPublic());
         test(kf, kp2.getPrivate());
-
+        test(kf, kp3.getPublic());
+        test(kf, kp3.getPrivate());
     }
 }
diff --git a/test/langtools/jdk/jshell/CompletionSuggestionTest.java b/test/langtools/jdk/jshell/CompletionSuggestionTest.java
index b78b25e33df..1a024e29887 100644
--- a/test/langtools/jdk/jshell/CompletionSuggestionTest.java
+++ b/test/langtools/jdk/jshell/CompletionSuggestionTest.java
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8131025 8141092 8153761 8145263 8131019 8175886 8176184 8176241 8176110 8177466 8197439 8221759 8234896
+ * @bug 8131025 8141092 8153761 8145263 8131019 8175886 8176184 8176241 8176110 8177466 8197439 8221759 8234896 8240658
  * @summary Test Completion and Documentation
  * @library /tools/lib
  * @modules jdk.compiler/com.sun.tools.javac.api
@@ -698,6 +698,27 @@ public void testMemberReferences() {
         assertCompletion("FI2<Object, String> fi = C::|", true, "statConvert1", "statConvert3");
     }
 
+    public void testBrokenLambdaCompletion() {
+        assertEval("interface Consumer<T> { public void consume(T t); }");
+        assertEval("interface Function<T, R> { public R convert(T t); }");
+        assertEval("<T> void m1(T t, Consumer<T> f) { }");
+        assertCompletion("m1(\"\", x -> {x.tri|", "trim()");
+        assertEval("<T> void m2(T t, Function<T, String> f) { }");
+        assertCompletion("m2(\"\", x -> {x.tri|", "trim()");
+        assertEval("<T> void m3(T t, Consumer<T> f, int i) { }");
+        assertCompletion("m3(\"\", x -> {x.tri|", "trim()");
+        assertEval("<T> void m4(T t, Function<T, String> f, int i) { }");
+        assertCompletion("m4(\"\", x -> {x.tri|", "trim()");
+        assertEval("<T> T m5(Consumer<T> f) { return null; }");
+        assertCompletion("String s = m5(x -> {x.tri|", "trim()");
+        assertEval("<T> T m6(Function<T, String> f) { return null; }");
+        assertCompletion("String s = m6(x -> {x.tri|", "trim()");
+        assertEval("<T> T m7(Consumer<T> f, int i) { return null; }");
+        assertCompletion("String s = m7(x -> {x.tri|", "trim()");
+        assertEval("<T> T m8(Function<T, String> f, int i) { return null; }");
+        assertCompletion("String s = m8(x -> {x.tri|", "trim()");
+    }
+
     @BeforeMethod
     public void setUp() {
         super.setUp();
diff --git a/test/langtools/tools/doclint/CoverageExtras.java b/test/langtools/tools/doclint/CoverageExtras.java
index 5db3edf1a0e..67288cfa41c 100644
--- a/test/langtools/tools/doclint/CoverageExtras.java
+++ b/test/langtools/tools/doclint/CoverageExtras.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,7 +21,7 @@
  * questions.
  */
 
-/**
+/*
  * @test
  * @bug 8006263
  * @summary Supplementary test cases needed for doclint
@@ -29,7 +29,6 @@
  */
 
 import com.sun.tools.doclint.Checker;
-import com.sun.tools.doclint.Entity;
 import com.sun.tools.doclint.HtmlTag;
 import com.sun.tools.doclint.Messages;
 import java.util.Objects;
diff --git a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Patterns.java b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Patterns.java
index 74be213312f..ce453a2779c 100644
--- a/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Patterns.java
+++ b/test/langtools/tools/javac/annotations/typeAnnotations/classfile/Patterns.java
@@ -46,10 +46,11 @@ public class Patterns {
     private ToolBox tb = new ToolBox();
 
     public static void main(String[] args) throws Exception {
-        new Patterns().run();
+        new Patterns().runBinding();
+        new Patterns().runDeconstruction();
     }
 
-    public void run() throws Exception {
+    public void runBinding() throws Exception {
         String out = new JavapTask(tb)
                 .options("-private",
                          "-verbose")
@@ -162,6 +163,112 @@ public void run() throws Exception {
         }
     }
 
+    public void runDeconstruction() throws Exception {
+        String out = new JavapTask(tb)
+                .options("-private",
+                         "-verbose")
+                .classpath(System.getProperty("test.classes"))
+                .classes("Patterns$DeconstructionPattern")
+                .run()
+                .getOutputLines(Task.OutputKind.DIRECT)
+                .stream()
+                .collect(Collectors.joining("\n"));
+
+        String constantPool = out.substring(0, out.indexOf('{'));
+
+        out = out.replaceAll("(?ms) *Code:.*?\n( *RuntimeInvisibleTypeAnnotations:)", "$1");
+        out = out.substring(out.indexOf('{'));
+        out = out.substring(0, out.lastIndexOf('}') + 1);
+
+        String A = snipCPNumber(constantPool, "LPatterns$DeconstructionPattern$A;");
+        String CA = snipCPNumber(constantPool, "LPatterns$DeconstructionPattern$CA;");
+        String value = snipCPNumber(constantPool, "value");
+
+        String expected = """
+                          {
+                            private static final java.lang.Object o;
+                              descriptor: Ljava/lang/Object;
+                              flags: (0x001a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL
+
+                            private static final boolean B1s;
+                              descriptor: Z
+                              flags: (0x001a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL
+
+                            private static final boolean B1m;
+                              descriptor: Z
+                              flags: (0x001a) ACC_PRIVATE, ACC_STATIC, ACC_FINAL
+
+                            private final boolean B2s;
+                              descriptor: Z
+                              flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+
+                            private final boolean B2m;
+                              descriptor: Z
+                              flags: (0x0012) ACC_PRIVATE, ACC_FINAL
+
+                            public Patterns$DeconstructionPattern();
+                              descriptor: ()V
+                              flags: (0x0001) ACC_PUBLIC
+                                RuntimeInvisibleTypeAnnotations:
+                                  0: #_A_(): LOCAL_VARIABLE, {start_pc=284, length=11, index=2}
+                                    Patterns$DeconstructionPattern$A
+                                  1: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=328, length=11, index=3}
+                                    Patterns$DeconstructionPattern$CA(
+                                      value=[@Patterns$DeconstructionPattern$A,@Patterns$DeconstructionPattern$A]
+                                    )
+                                  2: #_A_(): LOCAL_VARIABLE, {start_pc=30, length=11, index=1}
+                                    Patterns$DeconstructionPattern$A
+                                  3: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=71, length=11, index=1}
+                                    Patterns$DeconstructionPattern$CA(
+                                      value=[@Patterns$DeconstructionPattern$A,@Patterns$DeconstructionPattern$A]
+                                    )
+                                  4: #_A_(): LOCAL_VARIABLE, {start_pc=114, length=11, index=2}
+                                    Patterns$DeconstructionPattern$A
+                                  5: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=158, length=11, index=3}
+                                    Patterns$DeconstructionPattern$CA(
+                                      value=[@Patterns$DeconstructionPattern$A,@Patterns$DeconstructionPattern$A]
+                                    )
+                                  6: #_A_(): LOCAL_VARIABLE, {start_pc=199, length=11, index=2}
+                                    Patterns$DeconstructionPattern$A
+                                  7: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=243, length=11, index=3}
+                                    Patterns$DeconstructionPattern$CA(
+                                      value=[@Patterns$DeconstructionPattern$A,@Patterns$DeconstructionPattern$A]
+                                    )
+
+                            void testPatterns();
+                              descriptor: ()V
+                              flags: (0x0000)
+                                RuntimeInvisibleTypeAnnotations:
+                                  0: #_A_(): LOCAL_VARIABLE, {start_pc=28, length=11, index=2}
+                                    Patterns$DeconstructionPattern$A
+                                  1: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=72, length=11, index=3}
+                                    Patterns$DeconstructionPattern$CA(
+                                      value=[@Patterns$DeconstructionPattern$A,@Patterns$DeconstructionPattern$A]
+                                    )
+
+                            static {};
+                              descriptor: ()V
+                              flags: (0x0008) ACC_STATIC
+                                RuntimeInvisibleTypeAnnotations:
+                                  0: #_A_(): LOCAL_VARIABLE, {start_pc=30, length=11, index=0}
+                                    Patterns$DeconstructionPattern$A
+                                  1: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=70, length=11, index=0}
+                                    Patterns$DeconstructionPattern$CA(
+                                      value=[@Patterns$DeconstructionPattern$A,@Patterns$DeconstructionPattern$A]
+                                    )
+                                  2: #_A_(): LOCAL_VARIABLE, {start_pc=110, length=11, index=1}
+                                    Patterns$DeconstructionPattern$A
+                                  3: #_CA_(#_value_=[@#_A_(),@#_A_()]): LOCAL_VARIABLE, {start_pc=151, length=11, index=2}
+                                    Patterns$DeconstructionPattern$CA(
+                                      value=[@Patterns$DeconstructionPattern$A,@Patterns$DeconstructionPattern$A]
+                                    )
+                          }""".replace("_A_", A).replace("_CA_", CA).replace("_value_", value);
+
+        if (!expected.equals(out)) {
+            throw new AssertionError("Unexpected output:\n" + out + "\nexpected:\n" + expected);
+        }
+    }
+
     private String snipCPNumber(String constantPool, String expectedConstant) {
         Matcher m = Pattern.compile("#([0-9]+).*" + Pattern.quote(expectedConstant))
                            .matcher(constantPool);
@@ -219,4 +326,47 @@ void testPatternsDesugared() {
             boolean B8sx = o instanceof String && (s = (String) o) == s && s.isEmpty();
         }
     }
+
+    static class DeconstructionPattern {
+        @Target(ElementType.TYPE_USE)
+        @Repeatable(CA.class)
+        @interface A {}
+        @Target(ElementType.TYPE_USE)
+        @interface CA {
+            public A[] value();
+        }
+
+        private static final Object o = "";
+        private static final boolean B1s = o instanceof R(@A String s) && s.isEmpty();
+        private static final boolean B1m = o instanceof R(@A @A String s) && s.isEmpty();
+        private final boolean B2s = o instanceof R(@A String s) && s.isEmpty();
+        private final boolean B2m = o instanceof R(@A @A String s) && s.isEmpty();
+
+        static {
+            boolean B3s = o instanceof R(@A String s) && s.isEmpty();
+            boolean B3m = o instanceof R(@A @A String s) && s.isEmpty();
+        }
+
+        {
+            boolean B4s = o instanceof R(@A String s) && s.isEmpty();
+            boolean B4m = o instanceof R(@A @A String s) && s.isEmpty();
+        }
+
+        {
+            boolean B5s = o instanceof R(@A String s) && s.isEmpty();
+            boolean B5m = o instanceof R(@A @A String s) && s.isEmpty();
+        }
+
+        public DeconstructionPattern() {
+            boolean B6s = o instanceof R(@A String s) && s.isEmpty();
+            boolean B6m = o instanceof R(@A @A String s) && s.isEmpty();
+        }
+
+        void testPatterns() {
+            boolean B7s = o instanceof R(@A String s) && s.isEmpty();
+            boolean B7m = o instanceof R(@A @A String s) && s.isEmpty();
+        }
+
+        record R(String s) {}
+    }
 }
diff --git a/test/langtools/tools/javac/api/TestGetScopeResult.java b/test/langtools/tools/javac/api/TestGetScopeResult.java
index 8f32df197d9..b2a2e500e03 100644
--- a/test/langtools/tools/javac/api/TestGetScopeResult.java
+++ b/test/langtools/tools/javac/api/TestGetScopeResult.java
@@ -23,12 +23,13 @@
 
 /*
  * @test
- * @bug 8205418 8207229 8207230 8230847 8245786 8247334 8248641
+ * @bug 8205418 8207229 8207230 8230847 8245786 8247334 8248641 8240658
  * @summary Test the outcomes from Trees.getScope
  * @modules jdk.compiler/com.sun.tools.javac.api
  *          jdk.compiler/com.sun.tools.javac.comp
  *          jdk.compiler/com.sun.tools.javac.tree
  *          jdk.compiler/com.sun.tools.javac.util
+ * @compile TestGetScopeResult.java
  */
 
 import java.io.IOException;
@@ -62,6 +63,7 @@
 import com.sun.source.util.TreePathScanner;
 import com.sun.source.util.Trees;
 import com.sun.tools.javac.api.JavacScope;
+import com.sun.tools.javac.api.JavacTaskImpl;
 
 import com.sun.tools.javac.api.JavacTool;
 import com.sun.tools.javac.comp.Analyzer;
@@ -192,6 +194,19 @@ static interface BiFunction<R, P, Q> {
                    }
                }""",
                invocationInMethodInvocation);
+
+        String[] infer = {
+            "c:java.lang.String",
+            "super:java.lang.Object",
+            "this:Test"
+        };
+
+        doTest("class Test { void test() { cand(\"\", c -> { }); } <T>void cand(T t, I<T> i) { } interface I<T> { public String test(T s); }  }",
+               infer);
+        doTest("class Test { void test() { cand(\"\", c -> { }); } <T>void cand(T t, I<T> i, int j) { } interface I<T> { public void test(T s); }  }",
+               infer);
+        doTest("class Test { void test() { cand(\"\", c -> { }); } <T>void cand(T t, I<T> i, int j) { } interface I<T> { public String test(T s); }  }",
+               infer);
     }
 
     public void doTest(String code, String... expected) throws IOException {
@@ -208,24 +223,29 @@ public String getCharContent(boolean ignoreEncodingErrors) {
             }
             JavacTask t = (JavacTask) c.getTask(null, fm, null, null, null, List.of(new MyFileObject()));
             CompilationUnitTree cut = t.parse().iterator().next();
-            t.analyze();
 
-            List<String> actual = new ArrayList<>();
+            ((JavacTaskImpl)t).enter();
 
-            new TreePathScanner<Void, Void>() {
-                @Override
-                public Void visitLambdaExpression(LambdaExpressionTree node, Void p) {
-                    Scope scope = Trees.instance(t).getScope(new TreePath(getCurrentPath(), node.getBody()));
-                    actual.addAll(dumpScope(scope));
-                    return super.visitLambdaExpression(node, p);
-                }
-            }.scan(cut, null);
+            for (int r = 0; r < 2; r++) {
+                List<String> actual = new ArrayList<>();
 
-            List<String> expectedList = List.of(expected);
+                new TreePathScanner<Void, Void>() {
+                    @Override
+                    public Void visitLambdaExpression(LambdaExpressionTree node, Void p) {
+                        Scope scope = Trees.instance(t).getScope(new TreePath(getCurrentPath(), node.getBody()));
+                        actual.addAll(dumpScope(scope));
+                        return super.visitLambdaExpression(node, p);
+                    }
+                }.scan(cut, null);
+
+                List<String> expectedList = List.of(expected);
 
-            if (!expectedList.equals(actual)) {
-                throw new IllegalStateException("Unexpected scope content: " + actual + "\n" +
-                                                 "expected: " + expectedList);
+                if (!expectedList.equals(actual)) {
+                    throw new IllegalStateException("Unexpected scope content: " + actual + "\n" +
+                                                     "expected: " + expectedList);
+                }
+
+                t.analyze();
             }
         }
     }
diff --git a/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReference.java b/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReference.java
new file mode 100644
index 00000000000..741835a0a4f
--- /dev/null
+++ b/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReference.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 8240658
+ * @summary Verify that broken method invocations with lambdas get type inference done
+ * @modules jdk.compiler
+ * @compile --enable-preview -source ${jdk.version} TestGetTypeMirrorReference.java
+ * @run main/othervm --enable-preview TestGetTypeMirrorReference
+ */
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.*;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import javax.lang.model.type.TypeMirror;
+import javax.tools.DiagnosticCollector;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+/*
+ * This test verifies proper error recovery for method invocations which need
+ * type inference, and have lambdas as arguments.
+ *
+ * The test will read the adjacent TestGetTypeMirrorReferenceData.java, parse and
+ * attribute it, and call Trees.getTypeMirror on each place marked, in a block
+ * comment, with:
+ * getTypeMirror:<expected-typemirror-kind>:<expected-typemirror-toString>
+ * The actual retrieved TypeMirror will be checked against the provided description,
+ * verifying the return value of TypeMirror.getKind and TypeMirror.toString().
+ *
+ * The AST for TestGetTypeMirrorReferenceData.java will also be printed using
+ * Tree.toString(), and compared to the expected AST form.
+ */
+public class TestGetTypeMirrorReference {
+
+    private static final String JDK_VERSION =
+            Integer.toString(Runtime.version().feature());
+
+    public static void main(String... args) throws IOException {
+        analyze("TestGetTypeMirrorReferenceData.java",
+                """
+                package test;
+
+                public class TestGetTypeMirrorReferenceData {
+
+                    public TestGetTypeMirrorReferenceData() {
+                        super();
+                    }
+
+                    private static void test() {
+                        Test.of(1).convert((c1)->{
+                            Object o = c1;
+                        });
+                        Test.of(1).consume((c2)->{
+                            Object o = c2;
+                            return null;
+                        });
+                        Test.of(1).consumeWithParam((c3)->{
+                            Object o = c3;
+                        });
+                        convert(0, (c4)->{
+                            Object o = c4;
+                        });
+                        consume(0, (c5)->{
+                            Object o = c5;
+                        });
+                        convertVarArgs(0, (c6)->{
+                            Object o = c6;
+                        }, 1, 2, 3, 4);
+                        consumeVarArgs(0, (c7)->{
+                            Object o = c7;
+                        }, 1, 2, 3, 4);
+                        convertVarArgs2(0, (c8)->{
+                            Object o = c8;
+                        }, (c8)->{
+                            Object o = c8;
+                        });
+                        consumeVarArgs2(0, (c9)->{
+                            Object o = c9;
+                        }, (c9)->{
+                            Object o = c9;
+                        });
+                    }
+
+                    public <T, R>R convert(T t, Function<T, R> f, int i) {
+                        return null;
+                    }
+
+                    public <T>void consume(T t, Consumer<T> c, int i) {
+                    }
+
+                    public <T, R>R convertVarArgs(T t, Function<T, R> c, int... i) {
+                        return null;
+                    }
+
+                    public <T>void consumeVarArgs(T t, Consumer<T> c, int... i) {
+                    }
+
+                    public <T, R>R convertVarArgs2(T t, Function<T, R>... c) {
+                        return null;
+                    }
+
+                    public <T>void consumeVarArgs2(T t, Consumer<T>... c) {
+                    }
+
+                    public static class Test<T> {
+
+                        public Test() {
+                            super();
+                        }
+
+                        public static <T>Test<T> of(T t) {
+                            return new Test<>();
+                        }
+
+                        public <R>Test<R> convert(Function<T, R> c) {
+                            return null;
+                        }
+
+                        public void consume(Consumer<T> c) {
+                        }
+
+                        public void consumeWithParam(Consumer<T> c, int i) {
+                        }
+                    }
+
+                    public interface Function<T, R> {
+
+                        public R map(T t);
+                    }
+
+                    public interface Consumer<T> {
+
+                        public void run(T t);
+                    }
+                }""");
+    }
+
+    private static void analyze(String fileName, String expectedAST) throws IOException {
+        try (StandardJavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null)) {
+            List<JavaFileObject> files = new ArrayList<>();
+            File source = new File(System.getProperty("test.src", "."), fileName.replace('/', File.separatorChar)).getAbsoluteFile();
+            for (JavaFileObject f : fm.getJavaFileObjects(source)) {
+                files.add(f);
+            }
+            DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
+            List<String> options = List.of("-source", JDK_VERSION,
+                                           "-XDshould-stop.at=FLOW");
+            JavacTask ct = (JavacTask) ToolProvider.getSystemJavaCompiler().getTask(null, null, diagnostics, options, null, files);
+            Trees trees = Trees.instance(ct);
+            CompilationUnitTree cut = ct.parse().iterator().next();
+
+            ct.analyze();
+
+            String actualAST = Arrays.stream(cut.toString().split("\n"))
+                                     .map(l -> l.stripTrailing())
+                                     .collect(Collectors.joining("\n"));
+
+            if (!expectedAST.equals(actualAST)) {
+                throw new AssertionError("Unexpected AST shape!\n" + actualAST);
+            }
+
+            Pattern p = Pattern.compile("/\\*getTypeMirror:(.*?)\\*/");
+            Matcher m = p.matcher(cut.getSourceFile().getCharContent(false));
+
+            while (m.find()) {
+                TreePath tp = pathFor(trees, cut, m.start() - 1);
+                String expected = m.group(1);
+                if (expected.startsWith("getParentPath:")) {
+                    tp = tp.getParentPath();
+                    expected = expected.substring("getParentPath:".length());
+                }
+                TypeMirror found = trees.getTypeMirror(tp);
+                String actual = found != null ? found.getKind() + ":" + typeToString(found) : "<null>";
+
+                if (!expected.equals(actual)) {
+                    throw new IllegalStateException("expected=" + expected + "; actual=" + actual + "; tree: " + tp.getLeaf());
+                }
+            }
+        }
+    }
+
+    private static TreePath pathFor(final Trees trees, final CompilationUnitTree cut, final int pos) {
+        final TreePath[] result = new TreePath[1];
+
+        new TreePathScanner<Void, Void>() {
+            @Override public Void scan(Tree node, Void p) {
+                if (   node != null
+                    && trees.getSourcePositions().getStartPosition(cut, node) <= pos
+                    && pos <= trees.getSourcePositions().getEndPosition(cut, node)) {
+                    result[0] = new TreePath(getCurrentPath(), node);
+                    return super.scan(node, p);
+                }
+                return null;
+            }
+        }.scan(cut, null);
+
+        return result[0];
+    }
+
+    private static String typeToString(TypeMirror type) {
+        return type.toString();
+    }
+
+    static class TestFileObject extends SimpleJavaFileObject {
+        private final String text;
+        public TestFileObject(String text) {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            this.text = text;
+        }
+        @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return text;
+        }
+    }
+
+}
diff --git a/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReferenceData.java b/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReferenceData.java
new file mode 100644
index 00000000000..28e62147bdf
--- /dev/null
+++ b/test/langtools/tools/javac/api/lambdaErrorRecovery/TestGetTypeMirrorReferenceData.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 test;
+
+public class TestGetTypeMirrorReferenceData {
+
+    private static void test() {
+        Test.of(1).convert(c1 -> {Object o = c1/*getTypeMirror:DECLARED:java.lang.Integer*/;});
+        Test.of(1).consume(c2 -> {Object o = c2/*getTypeMirror:DECLARED:java.lang.Integer*/; return null;});
+        Test.of(1).consumeWithParam(c3 -> {Object o = c3/*getTypeMirror:DECLARED:java.lang.Integer*/;});
+        convert(0, c4 -> {Object o = c4/*getTypeMirror:DECLARED:java.lang.Integer*/;});
+        consume(0, c5 -> {Object o = c5/*getTypeMirror:DECLARED:java.lang.Integer*/;});
+        convertVarArgs(0, c6 -> {Object o = c6/*getTypeMirror:DECLARED:java.lang.Integer*/;}, 1, 2, 3, 4);
+        consumeVarArgs(0, c7 -> {Object o = c7/*getTypeMirror:DECLARED:java.lang.Integer*/;}, 1, 2, 3, 4);
+        convertVarArgs2(0, c8 -> {Object o = c8/*getTypeMirror:DECLARED:java.lang.Integer*/;}, c8 -> {Object o = c8/*getTypeMirror:DECLARED:java.lang.Integer*/;});
+        consumeVarArgs2(0, c9 -> {Object o = c9/*getTypeMirror:DECLARED:java.lang.Integer*/;}, c9 -> {Object o = c9/*getTypeMirror:DECLARED:java.lang.Integer*/;});
+    }
+    public <T, R> R convert(T t, Function<T, R> f, int i) {
+        return null;
+    }
+    public <T> void consume(T t, Consumer<T> c, int i) {
+    }
+    public <T, R> R convertVarArgs(T t, Function<T, R> c, int... i) {
+        return null;
+    }
+    public <T> void consumeVarArgs(T t, Consumer<T> c, int... i) {
+    }
+    public <T, R> R convertVarArgs2(T t, Function<T, R>... c) {
+        return null;
+    }
+    public <T> void consumeVarArgs2(T t, Consumer<T>... c) {
+    }
+    public static class Test<T> {
+        public static <T> Test<T> of(T t) {
+            return new Test<>();
+        }
+        public <R> Test<R> convert(Function<T, R> c) {
+            return null;
+        }
+        public void consume(Consumer<T> c) {}
+        public void consumeWithParam(Consumer<T> c, int i) {}
+    }
+    public interface Function<T, R> {
+        public R map(T t);
+    }
+    public interface Consumer<T> {
+        public void run(T t);
+    }
+}
diff --git a/test/langtools/tools/javac/diags/examples/DeconstructionPatternOnlyRecords.java b/test/langtools/tools/javac/diags/examples/DeconstructionPatternOnlyRecords.java
new file mode 100644
index 00000000000..059cd038a26
--- /dev/null
+++ b/test/langtools/tools/javac/diags/examples/DeconstructionPatternOnlyRecords.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+// key: compiler.err.deconstruction.pattern.only.records
+// key: compiler.warn.preview.feature.use.plural
+// key: compiler.misc.feature.deconstruction.patterns
+// options: --enable-preview -source ${jdk.version} -Xlint:preview
+
+class DeconstructionpatternOnlyRecords {
+    public boolean deconstruction(Object o) {
+        return o instanceof String(var content);
+    }
+}
diff --git a/test/langtools/tools/javac/diags/examples/IncorrectNumberOfNestedPatterns.java b/test/langtools/tools/javac/diags/examples/IncorrectNumberOfNestedPatterns.java
new file mode 100644
index 00000000000..03949569e07
--- /dev/null
+++ b/test/langtools/tools/javac/diags/examples/IncorrectNumberOfNestedPatterns.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+// key: compiler.err.incorrect.number.of.nested.patterns
+// key: compiler.misc.feature.deconstruction.patterns
+// key: compiler.misc.feature.records
+// key: compiler.warn.preview.feature.use.plural
+// options: --enable-preview -source ${jdk.version} -Xlint:preview
+
+class IncorrectNumberOfNestedPatterns {
+    private boolean t(Object o) {
+        return o instanceof R(var i);
+    }
+    record R(int i, int j) {}
+}
diff --git a/test/langtools/tools/javac/diags/examples/UnderscoreAsIdentifierError.java b/test/langtools/tools/javac/diags/examples/UnderscoreAsIdentifierError.java
index 1600d5cc2ca..9fa5fb4e8ec 100644
--- a/test/langtools/tools/javac/diags/examples/UnderscoreAsIdentifierError.java
+++ b/test/langtools/tools/javac/diags/examples/UnderscoreAsIdentifierError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * 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,6 +22,7 @@
  */
 
 // key: compiler.err.underscore.as.identifier
+// options: -source 9 -Xlint:-options
 
 class UnderscoreAsIdentifierError {
     String _ = null;
diff --git a/test/langtools/tools/javac/diags/examples/UnderscoreCantBeFollowedByDims.java b/test/langtools/tools/javac/diags/examples/UnderscoreCantBeFollowedByDims.java
new file mode 100644
index 00000000000..851a8866c5b
--- /dev/null
+++ b/test/langtools/tools/javac/diags/examples/UnderscoreCantBeFollowedByDims.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+// key: compiler.err.underscore.cant.be.followed.by.dimensions
+// key: compiler.err.underscore.as.identifier.in.method
+
+class UnderscoreCantBeFollowedByDims {
+    void m(String _[]) {}
+}
diff --git a/test/langtools/tools/javac/diags/examples/UnderscoreInLambdaExpression.java b/test/langtools/tools/javac/diags/examples/UnderscoreInLambdaExpression.java
index 586ab76a908..6616de5bd50 100644
--- a/test/langtools/tools/javac/diags/examples/UnderscoreInLambdaExpression.java
+++ b/test/langtools/tools/javac/diags/examples/UnderscoreInLambdaExpression.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * 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,6 +22,8 @@
  */
 
 // key: compiler.err.underscore.as.identifier.in.lambda
+// options: -source 9 -Xlint:-options
+
 public class UnderscoreInLambdaExpression {
     java.util.function.Function<String,String> f = _ -> "x";
 }
diff --git a/test/langtools/tools/javac/diags/examples/UnderscoreInMethodParameters.java b/test/langtools/tools/javac/diags/examples/UnderscoreInMethodParameters.java
new file mode 100644
index 00000000000..be07733cea2
--- /dev/null
+++ b/test/langtools/tools/javac/diags/examples/UnderscoreInMethodParameters.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+// key: compiler.err.underscore.as.identifier.in.method
+
+public class UnderscoreInMethodParameters {
+    void m(String _) {}
+}
diff --git a/test/langtools/tools/javac/diags/examples/UnderscoreOnlyInLamdaError.java b/test/langtools/tools/javac/diags/examples/UnderscoreOnlyInLamdaError.java
new file mode 100644
index 00000000000..f51df461d4e
--- /dev/null
+++ b/test/langtools/tools/javac/diags/examples/UnderscoreOnlyInLamdaError.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+// key: compiler.err.underscore.not.allowed
+
+import java.util.function.*;
+
+class UnderscoreAsIdentifierError {
+    BiFunction<Integer, String, String> biss = (i, j) -> String.valueOf(_);
+}
diff --git a/test/langtools/tools/javac/lambda/IdentifierTest.java b/test/langtools/tools/javac/lambda/IdentifierTest.java
index d4025fff825..b7ded314c1f 100644
--- a/test/langtools/tools/javac/lambda/IdentifierTest.java
+++ b/test/langtools/tools/javac/lambda/IdentifierTest.java
@@ -4,7 +4,8 @@
  * @author sogoel
  * @summary Test generation of warnings when '_' is used an identifier
  * @compile/fail/ref=IdentifierTest8.out -source 8 -Xlint:-options -Werror -XDrawDiagnostics IdentifierTest.java
- * @compile/fail/ref=IdentifierTest9.out -XDrawDiagnostics IdentifierTest.java
+ * @compile/fail/ref=IdentifierTest9.out -source 9 -Xlint:-options -XDrawDiagnostics IdentifierTest.java
+ * @compile/fail/ref=IdentifierTest10.out -Xlint:-options -XDrawDiagnostics IdentifierTest.java
  */
 
 import java.util.List;
@@ -180,4 +181,3 @@ public void testLabels() {
 interface _ {
     void mI();
 }
-
diff --git a/test/langtools/tools/javac/lambda/IdentifierTest10.out b/test/langtools/tools/javac/lambda/IdentifierTest10.out
new file mode 100644
index 00000000000..421acad2ae6
--- /dev/null
+++ b/test/langtools/tools/javac/lambda/IdentifierTest10.out
@@ -0,0 +1,44 @@
+IdentifierTest.java:42:11: compiler.err.underscore.not.allowed
+IdentifierTest.java:45:16: compiler.err.underscore.not.allowed
+IdentifierTest.java:46:20: compiler.err.underscore.not.allowed
+IdentifierTest.java:47:22: compiler.err.underscore.not.allowed
+IdentifierTest.java:52:13: compiler.err.underscore.not.allowed
+IdentifierTest.java:52:15: compiler.err.underscore.not.allowed
+IdentifierTest.java:52:23: compiler.err.underscore.not.allowed
+IdentifierTest.java:54:13: compiler.err.underscore.not.allowed
+IdentifierTest.java:56:13: compiler.err.underscore.not.allowed
+IdentifierTest.java:62:21: compiler.err.underscore.not.allowed
+IdentifierTest.java:64:67: compiler.err.underscore.not.allowed
+IdentifierTest.java:71:13: compiler.err.underscore.not.allowed
+IdentifierTest.java:72:14: compiler.err.underscore.not.allowed
+IdentifierTest.java:73:18: compiler.err.underscore.not.allowed
+IdentifierTest.java:78:22: compiler.err.underscore.not.allowed
+IdentifierTest.java:80:13: compiler.err.underscore.not.allowed
+IdentifierTest.java:80:15: compiler.err.underscore.not.allowed
+IdentifierTest.java:82:13: compiler.err.underscore.not.allowed
+IdentifierTest.java:82:15: compiler.err.underscore.not.allowed
+IdentifierTest.java:89:10: compiler.err.underscore.not.allowed
+IdentifierTest.java:89:38: compiler.err.underscore.not.allowed
+IdentifierTest.java:95:14: compiler.err.underscore.not.allowed
+IdentifierTest.java:102:17: compiler.err.underscore.not.allowed
+IdentifierTest.java:102:26: compiler.err.underscore.not.allowed
+IdentifierTest.java:119:20: compiler.err.underscore.not.allowed
+IdentifierTest.java:124:10: compiler.err.underscore.not.allowed
+IdentifierTest.java:129:17: compiler.err.underscore.not.allowed
+IdentifierTest.java:132:17: compiler.err.underscore.not.allowed
+IdentifierTest.java:139:17: compiler.err.underscore.not.allowed
+IdentifierTest.java:139:24: compiler.err.underscore.not.allowed
+IdentifierTest.java:139:33: compiler.err.underscore.not.allowed
+IdentifierTest.java:140:39: compiler.err.underscore.not.allowed
+IdentifierTest.java:144:13: compiler.err.underscore.not.allowed
+IdentifierTest.java:145:15: compiler.err.underscore.not.allowed
+IdentifierTest.java:146:13: compiler.err.underscore.not.allowed
+IdentifierTest.java:151:15: compiler.err.underscore.not.allowed
+IdentifierTest.java:152:17: compiler.err.underscore.not.allowed
+IdentifierTest.java:158:16: compiler.err.underscore.not.allowed
+IdentifierTest.java:160:25: compiler.err.underscore.not.allowed
+IdentifierTest.java:169:5: compiler.err.underscore.not.allowed
+IdentifierTest.java:173:26: compiler.err.underscore.not.allowed
+IdentifierTest.java:175:19: compiler.err.underscore.not.allowed
+IdentifierTest.java:181:11: compiler.err.underscore.not.allowed
+43 errors
diff --git a/test/langtools/tools/javac/lambda/IdentifierTest8.out b/test/langtools/tools/javac/lambda/IdentifierTest8.out
index 6d1da256d40..2a570598c35 100644
--- a/test/langtools/tools/javac/lambda/IdentifierTest8.out
+++ b/test/langtools/tools/javac/lambda/IdentifierTest8.out
@@ -1,47 +1,47 @@
-IdentifierTest.java:41:11: compiler.warn.underscore.as.identifier
-IdentifierTest.java:44:16: compiler.warn.underscore.as.identifier
-IdentifierTest.java:45:20: compiler.warn.underscore.as.identifier
-IdentifierTest.java:46:22: compiler.warn.underscore.as.identifier
-IdentifierTest.java:51:13: compiler.warn.underscore.as.identifier
-IdentifierTest.java:51:15: compiler.warn.underscore.as.identifier
-IdentifierTest.java:51:23: compiler.warn.underscore.as.identifier
-IdentifierTest.java:53:13: compiler.warn.underscore.as.identifier
-IdentifierTest.java:55:13: compiler.warn.underscore.as.identifier
-IdentifierTest.java:61:21: compiler.warn.underscore.as.identifier
-IdentifierTest.java:62:42: compiler.warn.underscore.as.identifier
-IdentifierTest.java:63:67: compiler.warn.underscore.as.identifier
-IdentifierTest.java:70:13: compiler.warn.underscore.as.identifier
-IdentifierTest.java:71:14: compiler.warn.underscore.as.identifier
-IdentifierTest.java:72:18: compiler.warn.underscore.as.identifier
-IdentifierTest.java:77:22: compiler.warn.underscore.as.identifier
-IdentifierTest.java:79:13: compiler.warn.underscore.as.identifier
-IdentifierTest.java:79:15: compiler.warn.underscore.as.identifier
-IdentifierTest.java:81:13: compiler.warn.underscore.as.identifier
-IdentifierTest.java:81:15: compiler.warn.underscore.as.identifier
-IdentifierTest.java:88:10: compiler.warn.underscore.as.identifier
-IdentifierTest.java:88:38: compiler.warn.underscore.as.identifier
-IdentifierTest.java:94:14: compiler.warn.underscore.as.identifier
-IdentifierTest.java:101:17: compiler.warn.underscore.as.identifier
-IdentifierTest.java:101:26: compiler.warn.underscore.as.identifier
-IdentifierTest.java:118:20: compiler.warn.underscore.as.identifier
-IdentifierTest.java:123:10: compiler.warn.underscore.as.identifier
-IdentifierTest.java:128:17: compiler.warn.underscore.as.identifier
-IdentifierTest.java:131:17: compiler.warn.underscore.as.identifier
-IdentifierTest.java:138:17: compiler.warn.underscore.as.identifier
-IdentifierTest.java:138:24: compiler.warn.underscore.as.identifier
-IdentifierTest.java:138:33: compiler.warn.underscore.as.identifier
-IdentifierTest.java:139:39: compiler.warn.underscore.as.identifier
-IdentifierTest.java:143:13: compiler.warn.underscore.as.identifier
-IdentifierTest.java:144:15: compiler.warn.underscore.as.identifier
-IdentifierTest.java:145:13: compiler.warn.underscore.as.identifier
-IdentifierTest.java:150:15: compiler.warn.underscore.as.identifier
-IdentifierTest.java:151:17: compiler.warn.underscore.as.identifier
-IdentifierTest.java:157:16: compiler.warn.underscore.as.identifier
-IdentifierTest.java:159:25: compiler.warn.underscore.as.identifier
-IdentifierTest.java:168:5: compiler.warn.underscore.as.identifier
-IdentifierTest.java:172:26: compiler.warn.underscore.as.identifier
-IdentifierTest.java:174:19: compiler.warn.underscore.as.identifier
-IdentifierTest.java:180:11: compiler.warn.underscore.as.identifier
+IdentifierTest.java:42:11: compiler.warn.underscore.as.identifier
+IdentifierTest.java:45:16: compiler.warn.underscore.as.identifier
+IdentifierTest.java:46:20: compiler.warn.underscore.as.identifier
+IdentifierTest.java:47:22: compiler.warn.underscore.as.identifier
+IdentifierTest.java:52:13: compiler.warn.underscore.as.identifier
+IdentifierTest.java:52:15: compiler.warn.underscore.as.identifier
+IdentifierTest.java:52:23: compiler.warn.underscore.as.identifier
+IdentifierTest.java:54:13: compiler.warn.underscore.as.identifier
+IdentifierTest.java:56:13: compiler.warn.underscore.as.identifier
+IdentifierTest.java:62:21: compiler.warn.underscore.as.identifier
+IdentifierTest.java:63:42: compiler.warn.underscore.as.identifier
+IdentifierTest.java:64:67: compiler.warn.underscore.as.identifier
+IdentifierTest.java:71:13: compiler.warn.underscore.as.identifier
+IdentifierTest.java:72:14: compiler.warn.underscore.as.identifier
+IdentifierTest.java:73:18: compiler.warn.underscore.as.identifier
+IdentifierTest.java:78:22: compiler.warn.underscore.as.identifier
+IdentifierTest.java:80:13: compiler.warn.underscore.as.identifier
+IdentifierTest.java:80:15: compiler.warn.underscore.as.identifier
+IdentifierTest.java:82:13: compiler.warn.underscore.as.identifier
+IdentifierTest.java:82:15: compiler.warn.underscore.as.identifier
+IdentifierTest.java:89:10: compiler.warn.underscore.as.identifier
+IdentifierTest.java:89:38: compiler.warn.underscore.as.identifier
+IdentifierTest.java:95:14: compiler.warn.underscore.as.identifier
+IdentifierTest.java:102:17: compiler.warn.underscore.as.identifier
+IdentifierTest.java:102:26: compiler.warn.underscore.as.identifier
+IdentifierTest.java:119:20: compiler.warn.underscore.as.identifier
+IdentifierTest.java:124:10: compiler.warn.underscore.as.identifier
+IdentifierTest.java:129:17: compiler.warn.underscore.as.identifier
+IdentifierTest.java:132:17: compiler.warn.underscore.as.identifier
+IdentifierTest.java:139:17: compiler.warn.underscore.as.identifier
+IdentifierTest.java:139:24: compiler.warn.underscore.as.identifier
+IdentifierTest.java:139:33: compiler.warn.underscore.as.identifier
+IdentifierTest.java:140:39: compiler.warn.underscore.as.identifier
+IdentifierTest.java:144:13: compiler.warn.underscore.as.identifier
+IdentifierTest.java:145:15: compiler.warn.underscore.as.identifier
+IdentifierTest.java:146:13: compiler.warn.underscore.as.identifier
+IdentifierTest.java:151:15: compiler.warn.underscore.as.identifier
+IdentifierTest.java:152:17: compiler.warn.underscore.as.identifier
+IdentifierTest.java:158:16: compiler.warn.underscore.as.identifier
+IdentifierTest.java:160:25: compiler.warn.underscore.as.identifier
+IdentifierTest.java:169:5: compiler.warn.underscore.as.identifier
+IdentifierTest.java:173:26: compiler.warn.underscore.as.identifier
+IdentifierTest.java:175:19: compiler.warn.underscore.as.identifier
+IdentifierTest.java:181:11: compiler.warn.underscore.as.identifier
 - compiler.err.warnings.and.werror
 1 error
 44 warnings
diff --git a/test/langtools/tools/javac/lambda/IdentifierTest9.out b/test/langtools/tools/javac/lambda/IdentifierTest9.out
index 6dd260aa8a2..7ee6c8cb149 100644
--- a/test/langtools/tools/javac/lambda/IdentifierTest9.out
+++ b/test/langtools/tools/javac/lambda/IdentifierTest9.out
@@ -1,45 +1,45 @@
-IdentifierTest.java:41:11: compiler.err.underscore.as.identifier
-IdentifierTest.java:44:16: compiler.err.underscore.as.identifier
-IdentifierTest.java:45:20: compiler.err.underscore.as.identifier
-IdentifierTest.java:46:22: compiler.err.underscore.as.identifier
-IdentifierTest.java:51:13: compiler.err.underscore.as.identifier
-IdentifierTest.java:51:15: compiler.err.underscore.as.identifier
-IdentifierTest.java:51:23: compiler.err.underscore.as.identifier
-IdentifierTest.java:53:13: compiler.err.underscore.as.identifier
-IdentifierTest.java:55:13: compiler.err.underscore.as.identifier
-IdentifierTest.java:61:21: compiler.err.underscore.as.identifier
-IdentifierTest.java:62:42: compiler.err.underscore.as.identifier
-IdentifierTest.java:63:67: compiler.err.underscore.as.identifier
-IdentifierTest.java:70:13: compiler.err.underscore.as.identifier
-IdentifierTest.java:71:14: compiler.err.underscore.as.identifier
-IdentifierTest.java:72:18: compiler.err.underscore.as.identifier
-IdentifierTest.java:77:22: compiler.err.underscore.as.identifier
-IdentifierTest.java:79:13: compiler.err.underscore.as.identifier
-IdentifierTest.java:79:15: compiler.err.underscore.as.identifier
-IdentifierTest.java:81:13: compiler.err.underscore.as.identifier
-IdentifierTest.java:81:15: compiler.err.underscore.as.identifier
-IdentifierTest.java:88:10: compiler.err.underscore.as.identifier
-IdentifierTest.java:88:38: compiler.err.underscore.as.identifier
-IdentifierTest.java:94:14: compiler.err.underscore.as.identifier
-IdentifierTest.java:101:17: compiler.err.underscore.as.identifier
-IdentifierTest.java:101:26: compiler.err.underscore.as.identifier
-IdentifierTest.java:118:20: compiler.err.underscore.as.identifier
-IdentifierTest.java:123:10: compiler.err.underscore.as.identifier
-IdentifierTest.java:128:17: compiler.err.underscore.as.identifier
-IdentifierTest.java:131:17: compiler.err.underscore.as.identifier
-IdentifierTest.java:138:17: compiler.err.underscore.as.identifier
-IdentifierTest.java:138:24: compiler.err.underscore.as.identifier
-IdentifierTest.java:138:33: compiler.err.underscore.as.identifier
-IdentifierTest.java:139:39: compiler.err.underscore.as.identifier
-IdentifierTest.java:143:13: compiler.err.underscore.as.identifier
-IdentifierTest.java:144:15: compiler.err.underscore.as.identifier
-IdentifierTest.java:145:13: compiler.err.underscore.as.identifier
-IdentifierTest.java:150:15: compiler.err.underscore.as.identifier
-IdentifierTest.java:151:17: compiler.err.underscore.as.identifier
-IdentifierTest.java:157:16: compiler.err.underscore.as.identifier
-IdentifierTest.java:159:25: compiler.err.underscore.as.identifier
-IdentifierTest.java:168:5: compiler.err.underscore.as.identifier
-IdentifierTest.java:172:26: compiler.err.underscore.as.identifier
-IdentifierTest.java:174:19: compiler.err.underscore.as.identifier
-IdentifierTest.java:180:11: compiler.err.underscore.as.identifier
+IdentifierTest.java:42:11: compiler.err.underscore.as.identifier
+IdentifierTest.java:45:16: compiler.err.underscore.as.identifier
+IdentifierTest.java:46:20: compiler.err.underscore.as.identifier
+IdentifierTest.java:47:22: compiler.err.underscore.as.identifier
+IdentifierTest.java:52:13: compiler.err.underscore.as.identifier
+IdentifierTest.java:52:15: compiler.err.underscore.as.identifier
+IdentifierTest.java:52:23: compiler.err.underscore.as.identifier
+IdentifierTest.java:54:13: compiler.err.underscore.as.identifier
+IdentifierTest.java:56:13: compiler.err.underscore.as.identifier
+IdentifierTest.java:62:21: compiler.err.underscore.as.identifier
+IdentifierTest.java:63:42: compiler.err.underscore.as.identifier
+IdentifierTest.java:64:67: compiler.err.underscore.as.identifier
+IdentifierTest.java:71:13: compiler.err.underscore.as.identifier
+IdentifierTest.java:72:14: compiler.err.underscore.as.identifier
+IdentifierTest.java:73:18: compiler.err.underscore.as.identifier
+IdentifierTest.java:78:22: compiler.err.underscore.as.identifier
+IdentifierTest.java:80:13: compiler.err.underscore.as.identifier
+IdentifierTest.java:80:15: compiler.err.underscore.as.identifier
+IdentifierTest.java:82:13: compiler.err.underscore.as.identifier
+IdentifierTest.java:82:15: compiler.err.underscore.as.identifier
+IdentifierTest.java:89:10: compiler.err.underscore.as.identifier
+IdentifierTest.java:89:38: compiler.err.underscore.as.identifier
+IdentifierTest.java:95:14: compiler.err.underscore.as.identifier
+IdentifierTest.java:102:17: compiler.err.underscore.as.identifier
+IdentifierTest.java:102:26: compiler.err.underscore.as.identifier
+IdentifierTest.java:119:20: compiler.err.underscore.as.identifier
+IdentifierTest.java:124:10: compiler.err.underscore.as.identifier
+IdentifierTest.java:129:17: compiler.err.underscore.as.identifier
+IdentifierTest.java:132:17: compiler.err.underscore.as.identifier
+IdentifierTest.java:139:17: compiler.err.underscore.as.identifier
+IdentifierTest.java:139:24: compiler.err.underscore.as.identifier
+IdentifierTest.java:139:33: compiler.err.underscore.as.identifier
+IdentifierTest.java:140:39: compiler.err.underscore.as.identifier
+IdentifierTest.java:144:13: compiler.err.underscore.as.identifier
+IdentifierTest.java:145:15: compiler.err.underscore.as.identifier
+IdentifierTest.java:146:13: compiler.err.underscore.as.identifier
+IdentifierTest.java:151:15: compiler.err.underscore.as.identifier
+IdentifierTest.java:152:17: compiler.err.underscore.as.identifier
+IdentifierTest.java:158:16: compiler.err.underscore.as.identifier
+IdentifierTest.java:160:25: compiler.err.underscore.as.identifier
+IdentifierTest.java:169:5: compiler.err.underscore.as.identifier
+IdentifierTest.java:173:26: compiler.err.underscore.as.identifier
+IdentifierTest.java:175:19: compiler.err.underscore.as.identifier
+IdentifierTest.java:181:11: compiler.err.underscore.as.identifier
 44 errors
diff --git a/test/langtools/tools/javac/lambda/LambdaParserTest.java b/test/langtools/tools/javac/lambda/LambdaParserTest.java
index e3440d3b17f..02ff762c005 100644
--- a/test/langtools/tools/javac/lambda/LambdaParserTest.java
+++ b/test/langtools/tools/javac/lambda/LambdaParserTest.java
@@ -295,7 +295,7 @@ void check(Result<?> res) {
         }
 
         errorExpected |= pn == LambdaParameterName.UNDERSCORE &&
-                lk.arity() > 0;
+                lk.arity() > 0 && sk == SourceKind.SOURCE_9;
 
         for (int i = 0; i < lk.arity(); i++) {
             if (!lk.isShort() &&
diff --git a/test/langtools/tools/javac/lambda/LambdaScope04.java b/test/langtools/tools/javac/lambda/LambdaScope04.java
index a2ebc6f28d5..c42b2342a4e 100644
--- a/test/langtools/tools/javac/lambda/LambdaScope04.java
+++ b/test/langtools/tools/javac/lambda/LambdaScope04.java
@@ -3,7 +3,8 @@
  * @bug 8003280
  * @summary Add lambda tests
  *  check that lambda cannot shadow variables from enclosing scope
- * @compile/fail/ref=LambdaScope04.out -XDrawDiagnostics LambdaScope04.java
+ * @compile/fail/ref=LambdaScope04_Source9.out -source 9 -Xlint:-options -XDrawDiagnostics LambdaScope04.java
+ * @compile/fail/ref=LambdaScope04_Source10.out -Xlint:-options -XDrawDiagnostics LambdaScope04.java
  */
 
 class LambdaScope04 {
diff --git a/test/langtools/tools/javac/lambda/LambdaScope04_Source10.out b/test/langtools/tools/javac/lambda/LambdaScope04_Source10.out
new file mode 100644
index 00000000000..74535a253c5
--- /dev/null
+++ b/test/langtools/tools/javac/lambda/LambdaScope04_Source10.out
@@ -0,0 +1,3 @@
+LambdaScope04.java:110:28: compiler.err.unreported.exception.implicit.close: java.lang.Exception, local
+LambdaScope04.java:118:28: compiler.err.unreported.exception.implicit.close: java.lang.Exception, local
+2 errors
diff --git a/test/langtools/tools/javac/lambda/LambdaScope04.out b/test/langtools/tools/javac/lambda/LambdaScope04_Source9.out
similarity index 52%
rename from test/langtools/tools/javac/lambda/LambdaScope04.out
rename to test/langtools/tools/javac/lambda/LambdaScope04_Source9.out
index 8cb2e2ab242..d474f8bf0c7 100644
--- a/test/langtools/tools/javac/lambda/LambdaScope04.out
+++ b/test/langtools/tools/javac/lambda/LambdaScope04_Source9.out
@@ -1,37 +1,37 @@
-LambdaScope04.java:23:18: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.instance.init, kindname.class, LambdaScope04
-LambdaScope04.java:24:34: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.instance.init, kindname.class, LambdaScope04
-LambdaScope04.java:29:18: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.static.init, kindname.class, LambdaScope04
-LambdaScope04.java:30:34: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.static.init, kindname.class, LambdaScope04
-LambdaScope04.java:36:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalInstance()
-LambdaScope04.java:37:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalInstance()
-LambdaScope04.java:43:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalStatic()
-LambdaScope04.java:44:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalStatic()
-LambdaScope04.java:49:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamInstance(java.lang.Object)
-LambdaScope04.java:50:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamInstance(java.lang.Object)
-LambdaScope04.java:55:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamStatic(java.lang.Object)
-LambdaScope04.java:56:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamStatic(java.lang.Object)
-LambdaScope04.java:62:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForInstance()
-LambdaScope04.java:63:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForInstance()
-LambdaScope04.java:70:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForStatic(java.lang.Iterable<java.lang.Object>)
-LambdaScope04.java:71:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForStatic(java.lang.Iterable<java.lang.Object>)
-LambdaScope04.java:78:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachInstance(java.lang.Iterable<java.lang.Object>)
-LambdaScope04.java:79:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachInstance(java.lang.Iterable<java.lang.Object>)
-LambdaScope04.java:86:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachStatic(java.lang.Iterable<java.lang.Object>)
-LambdaScope04.java:87:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachStatic(java.lang.Iterable<java.lang.Object>)
-LambdaScope04.java:94:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchInstance()
-LambdaScope04.java:95:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchInstance()
-LambdaScope04.java:102:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchStatic(java.lang.Iterable<java.lang.Object>)
-LambdaScope04.java:103:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchStatic(java.lang.Iterable<java.lang.Object>)
-LambdaScope04.java:110:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRInstance(java.lang.AutoCloseable)
-LambdaScope04.java:111:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRInstance(java.lang.AutoCloseable)
-LambdaScope04.java:118:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRStatic(java.lang.AutoCloseable)
-LambdaScope04.java:119:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRStatic(java.lang.AutoCloseable)
-LambdaScope04.java:127:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalInstance()
-LambdaScope04.java:128:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalInstance()
-LambdaScope04.java:136:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalStatic()
-LambdaScope04.java:137:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalStatic()
-LambdaScope04.java:146:26: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalInstance(int)
-LambdaScope04.java:147:42: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalInstance(int)
-LambdaScope04.java:157:26: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalStatic(int)
-LambdaScope04.java:158:42: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalStatic(int)
+LambdaScope04.java:24:18: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.instance.init, kindname.class, LambdaScope04
+LambdaScope04.java:25:34: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.instance.init, kindname.class, LambdaScope04
+LambdaScope04.java:30:18: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.static.init, kindname.class, LambdaScope04
+LambdaScope04.java:31:34: compiler.err.already.defined.in.clinit: kindname.variable, local, kindname.static.init, kindname.class, LambdaScope04
+LambdaScope04.java:37:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalInstance()
+LambdaScope04.java:38:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalInstance()
+LambdaScope04.java:44:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalStatic()
+LambdaScope04.java:45:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testLocalStatic()
+LambdaScope04.java:50:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamInstance(java.lang.Object)
+LambdaScope04.java:51:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamInstance(java.lang.Object)
+LambdaScope04.java:56:18: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamStatic(java.lang.Object)
+LambdaScope04.java:57:34: compiler.err.already.defined: kindname.variable, local, kindname.method, testParamStatic(java.lang.Object)
+LambdaScope04.java:63:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForInstance()
+LambdaScope04.java:64:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForInstance()
+LambdaScope04.java:71:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:72:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:79:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachInstance(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:80:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachInstance(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:87:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:88:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testForEachStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:95:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchInstance()
+LambdaScope04.java:96:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchInstance()
+LambdaScope04.java:103:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:104:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testCatchStatic(java.lang.Iterable<java.lang.Object>)
+LambdaScope04.java:111:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRInstance(java.lang.AutoCloseable)
+LambdaScope04.java:112:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRInstance(java.lang.AutoCloseable)
+LambdaScope04.java:119:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRStatic(java.lang.AutoCloseable)
+LambdaScope04.java:120:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testTWRStatic(java.lang.AutoCloseable)
+LambdaScope04.java:128:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalInstance()
+LambdaScope04.java:129:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalInstance()
+LambdaScope04.java:137:22: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalStatic()
+LambdaScope04.java:138:38: compiler.err.already.defined: kindname.variable, local, kindname.method, testBlockLocalStatic()
+LambdaScope04.java:147:26: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalInstance(int)
+LambdaScope04.java:148:42: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalInstance(int)
+LambdaScope04.java:158:26: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalStatic(int)
+LambdaScope04.java:159:42: compiler.err.already.defined: kindname.variable, local, kindname.method, testSwitchLocalStatic(int)
 36 errors
diff --git a/test/langtools/tools/javac/lambda/LambdaScope05.java b/test/langtools/tools/javac/lambda/LambdaScope05.java
index 0fbb4a20576..e3678b97a93 100644
--- a/test/langtools/tools/javac/lambda/LambdaScope05.java
+++ b/test/langtools/tools/javac/lambda/LambdaScope05.java
@@ -2,7 +2,8 @@
  * @test /nodynamiccopyright/
  * @bug 8015648
  * @summary Duplicate variable in lambda causes javac crash
- * @compile/fail/ref=LambdaScope05.out -XDrawDiagnostics LambdaScope05.java
+ * @compile/fail/ref=LambdaScope05_Source9.out -source 9 -Xlint:-options -XDrawDiagnostics LambdaScope05.java
+ * @compile -source 10 -Xlint:-options -XDrawDiagnostics LambdaScope05.java
  */
 
 class LambdaScope05 {
diff --git a/test/langtools/tools/javac/lambda/LambdaScope05.out b/test/langtools/tools/javac/lambda/LambdaScope05.out
deleted file mode 100644
index e96b9e5aad8..00000000000
--- a/test/langtools/tools/javac/lambda/LambdaScope05.out
+++ /dev/null
@@ -1,7 +0,0 @@
-LambdaScope05.java:13:47: compiler.err.already.defined.in.clinit: kindname.variable, p, kindname.static.init, kindname.class, LambdaScope05
-LambdaScope05.java:14:40: compiler.err.already.defined: kindname.variable, p, kindname.constructor, LambdaScope05()
-LambdaScope05.java:17:43: compiler.err.already.defined.in.clinit: kindname.variable, p, kindname.static.init, kindname.class, LambdaScope05
-LambdaScope05.java:21:43: compiler.err.already.defined.in.clinit: kindname.variable, p, kindname.instance.init, kindname.class, LambdaScope05
-LambdaScope05.java:25:43: compiler.err.already.defined: kindname.variable, p, kindname.method, m_static()
-LambdaScope05.java:29:43: compiler.err.already.defined: kindname.variable, p, kindname.method, m()
-6 errors
diff --git a/test/langtools/tools/javac/lambda/LambdaScope05_Source9.out b/test/langtools/tools/javac/lambda/LambdaScope05_Source9.out
new file mode 100644
index 00000000000..49e1cbfc12c
--- /dev/null
+++ b/test/langtools/tools/javac/lambda/LambdaScope05_Source9.out
@@ -0,0 +1,7 @@
+LambdaScope05.java:14:47: compiler.err.already.defined.in.clinit: kindname.variable, p, kindname.static.init, kindname.class, LambdaScope05
+LambdaScope05.java:15:40: compiler.err.already.defined: kindname.variable, p, kindname.constructor, LambdaScope05()
+LambdaScope05.java:18:43: compiler.err.already.defined.in.clinit: kindname.variable, p, kindname.static.init, kindname.class, LambdaScope05
+LambdaScope05.java:22:43: compiler.err.already.defined.in.clinit: kindname.variable, p, kindname.instance.init, kindname.class, LambdaScope05
+LambdaScope05.java:26:43: compiler.err.already.defined: kindname.variable, p, kindname.method, m_static()
+LambdaScope05.java:30:43: compiler.err.already.defined: kindname.variable, p, kindname.method, m()
+6 errors
diff --git a/test/langtools/tools/javac/lambda/UnderscoreAsIdent.java b/test/langtools/tools/javac/lambda/UnderscoreAsIdent.java
index dc50aa143e0..e18c9de9c75 100644
--- a/test/langtools/tools/javac/lambda/UnderscoreAsIdent.java
+++ b/test/langtools/tools/javac/lambda/UnderscoreAsIdent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
  * 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 @@
  * @test
  * @summary Check usages of underscore as identifier generate warnings
  * @compile/fail/ref=UnderscoreAsIdent8.out -source 8 -Xlint:-options -XDrawDiagnostics -Werror UnderscoreAsIdent.java
- * @compile/fail/ref=UnderscoreAsIdent9.out -XDrawDiagnostics -Werror UnderscoreAsIdent.java
+ * @compile/fail/ref=UnderscoreAsIdent9.out -source 9 -Xlint:-options -XDrawDiagnostics -Werror UnderscoreAsIdent.java
  */
 package _._;
 
diff --git a/test/langtools/tools/javac/lambda/deduplication/Deduplication.java b/test/langtools/tools/javac/lambda/deduplication/Deduplication.java
index d56f5127980..2b9a5e82b91 100644
--- a/test/langtools/tools/javac/lambda/deduplication/Deduplication.java
+++ b/test/langtools/tools/javac/lambda/deduplication/Deduplication.java
@@ -166,6 +166,12 @@ void f() {}
 
         group((Function<Object, Integer>) x -> x instanceof Integer i ? i : -1,
               (Function<Object, Integer>) x -> x instanceof Integer i ? i : -1);
+
+        group((Function<Object, Integer>) x -> x instanceof R(var i1, var i2) ? i1 : -1,
+              (Function<Object, Integer>) x -> x instanceof R(var i1, var i2) ? i1 : -1 );
+
+        group((Function<Object, Integer>) x -> x instanceof R(Integer i1, int i2) ? i2 : -1,
+              (Function<Object, Integer>) x -> x instanceof R(Integer i1, int i2) ? i2 : -1 );
     }
 
     void f() {}
@@ -174,4 +180,6 @@ void g() {}
 
     int i;
     int j;
+
+    record R(Integer i1, int i2) {}
 }
diff --git a/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java b/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java
index 5152d89a069..32f9a6a9c72 100644
--- a/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java
+++ b/test/langtools/tools/javac/lambda/deduplication/DeduplicationTest.java
@@ -134,6 +134,9 @@ public static void main(String[] args) throws Exception {
         Set<String> bootstrapMethodNames = new TreeSet<>();
         for (JavaFileObject output : generated) {
             ClassFile cf = ClassFile.read(output.openInputStream());
+            if (cf.getName().equals("com/sun/tools/javac/comp/Deduplication$R")) {
+                continue;
+            }
             BootstrapMethods_attribute bsm =
                     (BootstrapMethods_attribute) cf.getAttribute(Attribute.BootstrapMethods);
             for (BootstrapMethodSpecifier b : bsm.bootstrap_method_specifiers) {
diff --git a/test/langtools/tools/javac/lambda_leftovers/ShadowParametersTest01.java b/test/langtools/tools/javac/lambda_leftovers/ShadowParametersTest01.java
new file mode 100644
index 00000000000..71e3a515780
--- /dev/null
+++ b/test/langtools/tools/javac/lambda_leftovers/ShadowParametersTest01.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8173061
+ * @summary Shadowing of lambda parameters
+ * @compile ShadowParametersTest01.java
+ */
+
+import java.util.*;
+
+public class ShadowParametersTest01 {
+    void foo() {
+        Map<String, Integer> msi = null;
+        String key = "333";
+        msi.computeIfAbsent(key, key -> key.length());
+    }
+}
diff --git a/test/langtools/tools/javac/lambda_leftovers/ShadowParametersTest02.java b/test/langtools/tools/javac/lambda_leftovers/ShadowParametersTest02.java
new file mode 100644
index 00000000000..76f6267de5d
--- /dev/null
+++ b/test/langtools/tools/javac/lambda_leftovers/ShadowParametersTest02.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8173061
+ * @summary Shadowing of lambda parameters
+ * @modules jdk.compiler/com.sun.tools.javac.util
+ * @run main ShadowParametersTest02
+ */
+
+import com.sun.tools.javac.util.Assert;
+
+public class ShadowParametersTest02 {
+    public static void main(String... args) {
+        new ShadowParametersTest02().tests();
+    }
+
+    void tests() {
+        m(1);
+        Assert.check(str.equals("Hi from lambda"));
+        Assert.check(b);
+    }
+
+    String str = null;
+    boolean b = false;
+
+    void m(int x) {
+        Runnable r = () -> {
+            String x = "Hi from lambda";
+            str = x;
+            Runnable r = () -> {
+                boolean x = true;
+                b = x;
+            };
+            r.run();
+        };
+        r.run();
+    }
+}
diff --git a/test/langtools/tools/javac/lambda_leftovers/UnderscoreCantBeFollowedByDimsTest.java b/test/langtools/tools/javac/lambda_leftovers/UnderscoreCantBeFollowedByDimsTest.java
new file mode 100644
index 00000000000..feff3cec230
--- /dev/null
+++ b/test/langtools/tools/javac/lambda_leftovers/UnderscoreCantBeFollowedByDimsTest.java
@@ -0,0 +1,10 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8177513
+ * @summary underscore can't be followed by dimensions
+ * @compile/fail/ref=UnderscoreCantBeFollowedByDimsTest.out -XDrawDiagnostics UnderscoreCantBeFollowedByDimsTest.java
+ */
+
+public class UnderscoreCantBeFollowedByDimsTest {
+    void m(String _[]) {}
+}
diff --git a/test/langtools/tools/javac/lambda_leftovers/UnderscoreCantBeFollowedByDimsTest.out b/test/langtools/tools/javac/lambda_leftovers/UnderscoreCantBeFollowedByDimsTest.out
new file mode 100644
index 00000000000..505636f7580
--- /dev/null
+++ b/test/langtools/tools/javac/lambda_leftovers/UnderscoreCantBeFollowedByDimsTest.out
@@ -0,0 +1,3 @@
+UnderscoreCantBeFollowedByDimsTest.java:9:19: compiler.err.underscore.as.identifier.in.method
+UnderscoreCantBeFollowedByDimsTest.java:9:20: compiler.err.underscore.cant.be.followed.by.dimensions
+2 errors
diff --git a/test/langtools/tools/javac/lambda_leftovers/UnderscoreInCatchClauseTest.java b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInCatchClauseTest.java
new file mode 100644
index 00000000000..02722f90313
--- /dev/null
+++ b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInCatchClauseTest.java
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8173059
+ * @summary Underscore for unnamed method, constructor, lambda, and catch formals
+ * @compile/fail/ref=UnderscoreInCatchClauseTest.out -XDrawDiagnostics UnderscoreInCatchClauseTest.java
+ */
+
+public class UnderscoreInCatchClauseTest {
+    void foo() {
+        // this use should be allowed
+        try { } catch (Throwable _) {
+            // this use should be forbidden
+            throw _;
+        }
+    }
+}
diff --git a/test/langtools/tools/javac/lambda_leftovers/UnderscoreInCatchClauseTest.out b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInCatchClauseTest.out
new file mode 100644
index 00000000000..9e73b28be74
--- /dev/null
+++ b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInCatchClauseTest.out
@@ -0,0 +1,2 @@
+UnderscoreInCatchClauseTest.java:13:19: compiler.err.underscore.not.allowed
+1 error
diff --git a/test/langtools/tools/javac/lambda_leftovers/UnderscoreInLambdaTest.java b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInLambdaTest.java
new file mode 100644
index 00000000000..20f77a1de2b
--- /dev/null
+++ b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInLambdaTest.java
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8173059
+ * @summary Underscore for unnamed method, constructor, lambda, and catch formals
+ * @compile/fail/ref=UnderscoreInLambdaTest.out -XDrawDiagnostics UnderscoreInLambdaTest.java
+ */
+
+import java.util.function.*;
+
+public class UnderscoreInLambdaTest {
+    void foo() {
+        // error
+        BiFunction<Integer, String, String> biss1 =
+                (_, _) ->
+                    String.valueOf(_); // this use will be detected and banned by the parser
+        // ok implicit
+        BiFunction<Integer, String, String> biss2 =
+                (_, _) -> "";
+        // ok explicit
+        BiFunction<Integer, String, String> biss2 =
+                (int _, String _) -> "";
+    }
+}
diff --git a/test/langtools/tools/javac/lambda_leftovers/UnderscoreInLambdaTest.out b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInLambdaTest.out
new file mode 100644
index 00000000000..c59792516fd
--- /dev/null
+++ b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInLambdaTest.out
@@ -0,0 +1,2 @@
+UnderscoreInLambdaTest.java:15:36: compiler.err.underscore.not.allowed
+1 error
diff --git a/test/langtools/tools/javac/lambda_leftovers/UnderscoreInMethodsTest.java b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInMethodsTest.java
new file mode 100644
index 00000000000..221984cd281
--- /dev/null
+++ b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInMethodsTest.java
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8173059
+ * @summary Underscore for unnamed method, constructor, lambda, and catch formals
+ * @compile/fail/ref=UnderscoreInMethodsTest.out -XDrawDiagnostics UnderscoreInMethodsTest.java
+ */
+
+public class UnderscoreInMethodsTest {
+    class Super {
+        void m(String _) {}
+    }
+
+    class Child extends Super {
+        void m(String _) {
+            // error '_' is not in scope so it can't be used inside the method
+            System.out.println(_);
+        }
+    }
+}
diff --git a/test/langtools/tools/javac/lambda_leftovers/UnderscoreInMethodsTest.out b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInMethodsTest.out
new file mode 100644
index 00000000000..1fc88c43f3f
--- /dev/null
+++ b/test/langtools/tools/javac/lambda_leftovers/UnderscoreInMethodsTest.out
@@ -0,0 +1,4 @@
+UnderscoreInMethodsTest.java:10:23: compiler.err.underscore.as.identifier.in.method
+UnderscoreInMethodsTest.java:14:23: compiler.err.underscore.as.identifier.in.method
+UnderscoreInMethodsTest.java:16:32: compiler.err.underscore.not.allowed
+3 errors
diff --git a/test/langtools/tools/javac/lvti/SelfRefTest.java b/test/langtools/tools/javac/lvti/SelfRefTest.java
index 98f956d96b2..e04b38e2b12 100644
--- a/test/langtools/tools/javac/lvti/SelfRefTest.java
+++ b/test/langtools/tools/javac/lvti/SelfRefTest.java
@@ -14,7 +14,7 @@ class SelfRefTest {
 
     void test(boolean cond) {
        var x = cond ? x : x; //error - self reference
-       var y = (Function<Integer, Integer>)(Integer y) -> y; //error - bad shadowing
+       var y = (Function<Integer, Integer>)(Integer y) -> y; //error - bad shadowing - but ok in lambda leftovers!
        var z = (Runnable)() -> { int z2 = m(z); }; //error - self reference
        var w = new Object() { int w = 42; void test() { int w2 = w; } }; //ok
        int u = u; //ok
diff --git a/test/langtools/tools/javac/lvti/SelfRefTest.out b/test/langtools/tools/javac/lvti/SelfRefTest.out
index 97a558c4543..5a01ee70d40 100644
--- a/test/langtools/tools/javac/lvti/SelfRefTest.out
+++ b/test/langtools/tools/javac/lvti/SelfRefTest.out
@@ -1,4 +1,3 @@
 SelfRefTest.java:16:12: compiler.err.cant.infer.local.var.type: x, (compiler.misc.local.self.ref)
-SelfRefTest.java:17:53: compiler.err.already.defined: kindname.variable, y, kindname.method, test(boolean)
 SelfRefTest.java:18:12: compiler.err.cant.infer.local.var.type: z, (compiler.misc.local.self.ref)
-3 errors
+2 errors
diff --git a/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java
new file mode 100644
index 00000000000..94745936004
--- /dev/null
+++ b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.java
@@ -0,0 +1,40 @@
+/**
+ * @test /nodynamiccopyright/
+ * @summary Verify error reports for erroneous deconstruction patterns are sensible
+ * @compile/fail/ref=DeconstructionPatternErrors.out --enable-preview -source ${jdk.version} -XDrawDiagnostics -XDshould-stop.at=FLOW DeconstructionPatternErrors.java
+ */
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class DeconstructionPatternErrors {
+
+    public static void main(String... args) throws Throwable {
+        Object p;
+        p = new P(42);
+        if (p instanceof P(_));
+        if (p instanceof P3(ArrayList<Integer> l));
+        if (p instanceof P4(ArrayList<Integer> l));
+        if (p instanceof P5(int i));
+        if (p instanceof P(String s));
+        if (p instanceof P5(P(var v)));
+        if (p instanceof P2(var v1)); //too few nested patterns
+        if (p instanceof P2(Runnable v1)); //too few nested patterns
+        if (p instanceof P(var v1, var v2)); //too many nested patterns
+        if (p instanceof P(int v1, int v2)); //too many nested patterns
+        if (p instanceof P(int v1, Unresolvable v2)); //too many nested patterns
+        if (p instanceof GenRecord<String>(var v)); //incorrect generic type
+        if (p instanceof P4(GenRecord<String>(var v))); //incorrect generic type
+        if (p instanceof GenRecord<String>(Integer v)); //inconsistency in types
+    }
+
+    public record P(int i) {
+    }
+
+    public record P2(Runnable r1, Runnable r2) {}
+    public record P3(List<String> l) {}
+    public record P4(Object o) {}
+    public record P5(String s) {}
+    public record GenRecord<T>(T s) {}
+
+}
diff --git a/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out
new file mode 100644
index 00000000000..fb6db43447f
--- /dev/null
+++ b/test/langtools/tools/javac/patterns/DeconstructionPatternErrors.out
@@ -0,0 +1,20 @@
+DeconstructionPatternErrors.java:15:28: compiler.err.underscore.as.identifier
+DeconstructionPatternErrors.java:15:29: compiler.err.expected: token.identifier
+DeconstructionPatternErrors.java:16:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.util.List<java.lang.String>, java.util.ArrayList<java.lang.Integer>)
+DeconstructionPatternErrors.java:17:29: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, java.util.ArrayList<java.lang.Integer>
+DeconstructionPatternErrors.java:18:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, int)
+DeconstructionPatternErrors.java:19:28: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String)
+DeconstructionPatternErrors.java:20:29: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, DeconstructionPatternErrors.P)
+DeconstructionPatternErrors.java:21:26: compiler.err.incorrect.number.of.nested.patterns: java.lang.Runnable,java.lang.Runnable, java.lang.Runnable
+DeconstructionPatternErrors.java:22:26: compiler.err.incorrect.number.of.nested.patterns: java.lang.Runnable,java.lang.Runnable, java.lang.Runnable
+DeconstructionPatternErrors.java:23:26: compiler.err.incorrect.number.of.nested.patterns: int, int,compiler.misc.type.none
+DeconstructionPatternErrors.java:24:26: compiler.err.incorrect.number.of.nested.patterns: int, int,int
+DeconstructionPatternErrors.java:25:36: compiler.err.cant.resolve.location: kindname.class, Unresolvable, , , (compiler.misc.location: kindname.class, DeconstructionPatternErrors, null)
+DeconstructionPatternErrors.java:25:26: compiler.err.incorrect.number.of.nested.patterns: int, int,Unresolvable
+DeconstructionPatternErrors.java:26:13: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord<java.lang.String>
+DeconstructionPatternErrors.java:27:29: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord<java.lang.String>
+DeconstructionPatternErrors.java:28:44: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)
+DeconstructionPatternErrors.java:28:13: compiler.err.instanceof.reifiable.not.safe: java.lang.Object, DeconstructionPatternErrors.GenRecord<java.lang.String>
+- compiler.note.preview.filename: DeconstructionPatternErrors.java
+- compiler.note.preview.recompile
+17 errors
diff --git a/test/langtools/tools/javac/patterns/PrettyTest.java b/test/langtools/tools/javac/patterns/PrettyTest.java
new file mode 100644
index 00000000000..4714e8550b7
--- /dev/null
+++ b/test/langtools/tools/javac/patterns/PrettyTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 behavior of Pretty
+ * @modules jdk.compiler
+ * @compile --enable-preview -source ${jdk.version} PrettyTest.java
+ * @run main/othervm --enable-preview PrettyTest
+ */
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.tools.*;
+
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.util.JavacTask;
+
+public class PrettyTest {
+
+    public static void main(String[] args) throws Exception {
+        new PrettyTest().run();
+    }
+
+    void run() throws Exception {
+        String code = "class Test {\n" +
+                      "    boolean t(Object o) {\n" +
+                      "         boolean b;\n" +
+                      "         b = o instanceof String s;\n" +
+                      "         b = o instanceof R(String s);\n" +
+                      "         b = o instanceof R(var s);\n" +
+                      "         b = o instanceof R2(R(var s), String t);\n" +
+                      "         b = o instanceof R2(R(var s), var t);\n" +
+                      "    }\n" +
+                      "    record R(String s) {}\n" +
+                      "    record R2(R r, String s) {}\n" +
+                      "}\n";
+        String pretty = parse(code).toString();
+        String expected = """
+                          \n\
+                          class Test {
+                              \n\
+                              boolean t(Object o) {
+                                  boolean b;
+                                  b = o instanceof String s;
+                                  b = o instanceof R(String s);
+                                  b = o instanceof R(/*missing*/ s);
+                                  b = o instanceof R2(R(/*missing*/ s), String t);
+                                  b = o instanceof R2(R(/*missing*/ s), /*missing*/ t);
+                              }
+                              \n\
+                              class R {
+                                  private final String s;
+                              }
+                              \n\
+                              class R2 {
+                                  private final R r;
+                                  private final String s;
+                              }
+                          }""";
+        if (!expected.equals(pretty)) {
+            throw new AssertionError("Actual prettified source: " + pretty);
+        }
+    }
+
+    private CompilationUnitTree parse(String code) throws IOException {
+        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+        assert tool != null;
+        DiagnosticListener<JavaFileObject> noErrors = d -> {};
+
+        StringWriter out = new StringWriter();
+        JavacTask ct = (JavacTask) tool.getTask(out, null, noErrors,
+            List.of("--enable-preview", "-source", Integer.toString(Runtime.version().feature())), null,
+            Arrays.asList(new MyFileObject(code)));
+        return ct.parse().iterator().next();
+    }
+
+    static class MyFileObject extends SimpleJavaFileObject {
+        private String text;
+
+        public MyFileObject(String text) {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            this.text = text;
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return text;
+        }
+    }
+}
diff --git a/test/langtools/tools/javac/patterns/SimpleDeconstructionPattern.java b/test/langtools/tools/javac/patterns/SimpleDeconstructionPattern.java
new file mode 100644
index 00000000000..f295cfa7ca3
--- /dev/null
+++ b/test/langtools/tools/javac/patterns/SimpleDeconstructionPattern.java
@@ -0,0 +1,246 @@
+/**
+ * @test
+ * @compile/fail/ref=SimpleDeconstructionPatternNoPreview.out -XDrawDiagnostics SimpleDeconstructionPattern.java
+ * @compile --enable-preview -source ${jdk.version} SimpleDeconstructionPattern.java
+ * @run main/othervm --enable-preview SimpleDeconstructionPattern
+ */
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+public class SimpleDeconstructionPattern {
+
+    public static void main(String... args) throws Throwable {
+//        if (!test1(new P(42))) {
+//            throw new IllegalStateException();
+//        }
+//        if (test1(new P(41))) {
+//            throw new IllegalStateException();
+//        }
+        if (!test2(new P(42))) {
+            throw new IllegalStateException();
+        }
+        if (test2(new P(41))) {
+            throw new IllegalStateException();
+        }
+        if (!test2a(new P(42))) {
+            throw new IllegalStateException();
+        }
+        if (test2a(new P(41))) {
+            throw new IllegalStateException();
+        }
+//        if (!test3(new P2(new P(42), ""))) {
+//            throw new IllegalStateException();
+//        }
+//        if (test3(new P2(new P(41), ""))) {
+//            throw new IllegalStateException();
+//        }
+//        if (test3(new P2(new P(42), "a"))) {
+//            throw new IllegalStateException();
+//        }
+        if (!test4(new P2(new P(42), ""))) {
+            throw new IllegalStateException();
+        }
+        if (test4(new P2(new P(41), ""))) {
+            throw new IllegalStateException();
+        }
+        if (test4(new P2(new P(42), "a"))) {
+            throw new IllegalStateException();
+        }
+        if (!test5(new P(42))) {
+            throw new IllegalStateException();
+        }
+        if (test5(new P(41))) {
+            throw new IllegalStateException();
+        }
+//        if (!test6(new P(42))) {
+//            throw new IllegalStateException();
+//        }
+//        if (!test6(new P(41))) {
+//            throw new IllegalStateException();
+//        }
+//        if (!((new BaseUse(new BaseSubclass(0))) instanceof BaseUse(BaseSubclass(0)))) {
+//            throw new IllegalStateException();
+//        }
+        if (!test7(new P3(""))) {
+            throw new IllegalStateException();
+        }
+        if (test7(new P3("a"))) {
+            throw new IllegalStateException();
+        }
+        if (!test7a(new P3(""))) {
+            throw new IllegalStateException();
+        }
+        if (test7a(new P3("a"))) {
+            throw new IllegalStateException();
+        }
+        if (test8(new P4(""))) {
+            throw new IllegalStateException();
+        }
+        if (!test8(new P4(new P3("")))) {
+            throw new IllegalStateException();
+        }
+        if (!test8a(new P4(new P3("")))) {
+            throw new IllegalStateException();
+        }
+        if (test8(new P4(new P3("a")))) {
+            throw new IllegalStateException();
+        }
+        if (test8a(new P4(new P3("a")))) {
+            throw new IllegalStateException();
+        }
+        if (!test9(new P5(new ArrayList<String>(Arrays.asList(""))))) {
+            throw new IllegalStateException();
+        }
+        if (test9(new P5(new LinkedList<String>(Arrays.asList(""))))) {
+            throw new IllegalStateException();
+        }
+        if (testA(new P6(null))) {
+            throw new IllegalStateException();
+        }
+        if (testA(new P6(new P3(null)))) {
+            throw new IllegalStateException();
+        }
+        if (testB(new P6(null))) {
+            throw new IllegalStateException();
+        }
+        if (testB(new P6(new P3(null)))) {
+            throw new IllegalStateException();
+        }
+        if (testC(new P6(null))) {
+            throw new IllegalStateException();
+        }
+        if (testC(new P6(new P3(null)))) {
+            throw new IllegalStateException();
+        }
+        if (!testC(new P6(new P3("")))) {
+            throw new IllegalStateException();
+        }
+        if (!testGen1(new GenRecord1<>(1L, ""))) {
+            throw new IllegalStateException();
+        }
+        if (testGen1(new GenRecord1<>(1L, "a"))) {
+            throw new IllegalStateException();
+        }
+        if (testGen2(new GenRecord1<>(3L, ""))) {
+            throw new IllegalStateException();
+        }
+        if (!testGen2(new GenRecord1<>(3, ""))) {
+            throw new IllegalStateException();
+        }
+        if (testGen3(new GenRecord1<>(3L, ""))) {
+            throw new IllegalStateException();
+        }
+        if (!testGen3(new GenRecord1<>(3, ""))) {
+            throw new IllegalStateException();
+        }
+        if (!testGen3(new GenRecord1<>(3, ""))) {
+            throw new IllegalStateException();
+        }
+    }
+
+//    private static boolean test1(Object o) throws Throwable {
+//        return o instanceof P(42);
+//    }
+//
+    private static void exp(Object o) throws Throwable {
+        if (o instanceof P(var i)) {
+            System.err.println("i=" + i);
+        }
+    }
+
+    private static boolean test2(Object o) throws Throwable {
+        return o instanceof P(var i) && i == 42;
+    }
+
+    private static boolean test2a(Object o) throws Throwable {
+        return o instanceof P(int i) && i == 42;
+    }
+
+//    private static boolean test3(Object o) throws Throwable {
+//        return o instanceof P2(P(42), "");
+//    }
+//
+    private static boolean test4(Object o) throws Throwable {
+        return o instanceof P2(P(var i), var s) && i == 42 && "".equals(s);
+    }
+
+    private static boolean test5(Object o) throws Throwable {
+        return o instanceof P(var i) && i == 42;
+    }
+
+//    private static boolean test6(Object o) throws Throwable {
+//        return o instanceof P(_);
+//    }
+
+    private static boolean test7(Object o) throws Throwable {
+        return o instanceof P3(var s) && "".equals(s);
+    }
+
+    private static boolean test7a(Object o) throws Throwable {
+        return o instanceof P3(String s) && "".equals(s);
+    }
+
+    private static boolean test8(Object o) throws Throwable {
+        return o instanceof P4(P3(var s)) && "".equals(s);
+    }
+
+    private static boolean test8a(Object o) throws Throwable {
+        return o instanceof P4(P3(String s)) && "".equals(s);
+    }
+
+    private static boolean test9(Object o) throws Throwable {
+        return o instanceof P5(ArrayList<String> l) && !l.isEmpty();
+    }
+
+    private static boolean testA(Object o) throws Throwable {
+        return o instanceof P6(P3(var s));
+    }
+
+    private static boolean testB(Object o) throws Throwable {
+        return o instanceof P6(P3(String s));
+    }
+
+    private static boolean testC(Object o) throws Throwable {
+        return o instanceof P6(P3(String s)) && s.isEmpty();
+    }
+
+    private static boolean testGen1(Object o) throws Throwable {
+        return o instanceof GenRecord1(var i, var s) && s.length() == 0;
+    }
+
+    private static boolean testGen2(Object o) throws Throwable {
+        return o instanceof GenRecord1(Integer i, var s) && i.intValue() == 3 && s.length() == 0;
+    }
+
+    private static boolean testGen3(Object o) throws Throwable {
+        return o instanceof GenRecord1<?, ?>(Integer i, var s) && i.intValue() == 3 && s.length() == 0;
+    }
+
+    private static boolean testGen4(GenBase<Integer, String> o) throws Throwable {
+        return o instanceof GenRecord1<Integer, String>(var i, var s) && i.intValue() == 3 && s.length() == 0;
+    }
+
+    public record P(int i) {
+    }
+
+    public record P2(P p, String s) {
+    }
+
+    public record P3(String s) {
+    }
+
+    public record P4(Object o) {}
+
+    public record P5(List<String> l) {}
+    public record P6(P3 p) {}
+
+    public interface Base {}
+    public record BaseUse(Base b) {}
+    public record BaseSubclass(int i) implements Base {}
+
+    public interface GenBase<T1, T2 extends CharSequence> {}
+    public record GenRecord1<T1, T2 extends CharSequence> (T1 i, T2 s) implements GenBase<T1, T2> {}
+}
diff --git a/test/langtools/tools/javac/patterns/SimpleDeconstructionPatternNoPreview.out b/test/langtools/tools/javac/patterns/SimpleDeconstructionPatternNoPreview.out
new file mode 100644
index 00000000000..b08eb1f0fde
--- /dev/null
+++ b/test/langtools/tools/javac/patterns/SimpleDeconstructionPatternNoPreview.out
@@ -0,0 +1,17 @@
+SimpleDeconstructionPattern.java:149:27: compiler.err.preview.feature.disabled.plural: (compiler.misc.feature.deconstruction.patterns)
+SimpleDeconstructionPattern.java:226:12: compiler.warn.restricted.type.not.allowed.preview: record, 14
+SimpleDeconstructionPattern.java:229:12: compiler.warn.restricted.type.not.allowed.preview: record, 14
+SimpleDeconstructionPattern.java:232:12: compiler.warn.restricted.type.not.allowed.preview: record, 14
+SimpleDeconstructionPattern.java:235:12: compiler.warn.restricted.type.not.allowed.preview: record, 14
+SimpleDeconstructionPattern.java:237:12: compiler.warn.restricted.type.not.allowed.preview: record, 14
+SimpleDeconstructionPattern.java:238:12: compiler.warn.restricted.type.not.allowed.preview: record, 14
+SimpleDeconstructionPattern.java:241:12: compiler.warn.restricted.type.not.allowed.preview: record, 14
+SimpleDeconstructionPattern.java:242:12: compiler.warn.restricted.type.not.allowed.preview: record, 14
+SimpleDeconstructionPattern.java:242:38: compiler.err.expected: ';'
+SimpleDeconstructionPattern.java:245:12: compiler.warn.restricted.type.not.allowed.preview: record, 14
+SimpleDeconstructionPattern.java:245:29: compiler.err.expected: ';'
+SimpleDeconstructionPattern.java:245:59: compiler.err.illegal.start.of.type
+SimpleDeconstructionPattern.java:245:71: compiler.err.expected: ';'
+SimpleDeconstructionPattern.java:245:99: compiler.err.illegal.start.of.type
+6 errors
+9 warnings
diff --git a/test/langtools/tools/javac/sealed/SealedCompilationTests.java b/test/langtools/tools/javac/sealed/SealedCompilationTests.java
index 5313d5a1275..3671046b05a 100644
--- a/test/langtools/tools/javac/sealed/SealedCompilationTests.java
+++ b/test/langtools/tools/javac/sealed/SealedCompilationTests.java
@@ -956,4 +956,15 @@ sealed static class Super permits Outer.Sub {}
             assertOK(s);
         }
     }
+
+    public void testDoNotAllowSealedAnnotation() {
+        for (String s : List.of(
+            """
+            sealed @interface A {}
+            non-sealed interface I extends A {}
+            """
+        )) {
+            assertFail("compiler.err.expected4", s);
+        }
+    }
 }
diff --git a/test/lib/jdk/test/lib/SigTestUtil.java b/test/lib/jdk/test/lib/SigTestUtil.java
index f6775cda37d..b04f2215f8a 100644
--- a/test/lib/jdk/test/lib/SigTestUtil.java
+++ b/test/lib/jdk/test/lib/SigTestUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,10 +54,14 @@ public String toString() {
     // collection of all supported digest algorithms
     // note that the entries are ordered by required key sizes
     private static final String[] DIGEST_ALGS = {
+        "SHA3-512",
         "SHA-512",
+        "SHA3-384",
         "SHA-384",
+        "SHA3-256",
         "SHA-256",
         "SHA-512/256",
+        "SHA3-224",
         "SHA-224",
         "SHA-512/224",
         "SHA-1",
@@ -66,14 +70,14 @@ public String toString() {
 
     // indice for message digest algorithms lookup
     // may need to be adjusted if new algorithms are added
-    private static final int PKCS1_5_INDEX_768 = 0;
-    private static final int PKCS1_5_INDEX_512 = 2;
+    private static final int PKCS1_5_INDEX_768 = 0; // 512, 384-bit digests
+    private static final int PKCS1_5_INDEX_512 = 4; // 256-bit digests
     private static final int PKCS1_5_INDEX_END = DIGEST_ALGS.length;
-    private static final int PSS_INDEX_2048 = 0;
-    private static final int PSS_INDEX_1024 = 1;
-    private static final int PSS_INDEX_768 = 2;
-    private static final int PSS_INDEX_512 = 4;
-    private static final int PSS_INDEX_END = 7;
+    private static final int PSS_INDEX_2048 = 0; // 512-bit digests
+    private static final int PSS_INDEX_1024 = 2; // 384-bit digests
+    private static final int PSS_INDEX_768 = 4; // 256-bit digests
+    private static final int PSS_INDEX_512 = 7; // 224-bit digests
+    private static final int PSS_INDEX_END = DIGEST_ALGS.length - 2;
 
     public static Iterable<String> getDigestAlgorithms(SignatureType type,
             int keysize) throws RuntimeException {
@@ -135,9 +139,8 @@ public static String generateSigAlg(SignatureType type,
             String mdAlg) throws RuntimeException {
         switch (type) {
         case RSA:
-            int idx = mdAlg.indexOf("-");
-            if (idx != -1) {
-                mdAlg = mdAlg.substring(0, idx) + mdAlg.substring(idx+1);
+            if (mdAlg.startsWith("SHA-")) {
+                mdAlg = mdAlg.substring(0, 3) + mdAlg.substring(4);
             }
             return mdAlg + "with" + type.toString();
         case RSASSA_PSS:
diff --git a/test/micro/org/openjdk/bench/java/net/ThreadLocalParseUtil.java b/test/micro/org/openjdk/bench/java/net/ThreadLocalParseUtil.java
new file mode 100644
index 00000000000..1bdcefbef7d
--- /dev/null
+++ b/test/micro/org/openjdk/bench/java/net/ThreadLocalParseUtil.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.net;
+
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.Fork;
+import org.openjdk.jmh.annotations.CompilerControl;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Setup;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.net.URI;
+import java.net.URL;
+import java.util.concurrent.TimeUnit;
+
+import static java.lang.invoke.MethodType.methodType;
+
+@BenchmarkMode(Mode.AverageTime)
+@OutputTimeUnit(TimeUnit.NANOSECONDS)
+@State(Scope.Thread)
+@Fork(value = 1, jvmArgsAppend = "--add-exports=java.base/sun.net.www=ALL-UNNAMED")
+public class ThreadLocalParseUtil {
+
+    private static final MethodHandle MH_DECODE;
+    private static final MethodHandle MH_TO_URI;
+
+    static {
+        final MethodHandles.Lookup lookup = MethodHandles.lookup();
+        try {
+            Class<?> c = Class.forName("sun.net.www.ParseUtil");
+            MH_DECODE = lookup.findStatic(c, "decode", methodType(String.class, String.class));
+            MH_TO_URI = lookup.findStatic(c, "toURI", methodType(URI.class, URL.class));
+        } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) {
+            throw new ExceptionInInitializerError(e);
+        }
+    }
+
+    @Benchmark
+    public String decodeTest() throws Throwable {
+        return (String) MH_DECODE.invokeExact("/xyz/\u00A0\u00A0");
+    }
+
+    @Benchmark
+    public URI appendEncodedTest() throws Throwable {
+        URL url = new URL("https://example.com/xyz/abc/def?query=#30");
+        return (URI) MH_TO_URI.invokeExact(url);
+    }
+}