Merge
authorpsadhukhan
Wed, 15 May 2019 13:54:43 +0530
changeset 54879 f5c0793f2dc1
parent 54878 b267b838272f (current diff)
parent 54852 ddb27517396c (diff)
child 54880 b0b20413d853
child 55168 cb2628a4f33f
Merge
src/hotspot/share/gc/g1/g1InCSetState.hpp
src/hotspot/share/gc/z/zPreMappedMemory.cpp
src/hotspot/share/gc/z/zPreMappedMemory.hpp
src/hotspot/share/gc/z/zPreMappedMemory.inline.hpp
src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPhysicalMemoryManager.java
--- a/make/autoconf/lib-bundled.m4	Tue May 14 11:23:08 2019 +0530
+++ b/make/autoconf/lib-bundled.m4	Wed May 15 13:54:43 2019 +0530
@@ -161,8 +161,8 @@
   AC_MSG_CHECKING([for which zlib to use])
 
   DEFAULT_ZLIB=system
-  if test "x$OPENJDK_TARGET_OS" = xwindows; then
-    # On windows default is bundled...on others default is system
+  if test "x$OPENJDK_TARGET_OS" = xwindows -o "x$OPENJDK_TARGET_OS" = xaix; then
+    # On windows and aix default is bundled, on others default is system
     DEFAULT_ZLIB=bundled
   fi
 
--- a/make/hotspot/gensrc/GensrcJvmti.gmk	Tue May 14 11:23:08 2019 +0530
+++ b/make/hotspot/gensrc/GensrcJvmti.gmk	Wed May 15 13:54:43 2019 +0530
@@ -100,12 +100,17 @@
 endef
 
 $(eval $(call SetupJvmtiGeneration, jvmtiEnter.cpp, jvmtiEnter.xsl, \
+    -PARAM majorversion $(VERSION_FEATURE) \
     -PARAM interface jvmti))
 $(eval $(call SetupJvmtiGeneration, jvmtiEnterTrace.cpp, jvmtiEnter.xsl, \
+    -PARAM majorversion $(VERSION_FEATURE) \
     -PARAM interface jvmti -PARAM trace Trace))
-$(eval $(call SetupJvmtiGeneration, jvmtiEnv.hpp, jvmtiHpp.xsl))
-$(eval $(call SetupJvmtiGeneration, jvmti.h, jvmtiH.xsl))
-$(eval $(call SetupJvmtiGeneration, jvmti.html, jvmti.xsl))
+$(eval $(call SetupJvmtiGeneration, jvmtiEnv.hpp, jvmtiHpp.xsl, \
+    -PARAM majorversion $(VERSION_FEATURE)))
+$(eval $(call SetupJvmtiGeneration, jvmti.h, jvmtiH.xsl, \
+    -PARAM majorversion $(VERSION_FEATURE)))
+$(eval $(call SetupJvmtiGeneration, jvmti.html, jvmti.xsl, \
+    -PARAM majorversion $(VERSION_FEATURE)))
 
 JVMTI_BC_SRCDIR := $(TOPDIR)/src/hotspot/share/interpreter
 
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1413,7 +1413,6 @@
       out_sig_bt[argc++] = in_sig_bt[i];
     }
   } else {
-    Thread* THREAD = Thread::current();
     in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args);
     SignatureStream ss(method->signature());
     for (int i = 0; i < total_in_args ; i++ ) {
@@ -1421,7 +1420,7 @@
         // Arrays are passed as int, elem* pair
         out_sig_bt[argc++] = T_INT;
         out_sig_bt[argc++] = T_ADDRESS;
-        Symbol* atype = ss.as_symbol(CHECK_NULL);
+        Symbol* atype = ss.as_symbol();
         const char* at = atype->as_C_string();
         if (strlen(at) == 2) {
           assert(at[0] == '[', "must be");
--- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -1908,14 +1908,13 @@
       out_sig_bt[argc++] = in_sig_bt[i];
     }
   } else {
-    Thread* THREAD = Thread::current();
     in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args);
     SignatureStream ss(method->signature());
     int o = 0;
     for (int i = 0; i < total_in_args ; i++, o++) {
       if (in_sig_bt[i] == T_ARRAY) {
         // Arrays are passed as int, elem* pair
-        Symbol* atype = ss.as_symbol(CHECK_NULL);
+        Symbol* atype = ss.as_symbol();
         const char* at = atype->as_C_string();
         if (strlen(at) == 2) {
           assert(at[0] == '[', "must be");
--- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * Copyright (c) 2016, 2018 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -1618,14 +1618,13 @@
       out_sig_bt[argc++] = in_sig_bt[i];
     }
   } else {
-    Thread* THREAD = Thread::current();
     in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args);
     SignatureStream ss(method->signature());
     int o = 0;
     for (int i = 0; i < total_in_args; i++, o++) {
       if (in_sig_bt[i] == T_ARRAY) {
         // Arrays are passed as tuples (int, elem*).
-        Symbol* atype = ss.as_symbol(CHECK_NULL);
+        Symbol* atype = ss.as_symbol();
         const char* at = atype->as_C_string();
         if (strlen(at) == 2) {
           assert(at[0] == '[', "must be");
--- a/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/sparc/sharedRuntime_sparc.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1906,7 +1906,7 @@
         // Arrays are passed as int, elem* pair
         out_sig_bt[argc++] = T_INT;
         out_sig_bt[argc++] = T_ADDRESS;
-        Symbol* atype = ss.as_symbol(CHECK_NULL);
+        Symbol* atype = ss.as_symbol();
         const char* at = atype->as_C_string();
         if (strlen(at) == 2) {
           assert(at[0] == '[', "must be");
--- a/src/hotspot/cpu/x86/compiledIC_x86.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/x86/compiledIC_x86.cpp	Wed May 15 13:54:43 2019 +0530
@@ -159,10 +159,10 @@
   NativeJump*        jump          = nativeJump_at(method_holder->next_instruction_address());
 
 #ifdef ASSERT
-  // read the value once
-  volatile intptr_t data = method_holder->data();
-  volatile address destination = jump->jump_destination();
-  assert(data == 0 || data == (intptr_t)callee(),
+  Method* old_method = reinterpret_cast<Method*>(method_holder->data());
+  address destination = jump->jump_destination();
+  assert(old_method == NULL || old_method == callee() ||
+         !old_method->method_holder()->is_loader_alive(),
          "a) MT-unsafe modification of inline cache");
   assert(destination == (address)-1 || destination == entry,
          "b) MT-unsafe modification of inline cache");
--- a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.cpp	Wed May 15 13:54:43 2019 +0530
@@ -30,6 +30,7 @@
 #include "interpreter/interp_masm.hpp"
 #include "memory/universe.hpp"
 #include "runtime/jniHandles.hpp"
+#include "runtime/sharedRuntime.hpp"
 #include "runtime/thread.hpp"
 
 #define __ masm->
@@ -344,3 +345,33 @@
   __ bind(continuation);
 #endif
 }
+
+void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) {
+  BarrierSetNMethod* bs = BarrierSet::barrier_set()->barrier_set_nmethod();
+  if (bs == NULL) {
+    return;
+  }
+
+  Label bad_call;
+  __ cmpptr(rbx, 0); // rbx contains the incoming method for c2i adapters.
+  __ jcc(Assembler::equal, bad_call);
+
+  // Pointer chase to the method holder to find out if the method is concurrently unloading.
+  Label method_live;
+  __ load_method_holder_cld(rscratch1, rbx);
+
+  // Is it a strong CLD?
+  __ movl(rscratch2, Address(rscratch1, ClassLoaderData::keep_alive_offset()));
+  __ cmpptr(rscratch2, 0);
+  __ jcc(Assembler::greater, method_live);
+
+  // Is it a weak but alive CLD?
+  __ movptr(rscratch1, Address(rscratch1, ClassLoaderData::holder_offset()));
+  __ resolve_weak_handle(rscratch1, rscratch2);
+  __ cmpptr(rscratch1, 0);
+  __ jcc(Assembler::notEqual, method_live);
+
+  __ bind(bad_call);
+  __ jump(RuntimeAddress(SharedRuntime::get_handle_wrong_method_stub()));
+  __ bind(method_live);
+}
--- a/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/x86/gc/shared/barrierSetAssembler_x86.hpp	Wed May 15 13:54:43 2019 +0530
@@ -85,6 +85,7 @@
   virtual void barrier_stubs_init() {}
 
   virtual void nmethod_entry_barrier(MacroAssembler* masm);
+  virtual void c2i_entry_barrier(MacroAssembler* masm);
 };
 
 #endif // CPU_X86_GC_SHARED_BARRIERSETASSEMBLER_X86_HPP
--- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp	Wed May 15 13:54:43 2019 +0530
@@ -5175,6 +5175,23 @@
                  result, Address(result, 0), tmp, /*tmp_thread*/noreg);
 }
 
+// ((WeakHandle)result).resolve();
+void MacroAssembler::resolve_weak_handle(Register rresult, Register rtmp) {
+  assert_different_registers(rresult, rtmp);
+  Label resolved;
+
+  // A null weak handle resolves to null.
+  cmpptr(rresult, 0);
+  jcc(Assembler::equal, resolved);
+
+  // Only 64 bit platforms support GCs that require a tmp register
+  // Only IN_HEAP loads require a thread_tmp register
+  // WeakHandle::resolve is an indirection like jweak.
+  access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF,
+                 rresult, Address(rresult, 0), rtmp, /*tmp_thread*/noreg);
+  bind(resolved);
+}
+
 void MacroAssembler::load_mirror(Register mirror, Register method, Register tmp) {
   // get mirror
   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
@@ -5185,6 +5202,13 @@
   resolve_oop_handle(mirror, tmp);
 }
 
+void MacroAssembler::load_method_holder_cld(Register rresult, Register rmethod) {
+  movptr(rresult, Address(rmethod, Method::const_offset()));
+  movptr(rresult, Address(rresult, ConstMethod::constants_offset()));
+  movptr(rresult, Address(rresult, ConstantPool::pool_holder_offset_in_bytes()));
+  movptr(rresult, Address(rresult, InstanceKlass::class_loader_data_offset()));
+}
+
 void MacroAssembler::load_klass(Register dst, Register src) {
 #ifdef _LP64
   if (UseCompressedClassPointers) {
--- a/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/x86/macroAssembler_x86.hpp	Wed May 15 13:54:43 2019 +0530
@@ -313,7 +313,9 @@
   void testbool(Register dst);
 
   void resolve_oop_handle(Register result, Register tmp = rscratch2);
+  void resolve_weak_handle(Register result, Register tmp);
   void load_mirror(Register mirror, Register method, Register tmp = rscratch2);
+  void load_method_holder_cld(Register rresult, Register rmethod);
 
   // oop manipulations
   void load_klass(Register dst, Register src);
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_32.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1593,7 +1593,6 @@
       out_sig_bt[argc++] = in_sig_bt[i];
     }
   } else {
-    Thread* THREAD = Thread::current();
     in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args);
     SignatureStream ss(method->signature());
     for (int i = 0; i < total_in_args ; i++ ) {
@@ -1601,7 +1600,7 @@
         // Arrays are passed as int, elem* pair
         out_sig_bt[argc++] = T_INT;
         out_sig_bt[argc++] = T_ADDRESS;
-        Symbol* atype = ss.as_symbol(CHECK_NULL);
+        Symbol* atype = ss.as_symbol();
         const char* at = atype->as_C_string();
         if (strlen(at) == 2) {
           assert(at[0] == '[', "must be");
--- a/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/x86/sharedRuntime_x86_64.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -971,6 +971,9 @@
 
   address c2i_entry = __ pc();
 
+  BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
+  bs->c2i_entry_barrier(masm);
+
   gen_c2i_adapter(masm, total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
 
   __ flush();
@@ -1968,7 +1971,6 @@
       out_sig_bt[argc++] = in_sig_bt[i];
     }
   } else {
-    Thread* THREAD = Thread::current();
     in_elem_bt = NEW_RESOURCE_ARRAY(BasicType, total_in_args);
     SignatureStream ss(method->signature());
     for (int i = 0; i < total_in_args ; i++ ) {
@@ -1976,7 +1978,7 @@
         // Arrays are passed as int, elem* pair
         out_sig_bt[argc++] = T_INT;
         out_sig_bt[argc++] = T_ADDRESS;
-        Symbol* atype = ss.as_symbol(CHECK_NULL);
+        Symbol* atype = ss.as_symbol();
         const char* at = atype->as_C_string();
         if (strlen(at) == 2) {
           assert(at[0] == '[', "must be");
--- a/src/hotspot/cpu/x86/vm_version_x86.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/cpu/x86/vm_version_x86.cpp	Wed May 15 13:54:43 2019 +0530
@@ -32,6 +32,7 @@
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
 #include "runtime/stubCodeGenerator.hpp"
+#include "utilities/virtualizationSupport.hpp"
 #include "vm_version_x86.hpp"
 
 
@@ -1581,6 +1582,7 @@
     st->print_cr("KVM virtualization detected");
   } else if (vrt == VMWare) {
     st->print_cr("VMWare virtualization detected");
+    VirtualizationSupport::print_virtualization_info(st);
   } else if (vrt == HyperV) {
     st->print_cr("HyperV virtualization detected");
   }
@@ -1684,6 +1686,8 @@
 
     if (strncmp("VMwareVMware", signature, 12) == 0) {
       Abstract_VM_Version::_detected_virtualization = VMWare;
+      // check for extended metrics from guestlib
+      VirtualizationSupport::initialize();
     }
 
     if (strncmp("Microsoft Hv", signature, 12) == 0) {
--- a/src/hotspot/os/aix/os_aix.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/os/aix/os_aix.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2018 SAP SE. All rights reserved.
+ * Copyright (c) 2012, 2019 SAP SE. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1389,12 +1389,15 @@
 
   os::Posix::print_rlimit_info(st);
 
+  // _SC_THREAD_THREADS_MAX is the maximum number of threads within a process.
+  long tmax = sysconf(_SC_THREAD_THREADS_MAX);
+  st->print_cr("maximum #threads within a process:%ld", tmax);
+
   // load average
   st->print("load average:");
   double loadavg[3] = {-1.L, -1.L, -1.L};
   os::loadavg(loadavg, 3);
-  st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
-  st->cr();
+  st->print_cr("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
 
   // print wpar info
   libperfstat::wparinfo_t wi;
--- a/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/os/linux/gc/z/zNUMA_linux.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,7 +39,7 @@
 #endif
 
 static int z_get_mempolicy(uint32_t* mode, const unsigned long *nmask, unsigned long maxnode, uintptr_t addr, int flags) {
-  return syscall(__NR_get_mempolicy, mode, nmask, maxnode, addr, flags);
+  return syscall(SYS_get_mempolicy, mode, nmask, maxnode, addr, flags);
 }
 
 void ZNUMA::initialize_platform() {
--- a/src/hotspot/os/windows/os_windows.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/os/windows/os_windows.cpp	Wed May 15 13:54:43 2019 +0530
@@ -201,7 +201,7 @@
     char *home_path;
     char *dll_path;
     char *pslash;
-    char *bin = "\\bin";
+    const char *bin = "\\bin";
     char home_dir[MAX_PATH + 1];
     char *alt_home_dir = ::getenv("_ALT_JAVA_HOME_DIR");
 
@@ -2185,7 +2185,7 @@
 
 #define def_excpt(val) { #val, (val) }
 
-static const struct { char* name; uint number; } exceptlabels[] = {
+static const struct { const char* name; uint number; } exceptlabels[] = {
     def_excpt(EXCEPTION_ACCESS_VIOLATION),
     def_excpt(EXCEPTION_DATATYPE_MISALIGNMENT),
     def_excpt(EXCEPTION_BREAKPOINT),
@@ -5335,7 +5335,7 @@
   DWORD exit_code;
 
   char * cmd_string;
-  char * cmd_prefix = "cmd /C ";
+  const char * cmd_prefix = "cmd /C ";
   size_t len = strlen(cmd) + strlen(cmd_prefix) + 1;
   cmd_string = NEW_C_HEAP_ARRAY_RETURN_NULL(char, len, mtInternal);
   if (cmd_string == NULL) {
@@ -5674,8 +5674,8 @@
 */
 int os::get_signal_number(const char* name) {
   static const struct {
-    char* name;
-    int   number;
+    const char* name;
+    int         number;
   } siglabels [] =
     // derived from version 6.0 VC98/include/signal.h
   {"ABRT",      SIGABRT,        // abnormal termination triggered by abort cl
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.cpp	Wed May 15 13:54:43 2019 +0530
@@ -26,8 +26,10 @@
 #include "gc/z/zBackingFile_linux_x86.hpp"
 #include "gc/z/zBackingPath_linux_x86.hpp"
 #include "gc/z/zErrno.hpp"
+#include "gc/z/zGlobals.hpp"
 #include "gc/z/zLargePages.inline.hpp"
 #include "logging/log.hpp"
+#include "runtime/init.hpp"
 #include "runtime/os.hpp"
 #include "utilities/align.hpp"
 #include "utilities/debug.hpp"
@@ -36,9 +38,54 @@
 #include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/statfs.h>
+#include <sys/syscall.h>
 #include <sys/types.h>
 #include <unistd.h>
 
+//
+// Support for building on older Linux systems
+//
+
+// System calls
+#ifndef SYS_fallocate
+#define SYS_fallocate                    285
+#endif
+#ifndef SYS_memfd_create
+#define SYS_memfd_create                 319
+#endif
+
+// memfd_create(2) flags
+#ifndef MFD_CLOEXEC
+#define MFD_CLOEXEC                      0x0001U
+#endif
+#ifndef MFD_HUGETLB
+#define MFD_HUGETLB                      0x0004U
+#endif
+
+// open(2) flags
+#ifndef O_CLOEXEC
+#define O_CLOEXEC                        02000000
+#endif
+#ifndef O_TMPFILE
+#define O_TMPFILE                        (020000000 | O_DIRECTORY)
+#endif
+
+// fallocate(2) flags
+#ifndef FALLOC_FL_KEEP_SIZE
+#define FALLOC_FL_KEEP_SIZE              0x01
+#endif
+#ifndef FALLOC_FL_PUNCH_HOLE
+#define FALLOC_FL_PUNCH_HOLE             0x02
+#endif
+
+// Filesystem types, see statfs(2)
+#ifndef TMPFS_MAGIC
+#define TMPFS_MAGIC                      0x01021994
+#endif
+#ifndef HUGETLBFS_MAGIC
+#define HUGETLBFS_MAGIC                  0x958458f6
+#endif
+
 // Filesystem names
 #define ZFILESYSTEM_TMPFS                "tmpfs"
 #define ZFILESYSTEM_HUGETLBFS            "hugetlbfs"
@@ -49,31 +96,6 @@
 // Java heap filename
 #define ZFILENAME_HEAP                   "java_heap"
 
-// Support for building on older Linux systems
-#ifndef __NR_memfd_create
-#define __NR_memfd_create                319
-#endif
-#ifndef MFD_CLOEXEC
-#define MFD_CLOEXEC                      0x0001U
-#endif
-#ifndef MFD_HUGETLB
-#define MFD_HUGETLB                      0x0004U
-#endif
-#ifndef O_CLOEXEC
-#define O_CLOEXEC                        02000000
-#endif
-#ifndef O_TMPFILE
-#define O_TMPFILE                        (020000000 | O_DIRECTORY)
-#endif
-
-// Filesystem types, see statfs(2)
-#ifndef TMPFS_MAGIC
-#define TMPFS_MAGIC                      0x01021994
-#endif
-#ifndef HUGETLBFS_MAGIC
-#define HUGETLBFS_MAGIC                  0x958458f6
-#endif
-
 // Preferred tmpfs mount points, ordered by priority
 static const char* z_preferred_tmpfs_mountpoints[] = {
   "/dev/shm",
@@ -88,15 +110,22 @@
   NULL
 };
 
-static int z_memfd_create(const char *name, unsigned int flags) {
-  return syscall(__NR_memfd_create, name, flags);
+static int z_fallocate_hugetlbfs_attempts = 3;
+static bool z_fallocate_supported = true;
+
+static int z_fallocate(int fd, int mode, size_t offset, size_t length) {
+  return syscall(SYS_fallocate, fd, mode, offset, length);
 }
 
-bool ZBackingFile::_hugetlbfs_mmap_retry = true;
+static int z_memfd_create(const char *name, unsigned int flags) {
+  return syscall(SYS_memfd_create, name, flags);
+}
 
 ZBackingFile::ZBackingFile() :
     _fd(-1),
+    _size(0),
     _filesystem(0),
+    _block_size(0),
     _available(0),
     _initialized(false) {
 
@@ -107,46 +136,53 @@
   }
 
   // Get filesystem statistics
-  struct statfs statfs_buf;
-  if (fstatfs(_fd, &statfs_buf) == -1) {
+  struct statfs buf;
+  if (fstatfs(_fd, &buf) == -1) {
     ZErrno err;
-    log_error(gc, init)("Failed to determine filesystem type for backing file (%s)",
-                        err.to_string());
+    log_error(gc)("Failed to determine filesystem type for backing file (%s)", err.to_string());
     return;
   }
 
-  _filesystem = statfs_buf.f_type;
-  _available = statfs_buf.f_bavail * statfs_buf.f_bsize;
+  _filesystem = buf.f_type;
+  _block_size = buf.f_bsize;
+  _available = buf.f_bavail * _block_size;
 
   // Make sure we're on a supported filesystem
   if (!is_tmpfs() && !is_hugetlbfs()) {
-    log_error(gc, init)("Backing file must be located on a %s or a %s filesystem",
-                        ZFILESYSTEM_TMPFS, ZFILESYSTEM_HUGETLBFS);
+    log_error(gc)("Backing file must be located on a %s or a %s filesystem",
+                  ZFILESYSTEM_TMPFS, ZFILESYSTEM_HUGETLBFS);
     return;
   }
 
   // Make sure the filesystem type matches requested large page type
   if (ZLargePages::is_transparent() && !is_tmpfs()) {
-    log_error(gc, init)("-XX:+UseTransparentHugePages can only be enable when using a %s filesystem",
-                        ZFILESYSTEM_TMPFS);
+    log_error(gc)("-XX:+UseTransparentHugePages can only be enable when using a %s filesystem",
+                  ZFILESYSTEM_TMPFS);
     return;
   }
 
   if (ZLargePages::is_transparent() && !tmpfs_supports_transparent_huge_pages()) {
-    log_error(gc, init)("-XX:+UseTransparentHugePages on a %s filesystem not supported by kernel",
-                        ZFILESYSTEM_TMPFS);
+    log_error(gc)("-XX:+UseTransparentHugePages on a %s filesystem not supported by kernel",
+                  ZFILESYSTEM_TMPFS);
     return;
   }
 
   if (ZLargePages::is_explicit() && !is_hugetlbfs()) {
-    log_error(gc, init)("-XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled when using a %s filesystem",
-                        ZFILESYSTEM_HUGETLBFS);
+    log_error(gc)("-XX:+UseLargePages (without -XX:+UseTransparentHugePages) can only be enabled "
+                  "when using a %s filesystem", ZFILESYSTEM_HUGETLBFS);
     return;
   }
 
   if (!ZLargePages::is_explicit() && is_hugetlbfs()) {
-    log_error(gc, init)("-XX:+UseLargePages must be enabled when using a %s filesystem",
-                        ZFILESYSTEM_HUGETLBFS);
+    log_error(gc)("-XX:+UseLargePages must be enabled when using a %s filesystem",
+                  ZFILESYSTEM_HUGETLBFS);
+    return;
+  }
+
+  const size_t expected_block_size = is_tmpfs() ? os::vm_page_size() : os::large_page_size();
+  if (expected_block_size != _block_size) {
+    log_error(gc)("%s filesystem has unexpected block size " SIZE_FORMAT " (expected " SIZE_FORMAT ")",
+                  is_tmpfs() ? ZFILESYSTEM_TMPFS : ZFILESYSTEM_HUGETLBFS, _block_size, expected_block_size);
     return;
   }
 
@@ -165,7 +201,7 @@
   if (fd == -1) {
     ZErrno err;
     log_debug(gc, init)("Failed to create memfd file (%s)",
-                        ((UseLargePages && err == EINVAL) ? "Hugepages not supported" : err.to_string()));
+                        ((ZLargePages::is_explicit() && err == EINVAL) ? "Hugepages not supported" : err.to_string()));
     return -1;
   }
 
@@ -185,7 +221,7 @@
   // Find mountpoint
   ZBackingPath path(filesystem, preferred_mountpoints);
   if (path.get() == NULL) {
-    log_error(gc, init)("Use -XX:ZPath to specify the path to a %s filesystem", filesystem);
+    log_error(gc)("Use -XX:ZPath to specify the path to a %s filesystem", filesystem);
     return -1;
   }
 
@@ -201,7 +237,7 @@
     struct stat stat_buf;
     if (fstat(fd_anon, &stat_buf) == -1) {
       ZErrno err;
-      log_error(gc, init)("Failed to determine inode number for anonymous file (%s)", err.to_string());
+      log_error(gc)("Failed to determine inode number for anonymous file (%s)", err.to_string());
       return -1;
     }
 
@@ -220,14 +256,14 @@
   const int fd = os::open(filename, O_CREAT|O_EXCL|O_RDWR|O_CLOEXEC, S_IRUSR|S_IWUSR);
   if (fd == -1) {
     ZErrno err;
-    log_error(gc, init)("Failed to create file %s (%s)", filename, err.to_string());
+    log_error(gc)("Failed to create file %s (%s)", filename, err.to_string());
     return -1;
   }
 
   // Unlink file
   if (unlink(filename) == -1) {
     ZErrno err;
-    log_error(gc, init)("Failed to unlink file %s (%s)", filename, err.to_string());
+    log_error(gc)("Failed to unlink file %s (%s)", filename, err.to_string());
     return -1;
   }
 
@@ -262,6 +298,10 @@
   return _fd;
 }
 
+size_t ZBackingFile::size() const {
+  return _size;
+}
+
 size_t ZBackingFile::available() const {
   return _available;
 }
@@ -280,147 +320,271 @@
   return access(ZFILENAME_SHMEM_ENABLED, R_OK) == 0;
 }
 
-bool ZBackingFile::try_split_and_expand_tmpfs(size_t offset, size_t length, size_t alignment) const {
-  // Try first smaller part.
-  const size_t offset0 = offset;
-  const size_t length0 = align_up(length / 2, alignment);
-  if (!try_expand_tmpfs(offset0, length0, alignment)) {
-    return false;
+ZErrno ZBackingFile::fallocate_compat_ftruncate(size_t size) const {
+  while (ftruncate(_fd, size) == -1) {
+    if (errno != EINTR) {
+      // Failed
+      return errno;
+    }
   }
 
-  // Try second smaller part.
-  const size_t offset1 = offset0 + length0;
-  const size_t length1 = length - length0;
-  if (!try_expand_tmpfs(offset1, length1, alignment)) {
-    return false;
-  }
-
-  return true;
+  // Success
+  return 0;
 }
 
-bool ZBackingFile::try_expand_tmpfs(size_t offset, size_t length, size_t alignment) const {
-  assert(length > 0, "Invalid length");
-  assert(is_aligned(length, alignment), "Invalid length");
-
-  ZErrno err = posix_fallocate(_fd, offset, length);
-
-  if (err == EINTR && length > alignment) {
-    // Calling posix_fallocate() with a large length can take a long
-    // time to complete. When running profilers, such as VTune, this
-    // syscall will be constantly interrupted by signals. Expanding
-    // the file in smaller steps avoids this problem.
-    return try_split_and_expand_tmpfs(offset, length, alignment);
+ZErrno ZBackingFile::fallocate_compat_mmap(size_t offset, size_t length, bool touch) const {
+  // On hugetlbfs, mapping a file segment will fail immediately, without
+  // the need to touch the mapped pages first, if there aren't enough huge
+  // pages available to back the mapping.
+  void* const addr = mmap(0, length, PROT_READ|PROT_WRITE, MAP_SHARED, _fd, offset);
+  if (addr == MAP_FAILED) {
+    // Failed
+    return errno;
   }
 
-  if (err) {
-    log_error(gc)("Failed to allocate backing file (%s)", err.to_string());
-    return false;
+  // Once mapped, the huge pages are only reserved. We need to touch them
+  // to associate them with the file segment. Note that we can not punch
+  // hole in file segments which only have reserved pages.
+  if (touch) {
+    char* const start = (char*)addr;
+    char* const end = start + length;
+    os::pretouch_memory(start, end, _block_size);
+  }
+
+  // Unmap again. From now on, the huge pages that were mapped are allocated
+  // to this file. There's no risk in getting SIGBUS when touching them.
+  if (munmap(addr, length) == -1) {
+    // Failed
+    return errno;
   }
 
-  return true;
-}
-
-bool ZBackingFile::try_expand_tmpfs(size_t offset, size_t length) const {
-  assert(is_tmpfs(), "Wrong filesystem");
-  return try_expand_tmpfs(offset, length, os::vm_page_size());
+  // Success
+  return 0;
 }
 
-bool ZBackingFile::try_expand_hugetlbfs(size_t offset, size_t length) const {
-  assert(is_hugetlbfs(), "Wrong filesystem");
+ZErrno ZBackingFile::fallocate_compat_pwrite(size_t offset, size_t length) const {
+  uint8_t data = 0;
+
+  // Allocate backing memory by writing to each block
+  for (size_t pos = offset; pos < offset + length; pos += _block_size) {
+    if (pwrite(_fd, &data, sizeof(data), pos) == -1) {
+      // Failed
+      return errno;
+    }
+  }
 
-  // Prior to kernel 4.3, hugetlbfs did not support posix_fallocate().
-  // Instead of posix_fallocate() we can use a well-known workaround,
-  // which involves truncating the file to requested size and then try
-  // to map it to verify that there are enough huge pages available to
-  // back it.
-  while (ftruncate(_fd, offset + length) == -1) {
-    ZErrno err;
-    if (err != EINTR) {
-      log_error(gc)("Failed to truncate backing file (%s)", err.to_string());
-      return false;
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::fallocate_fill_hole_compat(size_t offset, size_t length) {
+  // fallocate(2) is only supported by tmpfs since Linux 3.5, and by hugetlbfs
+  // since Linux 4.3. When fallocate(2) is not supported we emulate it using
+  // ftruncate/pwrite (for tmpfs) or ftruncate/mmap/munmap (for hugetlbfs).
+
+  const size_t end = offset + length;
+  if (end > _size) {
+    // Increase file size
+    const ZErrno err = fallocate_compat_ftruncate(end);
+    if (err) {
+      // Failed
+      return err;
     }
   }
 
-  // If we fail mapping during initialization, i.e. when we are pre-mapping
-  // the heap, then we wait and retry a few times before giving up. Otherwise
-  // there is a risk that running JVMs back-to-back will fail, since there
-  // is a delay between process termination and the huge pages owned by that
-  // process being returned to the huge page pool and made available for new
-  // allocations.
-  void* addr = MAP_FAILED;
-  const int max_attempts = 5;
-  for (int attempt = 1; attempt <= max_attempts; attempt++) {
-    addr = mmap(0, length, PROT_READ|PROT_WRITE, MAP_SHARED, _fd, offset);
-    if (addr != MAP_FAILED || !_hugetlbfs_mmap_retry) {
-      // Mapping was successful or mmap retry is disabled
-      break;
+  // Allocate backing memory
+  const ZErrno err = is_hugetlbfs() ? fallocate_compat_mmap(offset, length, false /* touch */)
+                                    : fallocate_compat_pwrite(offset, length);
+  if (err) {
+    if (end > _size) {
+      // Restore file size
+      fallocate_compat_ftruncate(_size);
     }
 
-    ZErrno err;
-    log_debug(gc)("Failed to map backing file (%s), attempt %d of %d",
-                  err.to_string(), attempt, max_attempts);
+    // Failed
+    return err;
+  }
+
+  if (end > _size) {
+    // Record new file size
+    _size = end;
+  }
+
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::fallocate_fill_hole_syscall(size_t offset, size_t length) {
+  const int mode = 0; // Allocate
+  const int res = z_fallocate(_fd, mode, offset, length);
+  if (res == -1) {
+    // Failed
+    return errno;
+  }
+
+  const size_t end = offset + length;
+  if (end > _size) {
+    // Record new file size
+    _size = end;
+  }
+
+  // Success
+  return 0;
+}
 
-    // Wait and retry in one second, in the hope that
-    // huge pages will be available by then.
-    sleep(1);
+ZErrno ZBackingFile::fallocate_fill_hole(size_t offset, size_t length) {
+  // Using compat mode is more efficient when allocating space on hugetlbfs.
+  // Note that allocating huge pages this way will only reserve them, and not
+  // associate them with segments of the file. We must guarantee that we at
+  // some point touch these segments, otherwise we can not punch hole in them.
+  if (z_fallocate_supported && !is_hugetlbfs()) {
+     const ZErrno err = fallocate_fill_hole_syscall(offset, length);
+     if (!err) {
+       // Success
+       return 0;
+     }
+
+     if (err != ENOSYS && err != EOPNOTSUPP) {
+       // Failed
+       return err;
+     }
+
+     // Not supported
+     log_debug(gc)("Falling back to fallocate() compatibility mode");
+     z_fallocate_supported = false;
+  }
+
+  return fallocate_fill_hole_compat(offset, length);
+}
+
+ZErrno ZBackingFile::fallocate_punch_hole(size_t offset, size_t length) {
+  if (is_hugetlbfs()) {
+    // We can only punch hole in pages that have been touched. Non-touched
+    // pages are only reserved, and not associated with any specific file
+    // segment. We don't know which pages have been previously touched, so
+    // we always touch them here to guarantee that we can punch hole.
+    const ZErrno err = fallocate_compat_mmap(offset, length, true /* touch */);
+    if (err) {
+      // Failed
+      return err;
+    }
   }
 
-  // Disable mmap retry from now on
-  if (_hugetlbfs_mmap_retry) {
-    _hugetlbfs_mmap_retry = false;
+  const int mode = FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE;
+  if (z_fallocate(_fd, mode, offset, length) == -1) {
+    // Failed
+    return errno;
+  }
+
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::split_and_fallocate(bool punch_hole, size_t offset, size_t length) {
+  // Try first half
+  const size_t offset0 = offset;
+  const size_t length0 = align_up(length / 2, _block_size);
+  const ZErrno err0 = fallocate(punch_hole, offset0, length0);
+  if (err0) {
+    return err0;
+  }
+
+  // Try second half
+  const size_t offset1 = offset0 + length0;
+  const size_t length1 = length - length0;
+  const ZErrno err1 = fallocate(punch_hole, offset1, length1);
+  if (err1) {
+    return err1;
   }
 
-  if (addr == MAP_FAILED) {
-    // Not enough huge pages left
-    ZErrno err;
-    log_error(gc)("Failed to map backing file (%s)", err.to_string());
+  // Success
+  return 0;
+}
+
+ZErrno ZBackingFile::fallocate(bool punch_hole, size_t offset, size_t length) {
+  assert(is_aligned(offset, _block_size), "Invalid offset");
+  assert(is_aligned(length, _block_size), "Invalid length");
+
+  const ZErrno err = punch_hole ? fallocate_punch_hole(offset, length) : fallocate_fill_hole(offset, length);
+  if (err == EINTR && length > _block_size) {
+    // Calling fallocate(2) with a large length can take a long time to
+    // complete. When running profilers, such as VTune, this syscall will
+    // be constantly interrupted by signals. Expanding the file in smaller
+    // steps avoids this problem.
+    return split_and_fallocate(punch_hole, offset, length);
+  }
+
+  return err;
+}
+
+bool ZBackingFile::commit_inner(size_t offset, size_t length) {
+  log_trace(gc, heap)("Committing memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
+                      offset / M, (offset + length) / M, length / M);
+
+retry:
+  const ZErrno err = fallocate(false /* punch_hole */, offset, length);
+  if (err) {
+    if (err == ENOSPC && !is_init_completed() && is_hugetlbfs() && z_fallocate_hugetlbfs_attempts-- > 0) {
+      // If we fail to allocate during initialization, due to lack of space on
+      // the hugetlbfs filesystem, then we wait and retry a few times before
+      // giving up. Otherwise there is a risk that running JVMs back-to-back
+      // will fail, since there is a delay between process termination and the
+      // huge pages owned by that process being returned to the huge page pool
+      // and made available for new allocations.
+      log_debug(gc, init)("Failed to commit memory (%s), retrying", err.to_string());
+
+      // Wait and retry in one second, in the hope that huge pages will be
+      // available by then.
+      sleep(1);
+      goto retry;
+    }
+
+    // Failed
+    log_error(gc)("Failed to commit memory (%s)", err.to_string());
     return false;
   }
 
-  // Successful mapping, unmap again. From now on the pages we mapped
-  // will be reserved for this file.
-  if (munmap(addr, length) == -1) {
-    ZErrno err;
-    log_error(gc)("Failed to unmap backing file (%s)", err.to_string());
-    return false;
-  }
-
+  // Success
   return true;
 }
 
-bool ZBackingFile::try_expand_tmpfs_or_hugetlbfs(size_t offset, size_t length, size_t alignment) const {
-  assert(is_aligned(offset, alignment), "Invalid offset");
-  assert(is_aligned(length, alignment), "Invalid length");
+size_t ZBackingFile::commit(size_t offset, size_t length) {
+  // Try to commit the whole region
+  if (commit_inner(offset, length)) {
+    // Success
+    return length;
+  }
 
-  log_debug(gc)("Expanding heap from " SIZE_FORMAT "M to " SIZE_FORMAT "M", offset / M, (offset + length) / M);
-
-  return is_hugetlbfs() ? try_expand_hugetlbfs(offset, length) : try_expand_tmpfs(offset, length);
-}
-
-size_t ZBackingFile::try_expand(size_t offset, size_t length, size_t alignment) const {
+  // Failed, try to commit as much as possible
   size_t start = offset;
   size_t end = offset + length;
 
-  // Try to expand
-  if (try_expand_tmpfs_or_hugetlbfs(start, length, alignment)) {
-    // Success
-    return end;
-  }
-
-  // Failed, try to expand as much as possible
   for (;;) {
-    length = align_down((end - start) / 2, alignment);
-    if (length < alignment) {
-      // Done, don't expand more
-      return start;
+    length = align_down((end - start) / 2, ZGranuleSize);
+    if (length < ZGranuleSize) {
+      // Done, don't commit more
+      return start - offset;
     }
 
-    if (try_expand_tmpfs_or_hugetlbfs(start, length, alignment)) {
-      // Success, try expand more
+    if (commit_inner(start, length)) {
+      // Success, try commit more
       start += length;
     } else {
-      // Failed, try expand less
+      // Failed, try commit less
       end -= length;
     }
   }
 }
+
+size_t ZBackingFile::uncommit(size_t offset, size_t length) {
+  log_trace(gc, heap)("Uncommitting memory: " SIZE_FORMAT "M-" SIZE_FORMAT "M (" SIZE_FORMAT "M)",
+                      offset / M, (offset + length) / M, length / M);
+
+  const ZErrno err = fallocate(true /* punch_hole */, offset, length);
+  if (err) {
+    log_error(gc)("Failed to uncommit memory (%s)", err.to_string());
+    return 0;
+  }
+
+  return length;
+}
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zBackingFile_linux_x86.hpp	Wed May 15 13:54:43 2019 +0530
@@ -26,12 +26,14 @@
 
 #include "memory/allocation.hpp"
 
+class ZErrno;
+
 class ZBackingFile {
 private:
-  static bool _hugetlbfs_mmap_retry;
-
   int      _fd;
+  size_t   _size;
   uint64_t _filesystem;
+  size_t   _block_size;
   size_t   _available;
   bool     _initialized;
 
@@ -43,11 +45,17 @@
   bool is_hugetlbfs() const;
   bool tmpfs_supports_transparent_huge_pages() const;
 
-  bool try_split_and_expand_tmpfs(size_t offset, size_t length, size_t alignment) const;
-  bool try_expand_tmpfs(size_t offset, size_t length, size_t alignment) const;
-  bool try_expand_tmpfs(size_t offset, size_t length) const;
-  bool try_expand_hugetlbfs(size_t offset, size_t length) const;
-  bool try_expand_tmpfs_or_hugetlbfs(size_t offset, size_t length, size_t alignment) const;
+  ZErrno fallocate_compat_ftruncate(size_t size) const;
+  ZErrno fallocate_compat_mmap(size_t offset, size_t length, bool reserve_only) const;
+  ZErrno fallocate_compat_pwrite(size_t offset, size_t length) const;
+  ZErrno fallocate_fill_hole_compat(size_t offset, size_t length);
+  ZErrno fallocate_fill_hole_syscall(size_t offset, size_t length);
+  ZErrno fallocate_fill_hole(size_t offset, size_t length);
+  ZErrno fallocate_punch_hole(size_t offset, size_t length);
+  ZErrno split_and_fallocate(bool punch_hole, size_t offset, size_t length);
+  ZErrno fallocate(bool punch_hole, size_t offset, size_t length);
+
+  bool commit_inner(size_t offset, size_t length);
 
 public:
   ZBackingFile();
@@ -55,9 +63,11 @@
   bool is_initialized() const;
 
   int fd() const;
+  size_t size() const;
   size_t available() const;
 
-  size_t try_expand(size_t offset, size_t length, size_t alignment) const;
+  size_t commit(size_t offset, size_t length);
+  size_t uncommit(size_t offset, size_t length);
 };
 
 #endif // OS_CPU_LINUX_X86_GC_Z_ZBACKINGFILE_LINUX_X86_HPP
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zBackingPath_linux_x86.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zBackingPath_linux_x86.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,7 +72,7 @@
   FILE* fd = fopen(PROC_SELF_MOUNTINFO, "r");
   if (fd == NULL) {
     ZErrno err;
-    log_error(gc, init)("Failed to open %s: %s", PROC_SELF_MOUNTINFO, err.to_string());
+    log_error(gc)("Failed to open %s: %s", PROC_SELF_MOUNTINFO, err.to_string());
     return;
   }
 
@@ -113,10 +113,10 @@
   }
 
   // Preferred mount point not found
-  log_error(gc, init)("More than one %s filesystem found:", filesystem);
+  log_error(gc)("More than one %s filesystem found:", filesystem);
   ZArrayIterator<char*> iter2(mountpoints);
   for (char* mountpoint; iter2.next(&mountpoint);) {
-    log_error(gc, init)("  %s", mountpoint);
+    log_error(gc)("  %s", mountpoint);
   }
 
   return NULL;
@@ -130,7 +130,7 @@
 
   if (mountpoints.size() == 0) {
     // No mount point found
-    log_error(gc, init)("Failed to find an accessible %s filesystem", filesystem);
+    log_error(gc)("Failed to find an accessible %s filesystem", filesystem);
   } else if (mountpoints.size() == 1) {
     // One mount point found
     path = strdup(mountpoints.at(0));
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zPhysicalMemoryBacking_linux_x86.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zPhysicalMemoryBacking_linux_x86.cpp	Wed May 15 13:54:43 2019 +0530
@@ -32,6 +32,7 @@
 #include "gc/z/zPhysicalMemory.inline.hpp"
 #include "gc/z/zPhysicalMemoryBacking_linux_x86.hpp"
 #include "logging/log.hpp"
+#include "runtime/init.hpp"
 #include "runtime/os.hpp"
 #include "utilities/align.hpp"
 #include "utilities/debug.hpp"
@@ -40,7 +41,11 @@
 #include <sys/mman.h>
 #include <sys/types.h>
 
+//
 // Support for building on older Linux systems
+//
+
+// madvise(2) flags
 #ifndef MADV_HUGEPAGE
 #define MADV_HUGEPAGE                        14
 #endif
@@ -48,22 +53,37 @@
 // Proc file entry for max map mount
 #define ZFILENAME_PROC_MAX_MAP_COUNT         "/proc/sys/vm/max_map_count"
 
-ZPhysicalMemoryBacking::ZPhysicalMemoryBacking(size_t max_capacity) :
-    _manager(),
-    _file() {
+bool ZPhysicalMemoryBacking::is_initialized() const {
+  return _file.is_initialized();
+}
 
-  if (!_file.is_initialized()) {
+void ZPhysicalMemoryBacking::warn_available_space(size_t max) const {
+  // Note that the available space on a tmpfs or a hugetlbfs filesystem
+  // will be zero if no size limit was specified when it was mounted.
+  const size_t available = _file.available();
+  if (available == 0) {
+    // No size limit set, skip check
+    log_info(gc, init)("Available space on backing filesystem: N/A");
     return;
   }
 
-  // Check and warn if max map count is too low
-  check_max_map_count(max_capacity);
+  log_info(gc, init)("Available space on backing filesystem: " SIZE_FORMAT "M", available / M);
 
-  // Check and warn if available space on filesystem is too low
-  check_available_space_on_filesystem(max_capacity);
+  // Warn if the filesystem doesn't currently have enough space available to hold
+  // the max heap size. The max heap size will be capped if we later hit this limit
+  // when trying to expand the heap.
+  if (available < max) {
+    log_warning(gc)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****");
+    log_warning(gc)("Not enough space available on the backing filesystem to hold the current max Java heap");
+    log_warning(gc)("size (" SIZE_FORMAT "M). Please adjust the size of the backing filesystem accordingly "
+                    "(available", max / M);
+    log_warning(gc)("space is currently " SIZE_FORMAT "M). Continuing execution with the current filesystem "
+                    "size could", available / M);
+    log_warning(gc)("lead to a premature OutOfMemoryError being thrown, due to failure to map memory.");
+  }
 }
 
-void ZPhysicalMemoryBacking::check_max_map_count(size_t max_capacity) const {
+void ZPhysicalMemoryBacking::warn_max_map_count(size_t max) const {
   const char* const filename = ZFILENAME_PROC_MAX_MAP_COUNT;
   FILE* const file = fopen(filename, "r");
   if (file == NULL) {
@@ -86,62 +106,101 @@
   // However, ZGC tends to create the most mappings and dominate the total count.
   // In the worst cases, ZGC will map each granule three times, i.e. once per heap view.
   // We speculate that we need another 20% to allow for non-ZGC subsystems to map memory.
-  const size_t required_max_map_count = (max_capacity / ZGranuleSize) * 3 * 1.2;
+  const size_t required_max_map_count = (max / ZGranuleSize) * 3 * 1.2;
   if (actual_max_map_count < required_max_map_count) {
-    log_warning(gc, init)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****");
-    log_warning(gc, init)("The system limit on number of memory mappings per process might be too low "
-                          "for the given");
-    log_warning(gc, init)("max Java heap size (" SIZE_FORMAT "M). Please adjust %s to allow for at",
-                          max_capacity / M, filename);
-    log_warning(gc, init)("least " SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT "). Continuing "
-                          "execution with the current", required_max_map_count, actual_max_map_count);
-    log_warning(gc, init)("limit could lead to a fatal error, due to failure to map memory.");
+    log_warning(gc)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****");
+    log_warning(gc)("The system limit on number of memory mappings per process might be too low for the given");
+    log_warning(gc)("max Java heap size (" SIZE_FORMAT "M). Please adjust %s to allow for at",
+                    max / M, filename);
+    log_warning(gc)("least " SIZE_FORMAT " mappings (current limit is " SIZE_FORMAT "). Continuing execution "
+                    "with the current", required_max_map_count, actual_max_map_count);
+    log_warning(gc)("limit could lead to a fatal error, due to failure to map memory.");
   }
 }
 
-void ZPhysicalMemoryBacking::check_available_space_on_filesystem(size_t max_capacity) const {
-  // Note that the available space on a tmpfs or a hugetlbfs filesystem
-  // will be zero if no size limit was specified when it was mounted.
-  const size_t available = _file.available();
-  if (available == 0) {
-    // No size limit set, skip check
-    log_info(gc, init)("Available space on backing filesystem: N/A");
-    return;
+void ZPhysicalMemoryBacking::warn_commit_limits(size_t max) const {
+  // Warn if available space is too low
+  warn_available_space(max);
+
+  // Warn if max map count is too low
+  warn_max_map_count(max);
+}
+
+bool ZPhysicalMemoryBacking::supports_uncommit() {
+  assert(!is_init_completed(), "Invalid state");
+  assert(_file.size() >= ZGranuleSize, "Invalid size");
+
+  // Test if uncommit is supported by uncommitting and then re-committing a granule
+  return commit(uncommit(ZGranuleSize)) == ZGranuleSize;
+}
+
+size_t ZPhysicalMemoryBacking::commit(size_t size) {
+  size_t committed = 0;
+
+  // Fill holes in the backing file
+  while (committed < size) {
+    size_t allocated = 0;
+    const size_t remaining = size - committed;
+    const uintptr_t start = _uncommitted.alloc_from_front_at_most(remaining, &allocated);
+    if (start == UINTPTR_MAX) {
+      // No holes to commit
+      break;
+    }
+
+    // Try commit hole
+    const size_t filled = _file.commit(start, allocated);
+    if (filled > 0) {
+      // Successful or partialy successful
+      _committed.free(start, filled);
+      committed += filled;
+    }
+    if (filled < allocated) {
+      // Failed or partialy failed
+      _uncommitted.free(start + filled, allocated - filled);
+      return committed;
+    }
   }
 
-  log_info(gc, init)("Available space on backing filesystem: " SIZE_FORMAT "M",
-                     available / M);
+  // Expand backing file
+  if (committed < size) {
+    const size_t remaining = size - committed;
+    const uintptr_t start = _file.size();
+    const size_t expanded = _file.commit(start, remaining);
+    if (expanded > 0) {
+      // Successful or partialy successful
+      _committed.free(start, expanded);
+      committed += expanded;
+    }
+  }
 
-  // Warn if the filesystem doesn't currently have enough space available to hold
-  // the max heap size. The max heap size will be capped if we later hit this limit
-  // when trying to expand the heap.
-  if (available < max_capacity) {
-    log_warning(gc, init)("***** WARNING! INCORRECT SYSTEM CONFIGURATION DETECTED! *****");
-    log_warning(gc, init)("Not enough space available on the backing filesystem to hold the current "
-                          "max Java heap");
-    log_warning(gc, init)("size (" SIZE_FORMAT "M). Please adjust the size of the backing filesystem "
-                          "accordingly (available", max_capacity / M);
-    log_warning(gc, init)("space is currently " SIZE_FORMAT "M). Continuing execution with the current "
-                          "filesystem size could", available / M);
-    log_warning(gc, init)("lead to a premature OutOfMemoryError being thrown, due to failure to map "
-                          "memory.");
-  }
+  return committed;
 }
 
-bool ZPhysicalMemoryBacking::is_initialized() const {
-  return _file.is_initialized();
-}
+size_t ZPhysicalMemoryBacking::uncommit(size_t size) {
+  size_t uncommitted = 0;
+
+  // Punch holes in backing file
+  while (uncommitted < size) {
+    size_t allocated = 0;
+    const size_t remaining = size - uncommitted;
+    const uintptr_t start = _committed.alloc_from_back_at_most(remaining, &allocated);
+    assert(start != UINTPTR_MAX, "Allocation should never fail");
 
-size_t ZPhysicalMemoryBacking::try_expand(size_t old_capacity, size_t new_capacity) {
-  assert(old_capacity < new_capacity, "Invalid old/new capacity");
-
-  const size_t capacity = _file.try_expand(old_capacity, new_capacity - old_capacity, ZGranuleSize);
-  if (capacity > old_capacity) {
-    // Add expanded capacity to free list
-    _manager.free(old_capacity, capacity - old_capacity);
+    // Try punch hole
+    const size_t punched = _file.uncommit(start, allocated);
+    if (punched > 0) {
+      // Successful or partialy successful
+      _uncommitted.free(start, punched);
+      uncommitted += punched;
+    }
+    if (punched < allocated) {
+      // Failed or partialy failed
+      _committed.free(start + punched, allocated - punched);
+      return uncommitted;
+    }
   }
 
-  return capacity;
+  return uncommitted;
 }
 
 ZPhysicalMemory ZPhysicalMemoryBacking::alloc(size_t size) {
@@ -151,7 +210,7 @@
 
   // Allocate segments
   for (size_t allocated = 0; allocated < size; allocated += ZGranuleSize) {
-    const uintptr_t start = _manager.alloc_from_front(ZGranuleSize);
+    const uintptr_t start = _committed.alloc_from_front(ZGranuleSize);
     assert(start != UINTPTR_MAX, "Allocation should never fail");
     pmem.add_segment(ZPhysicalMemorySegment(start, ZGranuleSize));
   }
@@ -159,13 +218,13 @@
   return pmem;
 }
 
-void ZPhysicalMemoryBacking::free(ZPhysicalMemory pmem) {
+void ZPhysicalMemoryBacking::free(const ZPhysicalMemory& pmem) {
   const size_t nsegments = pmem.nsegments();
 
   // Free segments
   for (size_t i = 0; i < nsegments; i++) {
-    const ZPhysicalMemorySegment segment = pmem.segment(i);
-    _manager.free(segment.start(), segment.size());
+    const ZPhysicalMemorySegment& segment = pmem.segment(i);
+    _committed.free(segment.start(), segment.size());
   }
 }
 
@@ -178,10 +237,10 @@
   }
 }
 
-void ZPhysicalMemoryBacking::advise_view(uintptr_t addr, size_t size) const {
-  if (madvise((void*)addr, size, MADV_HUGEPAGE) == -1) {
+void ZPhysicalMemoryBacking::advise_view(uintptr_t addr, size_t size, int advice) const {
+  if (madvise((void*)addr, size, advice) == -1) {
     ZErrno err;
-    log_error(gc)("Failed to advise use of transparent huge pages (%s)", err.to_string());
+    log_error(gc)("Failed to advise on memory (advice %d, %s)", advice, err.to_string());
   }
 }
 
@@ -190,41 +249,42 @@
   os::pretouch_memory((void*)addr, (void*)(addr + size), page_size);
 }
 
-void ZPhysicalMemoryBacking::map_view(ZPhysicalMemory pmem, uintptr_t addr, bool pretouch) const {
+void ZPhysicalMemoryBacking::map_view(const ZPhysicalMemory& pmem, uintptr_t addr, bool pretouch) const {
   const size_t nsegments = pmem.nsegments();
+  size_t size = 0;
 
   // Map segments
   for (size_t i = 0; i < nsegments; i++) {
-    const ZPhysicalMemorySegment segment = pmem.segment(i);
-    const size_t size = segment.size();
-    const void* const res = mmap((void*)addr, size, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, _file.fd(), segment.start());
+    const ZPhysicalMemorySegment& segment = pmem.segment(i);
+    const uintptr_t segment_addr = addr + size;
+    const void* const res = mmap((void*)segment_addr, segment.size(), PROT_READ|PROT_WRITE, MAP_FIXED|MAP_SHARED, _file.fd(), segment.start());
     if (res == MAP_FAILED) {
       ZErrno err;
       map_failed(err);
     }
 
-    // Advise on use of transparent huge pages before touching it
-    if (ZLargePages::is_transparent()) {
-      advise_view(addr, size);
-    }
+    size += segment.size();
+  }
 
-    // NUMA interleave memory before touching it
-    ZNUMA::memory_interleave(addr, size);
+  // Advise on use of transparent huge pages before touching it
+  if (ZLargePages::is_transparent()) {
+    advise_view(addr, size, MADV_HUGEPAGE);
+  }
 
-    if (pretouch) {
-      pretouch_view(addr, size);
-    }
+  // NUMA interleave memory before touching it
+  ZNUMA::memory_interleave(addr, size);
 
-    addr += size;
+  // Pre-touch memory
+  if (pretouch) {
+    pretouch_view(addr, size);
   }
 }
 
-void ZPhysicalMemoryBacking::unmap_view(ZPhysicalMemory pmem, uintptr_t addr) const {
+void ZPhysicalMemoryBacking::unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const {
   // Note that we must keep the address space reservation intact and just detach
   // the backing memory. For this reason we map a new anonymous, non-accessible
   // and non-reserved page over the mapping instead of actually unmapping.
-  const size_t size = pmem.size();
-  const void* const res = mmap((void*)addr, size, PROT_NONE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
+  const void* const res = mmap((void*)addr, pmem.size(), PROT_NONE, MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE|MAP_NORESERVE, -1, 0);
   if (res == MAP_FAILED) {
     ZErrno err;
     map_failed(err);
@@ -232,11 +292,11 @@
 }
 
 uintptr_t ZPhysicalMemoryBacking::nmt_address(uintptr_t offset) const {
-  // From an NMT point of view we treat the first heap mapping (marked0) as committed
+  // From an NMT point of view we treat the first heap view (marked0) as committed
   return ZAddress::marked0(offset);
 }
 
-void ZPhysicalMemoryBacking::map(ZPhysicalMemory pmem, uintptr_t offset) const {
+void ZPhysicalMemoryBacking::map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
   if (ZVerifyViews) {
     // Map good view
     map_view(pmem, ZAddress::good(offset), AlwaysPreTouch);
@@ -248,7 +308,7 @@
   }
 }
 
-void ZPhysicalMemoryBacking::unmap(ZPhysicalMemory pmem, uintptr_t offset) const {
+void ZPhysicalMemoryBacking::unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
   if (ZVerifyViews) {
     // Unmap good view
     unmap_view(pmem, ZAddress::good(offset));
@@ -260,13 +320,13 @@
   }
 }
 
-void ZPhysicalMemoryBacking::debug_map(ZPhysicalMemory pmem, uintptr_t offset) const {
+void ZPhysicalMemoryBacking::debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
   // Map good view
   assert(ZVerifyViews, "Should be enabled");
   map_view(pmem, ZAddress::good(offset), false /* pretouch */);
 }
 
-void ZPhysicalMemoryBacking::debug_unmap(ZPhysicalMemory pmem, uintptr_t offset) const {
+void ZPhysicalMemoryBacking::debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
   // Unmap good view
   assert(ZVerifyViews, "Should be enabled");
   unmap_view(pmem, ZAddress::good(offset));
--- a/src/hotspot/os_cpu/linux_x86/gc/z/zPhysicalMemoryBacking_linux_x86.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/os_cpu/linux_x86/gc/z/zPhysicalMemoryBacking_linux_x86.hpp	Wed May 15 13:54:43 2019 +0530
@@ -32,35 +32,39 @@
 
 class ZPhysicalMemoryBacking {
 private:
-  ZMemoryManager _manager;
   ZBackingFile   _file;
+  ZMemoryManager _committed;
+  ZMemoryManager _uncommitted;
 
-  void check_max_map_count(size_t max_capacity) const;
-  void check_available_space_on_filesystem(size_t max_capacity) const;
+  void warn_available_space(size_t max) const;
+  void warn_max_map_count(size_t max) const;
+
   void map_failed(ZErrno err) const;
 
-  void advise_view(uintptr_t addr, size_t size) const;
+  void advise_view(uintptr_t addr, size_t size, int advice) const;
   void pretouch_view(uintptr_t addr, size_t size) const;
-  void map_view(ZPhysicalMemory pmem, uintptr_t addr, bool pretouch) const;
-  void unmap_view(ZPhysicalMemory pmem, uintptr_t addr) const;
+  void map_view(const ZPhysicalMemory& pmem, uintptr_t addr, bool pretouch) const;
+  void unmap_view(const ZPhysicalMemory& pmem, uintptr_t addr) const;
 
 public:
-  ZPhysicalMemoryBacking(size_t max_capacity);
-
   bool is_initialized() const;
 
-  size_t try_expand(size_t old_capacity, size_t new_capacity);
+  void warn_commit_limits(size_t max) const;
+  bool supports_uncommit();
+
+  size_t commit(size_t size);
+  size_t uncommit(size_t size);
 
   ZPhysicalMemory alloc(size_t size);
-  void free(ZPhysicalMemory pmem);
+  void free(const ZPhysicalMemory& pmem);
 
   uintptr_t nmt_address(uintptr_t offset) const;
 
-  void map(ZPhysicalMemory pmem, uintptr_t offset) const;
-  void unmap(ZPhysicalMemory pmem, uintptr_t offset) const;
+  void map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+  void unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
 
-  void debug_map(ZPhysicalMemory pmem, uintptr_t offset) const;
-  void debug_unmap(ZPhysicalMemory pmem, uintptr_t offset) const;
+  void debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+  void debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
 };
 
 #endif // OS_CPU_LINUX_X86_GC_Z_ZPHYSICALMEMORYBACKING_LINUX_X86_HPP
--- a/src/hotspot/share/aot/aotCompiledMethod.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/aot/aotCompiledMethod.cpp	Wed May 15 13:54:43 2019 +0530
@@ -278,7 +278,7 @@
           }
         }
       } else if (iter.type() == relocInfo::static_call_type ||
-                 iter.type() == relocInfo::opt_virtual_call_type){
+                 iter.type() == relocInfo::opt_virtual_call_type) {
         // Check Method* in AOT c2i stub for other calls.
         Metadata* meta = (Metadata*)nativeLoadGot_at(nativePltCall_at(iter.addr())->plt_c2i_stub())->data();
         if (meta != NULL) {
--- a/src/hotspot/share/ci/ciEnv.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/ci/ciEnv.cpp	Wed May 15 13:54:43 2019 +0530
@@ -405,8 +405,7 @@
     // This is a name from a signature.  Strip off the trimmings.
     // Call recursive to keep scope of strippedsym.
     TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
-                    sym->utf8_length()-2,
-                    KILL_COMPILE_ON_FATAL_(_unloaded_ciinstance_klass));
+                                                        sym->utf8_length()-2);
     ciSymbol* strippedname = get_symbol(strippedsym);
     return get_klass_by_name_impl(accessing_klass, cpool, strippedname, require_local);
   }
@@ -459,8 +458,7 @@
     // We have an unloaded array.
     // Build it on the fly if the element class exists.
     TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
-                                                 sym->utf8_length()-1,
-                                                 KILL_COMPILE_ON_FATAL_(fail_type));
+                                                     sym->utf8_length()-1);
 
     // Get element ciKlass recursively.
     ciKlass* elem_klass =
--- a/src/hotspot/share/ci/ciReplay.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/ci/ciReplay.cpp	Wed May 15 13:54:43 2019 +0530
@@ -336,7 +336,7 @@
   Symbol* parse_symbol(TRAPS) {
     const char* str = parse_escaped_string();
     if (str != NULL) {
-      Symbol* sym = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
+      Symbol* sym = SymbolTable::new_symbol(str);
       return sym;
     }
     return NULL;
@@ -345,7 +345,7 @@
   // Parse a valid klass name and look it up
   Klass* parse_klass(TRAPS) {
     const char* str = parse_escaped_string();
-    Symbol* klass_name = SymbolTable::lookup(str, (int)strlen(str), CHECK_NULL);
+    Symbol* klass_name = SymbolTable::new_symbol(str);
     if (klass_name != NULL) {
       Klass* k = NULL;
       if (_iklass != NULL) {
@@ -371,7 +371,7 @@
 
   // Lookup a klass
   Klass* resolve_klass(const char* klass, TRAPS) {
-    Symbol* klass_name = SymbolTable::lookup(klass, (int)strlen(klass), CHECK_NULL);
+    Symbol* klass_name = SymbolTable::new_symbol(klass);
     return SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD);
   }
 
@@ -800,8 +800,8 @@
     const char* field_name = parse_escaped_string();
     const char* field_signature = parse_string();
     fieldDescriptor fd;
-    Symbol* name = SymbolTable::lookup(field_name, (int)strlen(field_name), CHECK);
-    Symbol* sig = SymbolTable::lookup(field_signature, (int)strlen(field_signature), CHECK);
+    Symbol* name = SymbolTable::new_symbol(field_name);
+    Symbol* sig = SymbolTable::new_symbol(field_signature);
     if (!k->find_local_field(name, sig, &fd) ||
         !fd.is_static() ||
         fd.has_initial_value()) {
--- a/src/hotspot/share/ci/ciSignature.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/ci/ciSignature.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,16 +58,9 @@
     if (!ss.is_object()) {
       type = ciType::make(ss.type());
     } else {
-      Symbol* name = ss.as_symbol(THREAD);
-      if (HAS_PENDING_EXCEPTION) {
-        type = ss.is_array() ? (ciType*)ciEnv::unloaded_ciobjarrayklass()
-          : (ciType*)ciEnv::unloaded_ciinstance_klass();
-        env->record_out_of_memory_failure();
-        CLEAR_PENDING_EXCEPTION;
-      } else {
-        ciSymbol* klass_name = env->get_symbol(name);
-        type = env->get_klass_by_name_impl(_accessing_klass, cpool, klass_name, false);
-      }
+      Symbol* name = ss.as_symbol();
+      ciSymbol* klass_name = env->get_symbol(name);
+      type = env->get_klass_by_name_impl(_accessing_klass, cpool, klass_name, false);
     }
     _types->append(type);
     if (ss.at_return_type()) {
--- a/src/hotspot/share/ci/ciSymbol.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/ci/ciSymbol.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -132,12 +132,7 @@
 // Make a ciSymbol from a C string (implementation).
 ciSymbol* ciSymbol::make_impl(const char* s) {
   EXCEPTION_CONTEXT;
-  TempNewSymbol sym = SymbolTable::new_symbol(s, THREAD);
-  if (HAS_PENDING_EXCEPTION) {
-    CLEAR_PENDING_EXCEPTION;
-    CURRENT_THREAD_ENV->record_out_of_memory_failure();
-    return ciEnv::_unloaded_cisymbol;
-  }
+  TempNewSymbol sym = SymbolTable::new_symbol(s);
   return CURRENT_THREAD_ENV->get_symbol(sym);
 }
 
--- a/src/hotspot/share/classfile/classFileParser.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/classFileParser.cpp	Wed May 15 13:54:43 2019 +0530
@@ -335,8 +335,7 @@
                                      names,
                                      lengths,
                                      indices,
-                                     hashValues,
-                                     CHECK);
+                                     hashValues);
             names_count = 0;
           }
         } else {
@@ -373,8 +372,7 @@
                              names,
                              lengths,
                              indices,
-                             hashValues,
-                             CHECK);
+                             hashValues);
   }
 
   // Copy _current pointer of local copy back to stream.
@@ -823,7 +821,7 @@
         guarantee_property(java_lang_String::is_instance(patch()),
                            "Illegal class patch at %d in class file %s",
                            index, CHECK);
-        Symbol* const name = java_lang_String::as_symbol(patch(), CHECK);
+        Symbol* const name = java_lang_String::as_symbol(patch());
         patch_class(cp, index, NULL, name);
       }
       break;
@@ -5723,7 +5721,7 @@
     // The new class name is created with a refcount of one. When installed into the InstanceKlass,
     // it'll be two and when the ClassFileParser destructor runs, it'll go back to one and get deleted
     // when the class is unloaded.
-    _class_name = SymbolTable::new_symbol(new_anon_name, symbol_len, CHECK);
+    _class_name = SymbolTable::new_symbol(new_anon_name, symbol_len);
   }
 }
 
--- a/src/hotspot/share/classfile/classListParser.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/classListParser.cpp	Wed May 15 13:54:43 2019 +0530
@@ -326,8 +326,7 @@
 }
 
 Klass* ClassListParser::load_current_class(TRAPS) {
-  TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name, THREAD);
-  guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
+  TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name);
 
   Klass *klass = NULL;
   if (!is_loading_from_source()) {
--- a/src/hotspot/share/classfile/classLoader.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/classLoader.cpp	Wed May 15 13:54:43 2019 +0530
@@ -244,7 +244,7 @@
     return NULL;
   }
   PackageEntryTable* pkgEntryTable = loader_data->packages();
-  TempNewSymbol pkg_symbol = SymbolTable::new_symbol(pkg_name, CHECK_NULL);
+  TempNewSymbol pkg_symbol = SymbolTable::new_symbol(pkg_name);
   return pkgEntryTable->lookup_only(pkg_symbol);
 }
 
@@ -646,7 +646,7 @@
 
   for (int i = 0; i < num_of_entries; i++) {
     const char* module_name = (patch_mod_args->at(i))->module_name();
-    Symbol* const module_sym = SymbolTable::lookup(module_name, (int)strlen(module_name), CHECK);
+    Symbol* const module_sym = SymbolTable::new_symbol(module_name);
     assert(module_sym != NULL, "Failed to obtain Symbol for module name");
     ModuleClassPathList* module_cpl = new ModuleClassPathList(module_sym);
 
@@ -1126,7 +1126,7 @@
   const char *cp = package_from_name(fullq_class_name);
   if (cp != NULL) {
     PackageEntryTable* pkg_entry_tbl = ClassLoaderData::the_null_class_loader_data()->packages();
-    TempNewSymbol pkg_symbol = SymbolTable::new_symbol(cp, CHECK_false);
+    TempNewSymbol pkg_symbol = SymbolTable::new_symbol(cp);
     PackageEntry* pkg_entry = pkg_entry_tbl->lookup_only(pkg_symbol);
     if (pkg_entry != NULL) {
       assert(classpath_index != -1, "Unexpected classpath_index");
@@ -1141,7 +1141,7 @@
 oop ClassLoader::get_system_package(const char* name, TRAPS) {
   // Look up the name in the boot loader's package entry table.
   if (name != NULL) {
-    TempNewSymbol package_sym = SymbolTable::new_symbol(name, (int)strlen(name), CHECK_NULL);
+    TempNewSymbol package_sym = SymbolTable::new_symbol(name);
     // Look for the package entry in the boot loader's package entry table.
     PackageEntry* package =
       ClassLoaderData::the_null_class_loader_data()->packages()->lookup_only(package_sym);
--- a/src/hotspot/share/classfile/classLoaderData.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/classLoaderData.cpp	Wed May 15 13:54:43 2019 +0530
@@ -108,8 +108,7 @@
     const char* cl_instance_name = java_lang_String::as_utf8_string(cl_name);
 
     if (cl_instance_name != NULL && cl_instance_name[0] != '\0') {
-      // Can't throw InternalError and SymbolTable doesn't throw OOM anymore.
-      _name = SymbolTable::new_symbol(cl_instance_name, CATCH);
+      _name = SymbolTable::new_symbol(cl_instance_name);
     }
   }
 
@@ -125,8 +124,7 @@
                   (cl_name_and_id == NULL) ? _class_loader_klass->external_name() :
                                              java_lang_String::as_utf8_string(cl_name_and_id);
   assert(cl_instance_name_and_id != NULL && cl_instance_name_and_id[0] != '\0', "class loader has no name and id");
-  // Can't throw InternalError and SymbolTable doesn't throw OOM anymore.
-  _name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id, CATCH);
+  _name_and_id = SymbolTable::new_symbol(cl_instance_name_and_id);
 }
 
 ClassLoaderData::ClassLoaderData(Handle h_class_loader, bool is_unsafe_anonymous) :
--- a/src/hotspot/share/classfile/classLoaderData.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/classLoaderData.hpp	Wed May 15 13:54:43 2019 +0530
@@ -300,6 +300,10 @@
   ModuleEntryTable* modules();
   bool modules_defined() { return (_modules != NULL); }
 
+  // Offsets
+  static ByteSize holder_offset()     { return in_ByteSize(offset_of(ClassLoaderData, _holder)); }
+  static ByteSize keep_alive_offset() { return in_ByteSize(offset_of(ClassLoaderData, _keep_alive)); }
+
   // Loaded class dictionary
   Dictionary* dictionary() const { return _dictionary; }
 
--- a/src/hotspot/share/classfile/defaultMethods.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/defaultMethods.cpp	Wed May 15 13:54:43 2019 +0530
@@ -459,7 +459,7 @@
 };
 
 Symbol* MethodFamily::generate_no_defaults_message(TRAPS) const {
-  return SymbolTable::new_symbol("No qualifying defaults found", THREAD);
+  return SymbolTable::new_symbol("No qualifying defaults found");
 }
 
 Symbol* MethodFamily::generate_method_message(Symbol *klass_name, Method* method, TRAPS) const {
@@ -472,7 +472,7 @@
   ss.write((const char*)name->bytes(), name->utf8_length());
   ss.write((const char*)signature->bytes(), signature->utf8_length());
   ss.print(" is abstract");
-  return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD);
+  return SymbolTable::new_symbol(ss.base(), (int)ss.size());
 }
 
 Symbol* MethodFamily::generate_conflicts_message(GrowableArray<Method*>* methods, TRAPS) const {
@@ -487,7 +487,7 @@
     ss.print(".");
     ss.write((const char*)name->bytes(), name->utf8_length());
   }
-  return SymbolTable::new_symbol(ss.base(), (int)ss.size(), THREAD);
+  return SymbolTable::new_symbol(ss.base(), (int)ss.size());
 }
 
 
--- a/src/hotspot/share/classfile/javaClasses.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Wed May 15 13:54:43 2019 +0530
@@ -569,19 +569,19 @@
   return result;
 }
 
-Symbol* java_lang_String::as_symbol(oop java_string, TRAPS) {
+Symbol* java_lang_String::as_symbol(oop java_string) {
   typeArrayOop value  = java_lang_String::value(java_string);
   int          length = java_lang_String::length(java_string, value);
   bool      is_latin1 = java_lang_String::is_latin1(java_string);
   if (!is_latin1) {
     jchar* base = (length == 0) ? NULL : value->char_at_addr(0);
-    Symbol* sym = SymbolTable::lookup_unicode(base, length, THREAD);
+    Symbol* sym = SymbolTable::new_symbol(base, length);
     return sym;
   } else {
     ResourceMark rm;
     jbyte* position = (length == 0) ? NULL : value->byte_at_addr(0);
     const char* base = UNICODE::as_utf8(position, length);
-    Symbol* sym = SymbolTable::lookup(base, length, THREAD);
+    Symbol* sym = SymbolTable::new_symbol(base, length);
     return sym;
   }
 }
@@ -1443,7 +1443,7 @@
   if (is_instance)  st->print(";");
 }
 
-Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found, TRAPS) {
+Symbol* java_lang_Class::as_signature(oop java_class, bool intern_if_not_found) {
   assert(java_lang_Class::is_instance(java_class), "must be a Class object");
   Symbol* name;
   if (is_primitive(java_class)) {
@@ -1464,7 +1464,7 @@
       if (!intern_if_not_found) {
         name = SymbolTable::probe(sigstr, siglen);
       } else {
-        name = SymbolTable::new_symbol(sigstr, siglen, THREAD);
+        name = SymbolTable::new_symbol(sigstr, siglen);
       }
     }
   }
@@ -1895,7 +1895,7 @@
   PRESERVE_EXCEPTION_MARK;  // Keep original exception
   oop detailed_message = java_lang_Throwable::message(throwable);
   if (detailed_message != NULL) {
-    return java_lang_String::as_symbol(detailed_message, THREAD);
+    return java_lang_String::as_symbol(detailed_message);
   }
   return NULL;
 }
@@ -3703,7 +3703,7 @@
   java_lang_Class::print_signature(rtype(mt), st);
 }
 
-Symbol* java_lang_invoke_MethodType::as_signature(oop mt, bool intern_if_not_found, TRAPS) {
+Symbol* java_lang_invoke_MethodType::as_signature(oop mt, bool intern_if_not_found) {
   ResourceMark rm;
   stringStream buffer(128);
   print_signature(mt, &buffer);
@@ -3713,7 +3713,7 @@
   if (!intern_if_not_found) {
     name = SymbolTable::probe(sigstr, siglen);
   } else {
-    name = SymbolTable::new_symbol(sigstr, siglen, THREAD);
+    name = SymbolTable::new_symbol(sigstr, siglen);
   }
   return name;
 }
@@ -4375,11 +4375,11 @@
 bool JavaClasses::check_offset(const char *klass_name, int hardcoded_offset, const char *field_name, const char* field_sig) {
   EXCEPTION_MARK;
   fieldDescriptor fd;
-  TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name, CATCH);
+  TempNewSymbol klass_sym = SymbolTable::new_symbol(klass_name);
   Klass* k = SystemDictionary::resolve_or_fail(klass_sym, true, CATCH);
   InstanceKlass* ik = InstanceKlass::cast(k);
-  TempNewSymbol f_name = SymbolTable::new_symbol(field_name, CATCH);
-  TempNewSymbol f_sig  = SymbolTable::new_symbol(field_sig, CATCH);
+  TempNewSymbol f_name = SymbolTable::new_symbol(field_name);
+  TempNewSymbol f_sig  = SymbolTable::new_symbol(field_sig);
   if (!ik->find_local_field(f_name, f_sig, &fd)) {
     tty->print_cr("Nonstatic field %s.%s not found", klass_name, field_name);
     return false;
--- a/src/hotspot/share/classfile/javaClasses.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/javaClasses.hpp	Wed May 15 13:54:43 2019 +0530
@@ -205,7 +205,7 @@
   static Handle internalize_classname(Handle java_string, TRAPS) { return char_converter(java_string, '.', '/', THREAD); }
 
   // Conversion
-  static Symbol* as_symbol(oop java_string, TRAPS);
+  static Symbol* as_symbol(oop java_string);
   static Symbol* as_symbol_or_null(oop java_string);
 
   // Testers
@@ -291,7 +291,7 @@
   static Klass* as_Klass_raw(oop java_class);
   static void set_klass(oop java_class, Klass* klass);
   static BasicType as_BasicType(oop java_class, Klass** reference_klass = NULL);
-  static Symbol* as_signature(oop java_class, bool intern_if_not_found, TRAPS);
+  static Symbol* as_signature(oop java_class, bool intern_if_not_found);
   static void print_signature(oop java_class, outputStream *st);
   static const char* as_external_name(oop java_class);
   // Testing
@@ -1166,7 +1166,7 @@
   static int            ptype_slot_count(oop mt);  // extra counts for long/double
   static int            rtype_slot_count(oop mt);  // extra counts for long/double
 
-  static Symbol*        as_signature(oop mt, bool intern_if_not_found, TRAPS);
+  static Symbol*        as_signature(oop mt, bool intern_if_not_found);
   static void           print_signature(oop mt, outputStream* st);
 
   static bool is_instance(oop obj);
--- a/src/hotspot/share/classfile/modules.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/modules.cpp	Wed May 15 13:54:43 2019 +0530
@@ -111,7 +111,7 @@
 static PackageEntry* get_package_entry(ModuleEntry* module_entry, const char* package_name, TRAPS) {
   ResourceMark rm(THREAD);
   if (package_name == NULL) return NULL;
-  TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name, CHECK_NULL);
+  TempNewSymbol pkg_symbol = SymbolTable::new_symbol(package_name);
   PackageEntryTable* package_entry_table = module_entry->loader_data()->packages();
   assert(package_entry_table != NULL, "Unexpected null package entry table");
   return package_entry_table->lookup_only(pkg_symbol);
@@ -148,7 +148,7 @@
   const char* module_version = get_module_version(version);
   TempNewSymbol version_symbol;
   if (module_version != NULL) {
-    version_symbol = SymbolTable::new_symbol(module_version, CHECK);
+    version_symbol = SymbolTable::new_symbol(module_version);
   } else {
     version_symbol = NULL;
   }
@@ -160,7 +160,7 @@
     module_location =
       java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(location));
     if (module_location != NULL) {
-      location_symbol = SymbolTable::new_symbol(module_location, CHECK);
+      location_symbol = SymbolTable::new_symbol(module_location);
     }
   }
 
@@ -173,7 +173,7 @@
       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
                 err_msg("Invalid package name: %s for module: " JAVA_BASE_NAME, package_name));
     }
-    Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, CHECK);
+    Symbol* pkg_symbol = SymbolTable::new_symbol(package_name);
     pkg_list->append(pkg_symbol);
   }
 
@@ -345,7 +345,7 @@
       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), message);
     }
 
-    Symbol* pkg_symbol = SymbolTable::new_symbol(package_name, CHECK);
+    Symbol* pkg_symbol = SymbolTable::new_symbol(package_name);
     pkg_list->append(pkg_symbol);
   }
 
@@ -353,14 +353,14 @@
   assert(module_table != NULL, "module entry table shouldn't be null");
 
   // Create symbol* entry for module name.
-  TempNewSymbol module_symbol = SymbolTable::new_symbol(module_name, CHECK);
+  TempNewSymbol module_symbol = SymbolTable::new_symbol(module_name);
 
   bool dupl_modules = false;
 
   // Create symbol* entry for module version.
   TempNewSymbol version_symbol;
   if (module_version != NULL) {
-    version_symbol = SymbolTable::new_symbol(module_version, CHECK);
+    version_symbol = SymbolTable::new_symbol(module_version);
   } else {
     version_symbol = NULL;
   }
@@ -372,7 +372,7 @@
     module_location =
       java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(location));
     if (module_location != NULL) {
-      location_symbol = SymbolTable::new_symbol(module_location, CHECK);
+      location_symbol = SymbolTable::new_symbol(module_location);
     }
   }
 
@@ -657,7 +657,7 @@
   if (strlen(package_name) == 0) {
     return NULL;
   }
-  TempNewSymbol package_sym = SymbolTable::new_symbol(package_name, CHECK_NULL);
+  TempNewSymbol package_sym = SymbolTable::new_symbol(package_name);
   const PackageEntry* const pkg_entry =
     get_package_entry_by_name(package_sym, h_loader, THREAD);
   const ModuleEntry* const module_entry = (pkg_entry != NULL ? pkg_entry->module() : NULL);
--- a/src/hotspot/share/classfile/stackMapFrame.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/stackMapFrame.cpp	Wed May 15 13:54:43 2019 +0530
@@ -92,8 +92,7 @@
   // local num may be greater than size of parameters because long/double occupies two slots
   while(!ss.at_return_type()) {
     init_local_num += _verifier->change_sig_to_verificationType(
-      &ss, &_locals[init_local_num],
-      CHECK_VERIFY_(verifier(), VerificationType::bogus_type()));
+      &ss, &_locals[init_local_num]);
     ss.next();
   }
   _locals_size = init_local_num;
@@ -102,13 +101,12 @@
     case T_OBJECT:
     case T_ARRAY:
     {
-      Symbol* sig = ss.as_symbol(CHECK_(VerificationType::bogus_type()));
+      Symbol* sig = ss.as_symbol();
       if (!sig->is_permanent()) {
         // Create another symbol to save as signature stream unreferences
         // this symbol.
         Symbol *sig_copy =
-          verifier()->create_temporary_symbol(sig, 0, sig->utf8_length(),
-        CHECK_(VerificationType::bogus_type()));
+          verifier()->create_temporary_symbol(sig, 0, sig->utf8_length());
         assert(sig_copy == sig, "symbols don't match");
         sig = sig_copy;
       }
--- a/src/hotspot/share/classfile/symbolTable.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/symbolTable.cpp	Wed May 15 13:54:43 2019 +0530
@@ -195,7 +195,7 @@
   Service_lock->notify_all();
 }
 
-Symbol* SymbolTable::allocate_symbol(const char* name, int len, bool c_heap, TRAPS) {
+Symbol* SymbolTable::allocate_symbol(const char* name, int len, bool c_heap) {
   assert (len <= Symbol::max_length(), "should be checked by caller");
 
   Symbol* sym;
@@ -204,12 +204,12 @@
   }
   if (c_heap) {
     // refcount starts as 1
-    sym = new (len, THREAD) Symbol((const u1*)name, len, 1);
+    sym = new (len) Symbol((const u1*)name, len, 1);
     assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
   } else {
     // Allocate to global arena
     MutexLocker ml(SymbolArena_lock, Mutex::_no_safepoint_check_flag); // Protect arena
-    sym = new (len, arena(), THREAD) Symbol((const u1*)name, len, PERM_REFCOUNT);
+    sym = new (len, arena()) Symbol((const u1*)name, len, PERM_REFCOUNT);
   }
   return sym;
 }
@@ -317,25 +317,26 @@
   return sym;
 }
 
-Symbol* SymbolTable::lookup(const char* name, int len, TRAPS) {
+Symbol* SymbolTable::new_symbol(const char* name, int len) {
   unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
   Symbol* sym = SymbolTable::the_table()->lookup_common(name, len, hash);
   if (sym == NULL) {
-    sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true, CHECK_NULL);
+    sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true);
   }
   assert(sym->refcount() != 0, "lookup should have incremented the count");
   assert(sym->equals(name, len), "symbol must be properly initialized");
   return sym;
 }
 
-Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
+Symbol* SymbolTable::new_symbol(const Symbol* sym, int begin, int end) {
+  assert(begin <= end && end <= sym->utf8_length(), "just checking");
   assert(sym->refcount() != 0, "require a valid symbol");
   const char* name = (const char*)sym->base() + begin;
   int len = end - begin;
   unsigned int hash = hash_symbol(name, len, SymbolTable::_alt_hash);
   Symbol* found = SymbolTable::the_table()->lookup_common(name, len, hash);
   if (found == NULL) {
-    found = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true, THREAD);
+    found = SymbolTable::the_table()->do_add_if_needed(name, len, hash, true);
   }
   return found;
 }
@@ -347,8 +348,8 @@
   int _len;
   const char* _str;
 public:
-  SymbolTableLookup(Thread* thread, const char* key, int len, uintx hash)
-  : _thread(thread), _hash(hash), _len(len), _str(key) {}
+  SymbolTableLookup(const char* key, int len, uintx hash)
+  : _hash(hash), _len(len), _str(key) {}
   uintx get_hash() const {
     return _hash;
   }
@@ -388,7 +389,7 @@
 
 Symbol* SymbolTable::do_lookup(const char* name, int len, uintx hash) {
   Thread* thread = Thread::current();
-  SymbolTableLookup lookup(thread, name, len, hash);
+  SymbolTableLookup lookup(name, len, hash);
   SymbolTableGet stg;
   bool rehash_warning = false;
   _local_table->get(thread, lookup, stg, &rehash_warning);
@@ -406,23 +407,23 @@
 // Suggestion: Push unicode-based lookup all the way into the hashing
 // and probing logic, so there is no need for convert_to_utf8 until
 // an actual new Symbol* is created.
-Symbol* SymbolTable::lookup_unicode(const jchar* name, int utf16_length, TRAPS) {
+Symbol* SymbolTable::new_symbol(const jchar* name, int utf16_length) {
   int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
   char stack_buf[ON_STACK_BUFFER_LENGTH];
   if (utf8_length < (int) sizeof(stack_buf)) {
     char* chars = stack_buf;
     UNICODE::convert_to_utf8(name, utf16_length, chars);
-    return lookup(chars, utf8_length, THREAD);
+    return new_symbol(chars, utf8_length);
   } else {
-    ResourceMark rm(THREAD);
+    ResourceMark rm;
     char* chars = NEW_RESOURCE_ARRAY(char, utf8_length + 1);
     UNICODE::convert_to_utf8(name, utf16_length, chars);
-    return lookup(chars, utf8_length, THREAD);
+    return new_symbol(chars, utf8_length);
   }
 }
 
 Symbol* SymbolTable::lookup_only_unicode(const jchar* name, int utf16_length,
-                                           unsigned int& hash) {
+                                         unsigned int& hash) {
   int utf8_length = UNICODE::utf8_length((jchar*) name, utf16_length);
   char stack_buf[ON_STACK_BUFFER_LENGTH];
   if (utf8_length < (int) sizeof(stack_buf)) {
@@ -439,32 +440,33 @@
 
 void SymbolTable::new_symbols(ClassLoaderData* loader_data, const constantPoolHandle& cp,
                               int names_count, const char** names, int* lengths,
-                              int* cp_indices, unsigned int* hashValues, TRAPS) {
+                              int* cp_indices, unsigned int* hashValues) {
   bool c_heap = !loader_data->is_the_null_class_loader_data();
   for (int i = 0; i < names_count; i++) {
     const char *name = names[i];
     int len = lengths[i];
     unsigned int hash = hashValues[i];
     assert(SymbolTable::the_table()->lookup_shared(name, len, hash) == NULL, "must have checked already");
-    Symbol* sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap, CHECK);
+    Symbol* sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, c_heap);
     assert(sym->refcount() != 0, "lookup should have incremented the count");
     cp->symbol_at_put(cp_indices[i], sym);
   }
 }
 
-Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, bool heap, TRAPS) {
-  SymbolTableLookup lookup(THREAD, name, len, hash);
+Symbol* SymbolTable::do_add_if_needed(const char* name, int len, uintx hash, bool heap) {
+  SymbolTableLookup lookup(name, len, hash);
   SymbolTableGet stg;
   bool clean_hint = false;
   bool rehash_warning = false;
   Symbol* sym = NULL;
+  Thread* THREAD = Thread::current();
 
   do {
     if (_local_table->get(THREAD, lookup, stg, &rehash_warning)) {
       sym = stg.get_res_sym();
       break;
     }
-    sym = SymbolTable::the_table()->allocate_symbol(name, len, heap, THREAD);
+    sym = SymbolTable::the_table()->allocate_symbol(name, len, heap);
     if (_local_table->insert(THREAD, lookup, sym, &rehash_warning, &clean_hint)) {
       break;
     }
@@ -481,12 +483,12 @@
   return sym;
 }
 
-Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
+Symbol* SymbolTable::new_permanent_symbol(const char* name) {
   unsigned int hash = 0;
   int len = (int)strlen(name);
   Symbol* sym = SymbolTable::lookup_only(name, len, hash);
   if (sym == NULL) {
-    sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, false, CHECK_NULL);
+    sym = SymbolTable::the_table()->do_add_if_needed(name, len, hash, false);
   }
   if (!sym->is_permanent()) {
     sym->make_permanent();
--- a/src/hotspot/share/classfile/symbolTable.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/symbolTable.hpp	Wed May 15 13:54:43 2019 +0530
@@ -43,7 +43,7 @@
 // it becomes "managed" by TempNewSymbol instances. As a handle class, TempNewSymbol
 // needs to maintain proper reference counting in context of copy semantics.
 //
-// In SymbolTable, new_symbol() and lookup() will create a Symbol* if not already in the
+// In SymbolTable, new_symbol() will create a Symbol* if not already in the
 // symbol table and add to the symbol's reference count.
 // probe() and lookup_only() will increment the refcount if symbol is found.
 class TempNewSymbol : public StackObj {
@@ -139,16 +139,19 @@
 
   SymbolTable();
 
-  Symbol* allocate_symbol(const char* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F
+  Symbol* allocate_symbol(const char* name, int len, bool c_heap); // Assumes no characters larger than 0x7F
   Symbol* do_lookup(const char* name, int len, uintx hash);
-  Symbol* do_add_if_needed(const char* name, int len, uintx hash, bool heap, TRAPS);
+  Symbol* do_add_if_needed(const char* name, int len, uintx hash, bool heap);
+
+  // lookup only, won't add. Also calculate hash. Used by the ClassfileParser.
+  static Symbol* lookup_only(const char* name, int len, unsigned int& hash);
+  static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
 
   // Adding elements
   static void new_symbols(ClassLoaderData* loader_data,
                           const constantPoolHandle& cp, int names_count,
                           const char** name, int* lengths,
-                          int* cp_indices, unsigned int* hashValues,
-                          TRAPS);
+                          int* cp_indices, unsigned int* hashValues);
 
   static Symbol* lookup_shared(const char* name, int len, unsigned int hash);
   Symbol* lookup_dynamic(const char* name, int len, unsigned int hash);
@@ -190,14 +193,6 @@
   static void trigger_cleanup();
 
   // Probing
-  static Symbol* lookup(const char* name, int len, TRAPS);
-  // lookup only, won't add. Also calculate hash.
-  static Symbol* lookup_only(const char* name, int len, unsigned int& hash);
-  // adds new symbol if not found
-  static Symbol* lookup(const Symbol* sym, int begin, int end, TRAPS);
-  // jchar (UTF16) version of lookups
-  static Symbol* lookup_unicode(const jchar* name, int len, TRAPS);
-  static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
   // Needed for preloading classes in signatures when compiling.
   // Returns the symbol is already present in symbol table, otherwise
   // NULL.  NO ALLOCATION IS GUARANTEED!
@@ -210,20 +205,18 @@
     return lookup_only_unicode(name, len, ignore_hash);
   }
 
-  // Symbol creation
-  static Symbol* new_symbol(const char* utf8_buffer, int length, TRAPS) {
-    assert(utf8_buffer != NULL, "just checking");
-    return lookup(utf8_buffer, length, THREAD);
+  // Symbol lookup and create if not found.
+  // jchar (UTF16) version of lookup
+  static Symbol* new_symbol(const jchar* name, int len);
+  // char (UTF8) versions
+  static Symbol* new_symbol(const Symbol* sym, int begin, int end);
+  static Symbol* new_symbol(const char* utf8_buffer, int length);
+  static Symbol* new_symbol(const char* name) {
+    return new_symbol(name, (int)strlen(name));
   }
-  static Symbol* new_symbol(const char* name, TRAPS) {
-    return new_symbol(name, (int)strlen(name), THREAD);
-  }
-  static Symbol* new_symbol(const Symbol* sym, int begin, int end, TRAPS) {
-    assert(begin <= end && end <= sym->utf8_length(), "just checking");
-    return lookup(sym, begin, end, THREAD);
-  }
+
   // Create a symbol in the arena for symbols that are not deleted
-  static Symbol* new_permanent_symbol(const char* name, TRAPS);
+  static Symbol* new_permanent_symbol(const char* name);
 
   // Rehash the string table if it gets out of balance
   static void rehash_table();
@@ -245,7 +238,6 @@
   static void dump(outputStream* st, bool verbose=false);
   // Debugging
   static void verify();
-  static void read(const char* filename, TRAPS);
 
   // Histogram
   static void print_histogram() PRODUCT_RETURN;
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Wed May 15 13:54:43 2019 +0530
@@ -263,7 +263,7 @@
     ResourceMark rm(THREAD);
     // Ignore wrapping L and ;.
     TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1,
-                                   class_name->utf8_length() - 2, CHECK_NULL);
+                                                 class_name->utf8_length() - 2);
     return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD);
   } else {
     return resolve_instance_class_or_null(class_name, class_loader, protection_domain, THREAD);
@@ -2356,7 +2356,7 @@
   SignatureStream sig_strm(signature, is_method);
   while (!sig_strm.is_done()) {
     if (sig_strm.is_object()) {
-      Symbol* sig = sig_strm.as_symbol(CHECK_NULL);
+      Symbol* sig = sig_strm.as_symbol();
       if (!add_loader_constraint(sig, loader1, loader2, THREAD)) {
         return sig;
       }
@@ -2626,7 +2626,7 @@
       mirror = ss.as_java_mirror(class_loader, protection_domain,
                                  SignatureStream::NCDFError, CHECK_(empty));
     }
-    assert(mirror != NULL, "%s", ss.as_symbol(THREAD)->as_C_string());
+    assert(mirror != NULL, "%s", ss.as_symbol()->as_C_string());
     if (ss.at_return_type())
       rt = Handle(THREAD, mirror);
     else
--- a/src/hotspot/share/classfile/verificationType.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/verificationType.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -129,13 +129,11 @@
     case 'D': return VerificationType(Double);
     case '[':
       component = context->create_temporary_symbol(
-        name(), 1, name()->utf8_length(),
-        CHECK_(VerificationType::bogus_type()));
+        name(), 1, name()->utf8_length());
       return VerificationType::reference_type(component);
     case 'L':
       component = context->create_temporary_symbol(
-        name(), 2, name()->utf8_length() - 1,
-        CHECK_(VerificationType::bogus_type()));
+        name(), 2, name()->utf8_length() - 1);
       return VerificationType::reference_type(component);
     default:
       // Met an invalid type signature, e.g. [X
--- a/src/hotspot/share/classfile/verifier.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/verifier.cpp	Wed May 15 13:54:43 2019 +0530
@@ -595,9 +595,9 @@
   return VerificationType::reference_type(vmSymbols::java_lang_Object());
 }
 
-TypeOrigin ClassVerifier::ref_ctx(const char* sig, TRAPS) {
+TypeOrigin ClassVerifier::ref_ctx(const char* sig) {
   VerificationType vt = VerificationType::reference_type(
-      create_temporary_symbol(sig, (int)strlen(sig), THREAD));
+                         create_temporary_symbol(sig, (int)strlen(sig)));
   return TypeOrigin::implicit(vt);
 }
 
@@ -647,7 +647,7 @@
 
   // Translate the signature arguments into verification types.
   while (!sig_stream.at_return_type()) {
-    int n = change_sig_to_verificationType(&sig_stream, sig_type, CHECK_VERIFY(this));
+    int n = change_sig_to_verificationType(&sig_stream, sig_type);
     assert(n <= 2, "Unexpected signature type");
 
     // Store verification type(s).  Longs and Doubles each have two verificationTypes.
@@ -664,7 +664,7 @@
 
   // Store verification type(s) for the return type, if there is one.
   if (sig_stream.type() != T_VOID) {
-    int n = change_sig_to_verificationType(&sig_stream, sig_type, CHECK_VERIFY(this));
+    int n = change_sig_to_verificationType(&sig_stream, sig_type);
     assert(n <= 2, "Unexpected signature return type");
     for (int y = 0; y < n; y++) {
       verif_types->push(sig_type[y]);
@@ -925,7 +925,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_int_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[I", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[I")),
                 bad_type_msg, "iaload");
             return;
           }
@@ -953,7 +953,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_char_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[C", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[C")),
                 bad_type_msg, "caload");
             return;
           }
@@ -967,7 +967,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_short_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[S", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[S")),
                 bad_type_msg, "saload");
             return;
           }
@@ -981,7 +981,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_long_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[J", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[J")),
                 bad_type_msg, "laload");
             return;
           }
@@ -996,7 +996,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_float_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[F", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[F")),
                 bad_type_msg, "faload");
             return;
           }
@@ -1010,7 +1010,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_double_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[D", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[D")),
                 bad_type_msg, "daload");
             return;
           }
@@ -1099,7 +1099,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_int_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[I", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[I")),
                 bad_type_msg, "iastore");
             return;
           }
@@ -1127,7 +1127,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_char_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[C", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[C")),
                 bad_type_msg, "castore");
             return;
           }
@@ -1141,7 +1141,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_short_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[S", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[S")),
                 bad_type_msg, "sastore");
             return;
           }
@@ -1156,7 +1156,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_long_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[J", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[J")),
                 bad_type_msg, "lastore");
             return;
           }
@@ -1170,7 +1170,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_float_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[F", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[F")),
                 bad_type_msg, "fastore");
             return;
           }
@@ -1185,7 +1185,7 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_double_array()) {
             verify_error(ErrorContext::bad_type(bci,
-                current_frame.stack_top_ctx(), ref_ctx("[D", THREAD)),
+                current_frame.stack_top_ctx(), ref_ctx("[D")),
                 bad_type_msg, "dastore");
             return;
           }
@@ -2183,8 +2183,7 @@
     uintptr_t constant_type_buffer[2];
     VerificationType* v_constant_type = (VerificationType*)constant_type_buffer;
     SignatureStream sig_stream(constant_type, false);
-    int n = change_sig_to_verificationType(
-      &sig_stream, v_constant_type, CHECK_VERIFY(this));
+    int n = change_sig_to_verificationType(&sig_stream, v_constant_type);
     int opcode_n = (opcode == Bytecodes::_ldc2_w ? 2 : 1);
     if (n != opcode_n) {
       // wrong kind of ldc; reverify against updated type mask
@@ -2325,8 +2324,7 @@
 
   SignatureStream sig_stream(field_sig, false);
   VerificationType stack_object_type;
-  int n = change_sig_to_verificationType(
-    &sig_stream, field_type, CHECK_VERIFY(this));
+  int n = change_sig_to_verificationType(&sig_stream, field_type);
   u2 bci = bcs->bci();
   bool is_assignable;
   switch (bcs->raw_code()) {
@@ -3002,8 +3000,7 @@
   }
 
   // from_bt[index] contains the array signature which has a length of 2
-  Symbol* sig = create_temporary_symbol(
-    from_bt[index], 2, CHECK_(VerificationType::bogus_type()));
+  Symbol* sig = create_temporary_symbol(from_bt[index], 2);
   return VerificationType::reference_type(sig);
 }
 
@@ -3041,8 +3038,7 @@
     int n = os::snprintf(arr_sig_str, length + 1, "[L%s;", component_name);
     assert(n == length, "Unexpected number of characters in string");
   }
-  Symbol* arr_sig = create_temporary_symbol(
-    arr_sig_str, length, CHECK_VERIFY(this));
+  Symbol* arr_sig = create_temporary_symbol(arr_sig_str, length);
   VerificationType new_array_type = VerificationType::reference_type(arr_sig);
   current_frame->push_stack(new_array_type, CHECK_VERIFY(this));
 }
@@ -3150,18 +3146,18 @@
 // These are stored in the verifier until the end of verification so that
 // they can be reference counted.
 Symbol* ClassVerifier::create_temporary_symbol(const Symbol *s, int begin,
-                                               int end, TRAPS) {
+                                               int end) {
   const char* name = (const char*)s->base() + begin;
   int length = end - begin;
-  return create_temporary_symbol(name, length, CHECK_NULL);
+  return create_temporary_symbol(name, length);
 }
 
-Symbol* ClassVerifier::create_temporary_symbol(const char *name, int length, TRAPS) {
+Symbol* ClassVerifier::create_temporary_symbol(const char *name, int length) {
   // Quick deduplication check
   if (_previous_symbol != NULL && _previous_symbol->equals(name, length)) {
     return _previous_symbol;
   }
-  Symbol* sym = SymbolTable::new_symbol(name, length, CHECK_NULL);
+  Symbol* sym = SymbolTable::new_symbol(name, length);
   if (!sym->is_permanent()) {
     if (_symbols == NULL) {
       _symbols = new GrowableArray<Symbol*>(50, 0, NULL);
--- a/src/hotspot/share/classfile/verifier.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/verifier.hpp	Wed May 15 13:54:43 2019 +0530
@@ -446,7 +446,7 @@
   }
 
   int change_sig_to_verificationType(
-    SignatureStream* sig_type, VerificationType* inference_type, TRAPS);
+    SignatureStream* sig_type, VerificationType* inference_type);
 
   VerificationType cp_index_to_type(int index, const constantPoolHandle& cp, TRAPS) {
     return VerificationType::reference_type(cp->klass_name_at(index));
@@ -456,8 +456,8 @@
   // their reference counts need to be decremented when the verifier object
   // goes out of scope.  Since these symbols escape the scope in which they're
   // created, we can't use a TempNewSymbol.
-  Symbol* create_temporary_symbol(const Symbol* s, int begin, int end, TRAPS);
-  Symbol* create_temporary_symbol(const char *s, int length, TRAPS);
+  Symbol* create_temporary_symbol(const Symbol* s, int begin, int end);
+  Symbol* create_temporary_symbol(const char *s, int length);
   Symbol* create_temporary_symbol(Symbol* s) {
     if (s == _previous_symbol) {
       return s;
@@ -473,18 +473,18 @@
     return s;
   }
 
-  TypeOrigin ref_ctx(const char* str, TRAPS);
+  TypeOrigin ref_ctx(const char* str);
 
 };
 
 inline int ClassVerifier::change_sig_to_verificationType(
-    SignatureStream* sig_type, VerificationType* inference_type, TRAPS) {
+    SignatureStream* sig_type, VerificationType* inference_type) {
   BasicType bt = sig_type->type();
   switch (bt) {
     case T_OBJECT:
     case T_ARRAY:
       {
-        Symbol* name = sig_type->as_symbol(CHECK_0);
+        Symbol* name = sig_type->as_symbol();
         // Create another symbol to save as signature stream unreferences this symbol.
         Symbol* name_copy = create_temporary_symbol(name);
         assert(name_copy == name, "symbols don't match");
--- a/src/hotspot/share/classfile/vmSymbols.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/classfile/vmSymbols.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -84,7 +84,7 @@
   if (!UseSharedSpaces) {
     const char* string = &vm_symbol_bodies[0];
     for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
-      Symbol* sym = SymbolTable::new_permanent_symbol(string, CHECK);
+      Symbol* sym = SymbolTable::new_permanent_symbol(string);
       _symbols[index] = sym;
       string += strlen(string); // skip string body
       string += 1;              // skip trailing null
@@ -141,7 +141,7 @@
     // Spot-check correspondence between strings, symbols, and enums:
     assert(_symbols[NO_SID] == NULL, "must be");
     const char* str = "java/lang/Object";
-    TempNewSymbol jlo = SymbolTable::new_permanent_symbol(str, CHECK);
+    TempNewSymbol jlo = SymbolTable::new_permanent_symbol(str);
     assert(strncmp(str, (char*)jlo->base(), jlo->utf8_length()) == 0, "");
     assert(jlo == java_lang_Object(), "");
     SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object);
@@ -160,7 +160,7 @@
     // The string "format" happens (at the moment) not to be a vmSymbol,
     // though it is a method name in java.lang.String.
     str = "format";
-    TempNewSymbol fmt = SymbolTable::new_permanent_symbol(str, CHECK);
+    TempNewSymbol fmt = SymbolTable::new_permanent_symbol(str);
     sid = find_sid(fmt);
     assert(sid == NO_SID, "symbol index works (negative test)");
   }
--- a/src/hotspot/share/code/compiledMethod.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/code/compiledMethod.cpp	Wed May 15 13:54:43 2019 +0530
@@ -468,39 +468,6 @@
   return ic->set_to_clean();
 }
 
-// static_stub_Relocations may have dangling references to
-// nmethods so trim them out here.  Otherwise it looks like
-// compiled code is maintaining a link to dead metadata.
-void CompiledMethod::clean_ic_stubs() {
-#ifdef ASSERT
-  address low_boundary = oops_reloc_begin();
-  RelocIterator iter(this, low_boundary);
-  while (iter.next()) {
-    address static_call_addr = NULL;
-    if (iter.type() == relocInfo::opt_virtual_call_type) {
-      CompiledIC* cic = CompiledIC_at(&iter);
-      if (!cic->is_call_to_interpreted()) {
-        static_call_addr = iter.addr();
-      }
-    } else if (iter.type() == relocInfo::static_call_type) {
-      CompiledStaticCall* csc = compiledStaticCall_at(iter.reloc());
-      if (!csc->is_call_to_interpreted()) {
-        static_call_addr = iter.addr();
-      }
-    }
-    if (static_call_addr != NULL) {
-      RelocIterator sciter(this, low_boundary);
-      while (sciter.next()) {
-        if (sciter.type() == relocInfo::static_stub_type &&
-            sciter.static_stub_reloc()->static_call() == static_call_addr) {
-          sciter.static_stub_reloc()->clear_inline_cache();
-        }
-      }
-    }
-  }
-#endif
-}
-
 // Clean references to unloaded nmethods at addr from this one, which is not unloaded.
 template <class CompiledICorStaticCall>
 static bool clean_if_nmethod_is_unloaded(CompiledICorStaticCall *ic, address addr, CompiledMethod* from,
@@ -549,9 +516,6 @@
     return false;
   }
 
-  // All static stubs need to be cleaned.
-  clean_ic_stubs();
-
 #ifdef ASSERT
   // Check that the metadata embedded in the nmethod is alive
   CheckClass check_class;
@@ -581,6 +545,7 @@
   // Find all calls in an nmethod and clear the ones that point to non-entrant,
   // zombie and unloaded nmethods.
   RelocIterator iter(this, oops_reloc_begin());
+  bool is_in_static_stub = false;
   while(iter.next()) {
 
     switch (iter.type()) {
@@ -611,6 +576,45 @@
       }
       break;
 
+    case relocInfo::static_stub_type: {
+      is_in_static_stub = true;
+      break;
+    }
+
+    case relocInfo::metadata_type: {
+      // Only the metadata relocations contained in static/opt virtual call stubs
+      // contains the Method* passed to c2i adapters. It is the only metadata
+      // relocation that needs to be walked, as it is the one metadata relocation
+      // that violates the invariant that all metadata relocations have an oop
+      // in the compiled method (due to deferred resolution and code patching).
+
+      // This causes dead metadata to remain in compiled methods that are not
+      // unloading. Unless these slippery metadata relocations of the static
+      // stubs are at least cleared, subsequent class redefinition operations
+      // will access potentially free memory, and JavaThread execution
+      // concurrent to class unloading may call c2i adapters with dead methods.
+      if (!is_in_static_stub) {
+        // The first metadata relocation after a static stub relocation is the
+        // metadata relocation of the static stub used to pass the Method* to
+        // c2i adapters.
+        continue;
+      }
+      is_in_static_stub = false;
+      metadata_Relocation* r = iter.metadata_reloc();
+      Metadata* md = r->metadata_value();
+      if (md != NULL && md->is_method()) {
+        Method* method = static_cast<Method*>(md);
+        if (!method->method_holder()->is_loader_alive()) {
+          Atomic::store((Method*)NULL, r->metadata_addr());
+
+          if (!r->metadata_is_immediate()) {
+            r->fix_metadata_relocation();
+          }
+        }
+      }
+      break;
+    }
+
     default:
       break;
     }
--- a/src/hotspot/share/code/compiledMethod.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/code/compiledMethod.hpp	Wed May 15 13:54:43 2019 +0530
@@ -395,8 +395,6 @@
  private:
   bool static clean_ic_if_metadata_is_dead(CompiledIC *ic);
 
-  void clean_ic_stubs();
-
  public:
   // GC unloading support
   // Cleans unloaded klasses and unloaded nmethods in inline caches
--- a/src/hotspot/share/code/nmethod.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/code/nmethod.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1555,7 +1555,7 @@
     // Visit all immediate references that are embedded in the instruction stream.
     RelocIterator iter(this, oops_reloc_begin());
     while (iter.next()) {
-      if (iter.type() == relocInfo::metadata_type ) {
+      if (iter.type() == relocInfo::metadata_type) {
         metadata_Relocation* r = iter.metadata_reloc();
         // In this metadata, we must only follow those metadatas directly embedded in
         // the code.  Other metadatas (oop_index>0) are seen as part of
--- a/src/hotspot/share/compiler/compilerOracle.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/compiler/compilerOracle.cpp	Wed May 15 13:54:43 2019 +0530
@@ -829,8 +829,8 @@
       }
 
       EXCEPTION_MARK;
-      Symbol* c_name = SymbolTable::new_symbol(className, CHECK);
-      Symbol* m_name = SymbolTable::new_symbol(methodName, CHECK);
+      Symbol* c_name = SymbolTable::new_symbol(className);
+      Symbol* m_name = SymbolTable::new_symbol(methodName);
       Symbol* signature = NULL;
 
       BasicMatcher* bm = new BasicMatcher();
--- a/src/hotspot/share/compiler/methodMatcher.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/compiler/methodMatcher.cpp	Wed May 15 13:54:43 2019 +0530
@@ -300,10 +300,10 @@
         }
         line += bytes_read;
       }
-      signature = SymbolTable::new_symbol(sig, CHECK);
+      signature = SymbolTable::new_symbol(sig);
     }
-    Symbol* c_name = SymbolTable::new_symbol(class_name, CHECK);
-    Symbol* m_name = SymbolTable::new_symbol(method_name, CHECK);
+    Symbol* c_name = SymbolTable::new_symbol(class_name);
+    Symbol* m_name = SymbolTable::new_symbol(method_name);
 
     matcher->init(c_name, c_match, m_name, m_match, signature);
     return;
--- a/src/hotspot/share/gc/g1/g1AllocRegion.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1AllocRegion.hpp	Wed May 15 13:54:43 2019 +0530
@@ -27,7 +27,7 @@
 
 #include "gc/g1/heapRegion.hpp"
 #include "gc/g1/g1EvacStats.hpp"
-#include "gc/g1/g1InCSetState.hpp"
+#include "gc/g1/g1HeapRegionAttr.hpp"
 
 class G1CollectedHeap;
 
@@ -249,14 +249,14 @@
 class G1GCAllocRegion : public G1AllocRegion {
 protected:
   G1EvacStats* _stats;
-  InCSetState::in_cset_state_t _purpose;
+  G1HeapRegionAttr::region_type_t _purpose;
 
   virtual HeapRegion* allocate_new_region(size_t word_size, bool force);
   virtual void retire_region(HeapRegion* alloc_region, size_t allocated_bytes);
 
   virtual size_t retire(bool fill_up);
 
-  G1GCAllocRegion(const char* name, bool bot_updates, G1EvacStats* stats, InCSetState::in_cset_state_t purpose)
+  G1GCAllocRegion(const char* name, bool bot_updates, G1EvacStats* stats, G1HeapRegionAttr::region_type_t purpose)
   : G1AllocRegion(name, bot_updates), _stats(stats), _purpose(purpose) {
     assert(stats != NULL, "Must pass non-NULL PLAB statistics");
   }
@@ -265,13 +265,13 @@
 class SurvivorGCAllocRegion : public G1GCAllocRegion {
 public:
   SurvivorGCAllocRegion(G1EvacStats* stats)
-  : G1GCAllocRegion("Survivor GC Alloc Region", false /* bot_updates */, stats, InCSetState::Young) { }
+  : G1GCAllocRegion("Survivor GC Alloc Region", false /* bot_updates */, stats, G1HeapRegionAttr::Young) { }
 };
 
 class OldGCAllocRegion : public G1GCAllocRegion {
 public:
   OldGCAllocRegion(G1EvacStats* stats)
-  : G1GCAllocRegion("Old GC Alloc Region", true /* bot_updates */, stats, InCSetState::Old) { }
+  : G1GCAllocRegion("Old GC Alloc Region", true /* bot_updates */, stats, G1HeapRegionAttr::Old) { }
 
   // This specialization of release() makes sure that the last card that has
   // been allocated into has been completely filled by a dummy object.  This
--- a/src/hotspot/share/gc/g1/g1Allocator.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1Allocator.cpp	Wed May 15 13:54:43 2019 +0530
@@ -39,8 +39,8 @@
   _survivor_is_full(false),
   _old_is_full(false),
   _mutator_alloc_region(),
-  _survivor_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Young)),
-  _old_gc_alloc_region(heap->alloc_buffer_stats(InCSetState::Old)),
+  _survivor_gc_alloc_region(heap->alloc_buffer_stats(G1HeapRegionAttr::Young)),
+  _old_gc_alloc_region(heap->alloc_buffer_stats(G1HeapRegionAttr::Old)),
   _retained_old_gc_alloc_region(NULL) {
 }
 
@@ -161,7 +161,7 @@
 }
 
 
-HeapWord* G1Allocator::par_allocate_during_gc(InCSetState dest,
+HeapWord* G1Allocator::par_allocate_during_gc(G1HeapRegionAttr dest,
                                               size_t word_size) {
   size_t temp = 0;
   HeapWord* result = par_allocate_during_gc(dest, word_size, word_size, &temp);
@@ -171,14 +171,14 @@
   return result;
 }
 
-HeapWord* G1Allocator::par_allocate_during_gc(InCSetState dest,
+HeapWord* G1Allocator::par_allocate_during_gc(G1HeapRegionAttr dest,
                                               size_t min_word_size,
                                               size_t desired_word_size,
                                               size_t* actual_word_size) {
-  switch (dest.value()) {
-    case InCSetState::Young:
+  switch (dest.type()) {
+    case G1HeapRegionAttr::Young:
       return survivor_attempt_allocation(min_word_size, desired_word_size, actual_word_size);
-    case InCSetState::Old:
+    case G1HeapRegionAttr::Old:
       return old_attempt_allocation(min_word_size, desired_word_size, actual_word_size);
     default:
       ShouldNotReachHere();
@@ -246,22 +246,22 @@
 G1PLABAllocator::G1PLABAllocator(G1Allocator* allocator) :
   _g1h(G1CollectedHeap::heap()),
   _allocator(allocator),
-  _surviving_alloc_buffer(_g1h->desired_plab_sz(InCSetState::Young)),
-  _tenured_alloc_buffer(_g1h->desired_plab_sz(InCSetState::Old)),
+  _surviving_alloc_buffer(_g1h->desired_plab_sz(G1HeapRegionAttr::Young)),
+  _tenured_alloc_buffer(_g1h->desired_plab_sz(G1HeapRegionAttr::Old)),
   _survivor_alignment_bytes(calc_survivor_alignment_bytes()) {
-  for (uint state = 0; state < InCSetState::Num; state++) {
+  for (uint state = 0; state < G1HeapRegionAttr::Num; state++) {
     _direct_allocated[state] = 0;
     _alloc_buffers[state] = NULL;
   }
-  _alloc_buffers[InCSetState::Young] = &_surviving_alloc_buffer;
-  _alloc_buffers[InCSetState::Old]  = &_tenured_alloc_buffer;
+  _alloc_buffers[G1HeapRegionAttr::Young] = &_surviving_alloc_buffer;
+  _alloc_buffers[G1HeapRegionAttr::Old]  = &_tenured_alloc_buffer;
 }
 
 bool G1PLABAllocator::may_throw_away_buffer(size_t const allocation_word_sz, size_t const buffer_size) const {
   return (allocation_word_sz * 100 < buffer_size * ParallelGCBufferWastePct);
 }
 
-HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(InCSetState dest,
+HeapWord* G1PLABAllocator::allocate_direct_or_new_plab(G1HeapRegionAttr dest,
                                                        size_t word_sz,
                                                        bool* plab_refill_failed) {
   size_t plab_word_size = _g1h->desired_plab_sz(dest);
@@ -300,17 +300,17 @@
   // Try direct allocation.
   HeapWord* result = _allocator->par_allocate_during_gc(dest, word_sz);
   if (result != NULL) {
-    _direct_allocated[dest.value()] += word_sz;
+    _direct_allocated[dest.type()] += word_sz;
   }
   return result;
 }
 
-void G1PLABAllocator::undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz) {
+void G1PLABAllocator::undo_allocation(G1HeapRegionAttr dest, HeapWord* obj, size_t word_sz) {
   alloc_buffer(dest)->undo_allocation(obj, word_sz);
 }
 
 void G1PLABAllocator::flush_and_retire_stats() {
-  for (uint state = 0; state < InCSetState::Num; state++) {
+  for (uint state = 0; state < G1HeapRegionAttr::Num; state++) {
     PLAB* const buf = _alloc_buffers[state];
     if (buf != NULL) {
       G1EvacStats* stats = _g1h->alloc_buffer_stats(state);
@@ -323,7 +323,7 @@
 
 size_t G1PLABAllocator::waste() const {
   size_t result = 0;
-  for (uint state = 0; state < InCSetState::Num; state++) {
+  for (uint state = 0; state < G1HeapRegionAttr::Num; state++) {
     PLAB * const buf = _alloc_buffers[state];
     if (buf != NULL) {
       result += buf->waste();
@@ -334,7 +334,7 @@
 
 size_t G1PLABAllocator::undo_waste() const {
   size_t result = 0;
-  for (uint state = 0; state < InCSetState::Num; state++) {
+  for (uint state = 0; state < G1HeapRegionAttr::Num; state++) {
     PLAB * const buf = _alloc_buffers[state];
     if (buf != NULL) {
       result += buf->undo_waste();
--- a/src/hotspot/share/gc/g1/g1Allocator.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1Allocator.hpp	Wed May 15 13:54:43 2019 +0530
@@ -26,7 +26,7 @@
 #define SHARE_GC_G1_G1ALLOCATOR_HPP
 
 #include "gc/g1/g1AllocRegion.hpp"
-#include "gc/g1/g1InCSetState.hpp"
+#include "gc/g1/g1HeapRegionAttr.hpp"
 #include "gc/shared/collectedHeap.hpp"
 #include "gc/shared/plab.hpp"
 
@@ -112,10 +112,10 @@
   // allocation region, either by picking one or expanding the
   // heap, and then allocate a block of the given size. The block
   // may not be a humongous - it must fit into a single heap region.
-  HeapWord* par_allocate_during_gc(InCSetState dest,
+  HeapWord* par_allocate_during_gc(G1HeapRegionAttr dest,
                                    size_t word_size);
 
-  HeapWord* par_allocate_during_gc(InCSetState dest,
+  HeapWord* par_allocate_during_gc(G1HeapRegionAttr dest,
                                    size_t min_word_size,
                                    size_t desired_word_size,
                                    size_t* actual_word_size);
@@ -132,7 +132,7 @@
 
   PLAB  _surviving_alloc_buffer;
   PLAB  _tenured_alloc_buffer;
-  PLAB* _alloc_buffers[InCSetState::Num];
+  PLAB* _alloc_buffers[G1HeapRegionAttr::Num];
 
   // The survivor alignment in effect in bytes.
   // == 0 : don't align survivors
@@ -142,10 +142,10 @@
   const uint _survivor_alignment_bytes;
 
   // Number of words allocated directly (not counting PLAB allocation).
-  size_t _direct_allocated[InCSetState::Num];
+  size_t _direct_allocated[G1HeapRegionAttr::Num];
 
   void flush_and_retire_stats();
-  inline PLAB* alloc_buffer(InCSetState dest);
+  inline PLAB* alloc_buffer(G1HeapRegionAttr dest);
 
   // Calculate the survivor space object alignment in bytes. Returns that or 0 if
   // there are no restrictions on survivor alignment.
@@ -162,20 +162,20 @@
   // allocating a new PLAB. Returns the address of the allocated memory, NULL if
   // not successful. Plab_refill_failed indicates whether an attempt to refill the
   // PLAB failed or not.
-  HeapWord* allocate_direct_or_new_plab(InCSetState dest,
+  HeapWord* allocate_direct_or_new_plab(G1HeapRegionAttr dest,
                                         size_t word_sz,
                                         bool* plab_refill_failed);
 
   // Allocate word_sz words in the PLAB of dest.  Returns the address of the
   // allocated memory, NULL if not successful.
-  inline HeapWord* plab_allocate(InCSetState dest,
+  inline HeapWord* plab_allocate(G1HeapRegionAttr dest,
                                  size_t word_sz);
 
-  inline HeapWord* allocate(InCSetState dest,
+  inline HeapWord* allocate(G1HeapRegionAttr dest,
                             size_t word_sz,
                             bool* refill_failed);
 
-  void undo_allocation(InCSetState dest, HeapWord* obj, size_t word_sz);
+  void undo_allocation(G1HeapRegionAttr dest, HeapWord* obj, size_t word_sz);
 };
 
 // G1ArchiveRegionMap is a boolean array used to mark G1 regions as
--- a/src/hotspot/share/gc/g1/g1Allocator.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1Allocator.inline.hpp	Wed May 15 13:54:43 2019 +0530
@@ -63,15 +63,15 @@
   return mutator_alloc_region()->attempt_allocation_force(word_size);
 }
 
-inline PLAB* G1PLABAllocator::alloc_buffer(InCSetState dest) {
+inline PLAB* G1PLABAllocator::alloc_buffer(G1HeapRegionAttr dest) {
   assert(dest.is_valid(),
-         "Allocation buffer index out of bounds: " CSETSTATE_FORMAT, dest.value());
-  assert(_alloc_buffers[dest.value()] != NULL,
-         "Allocation buffer is NULL: " CSETSTATE_FORMAT, dest.value());
-  return _alloc_buffers[dest.value()];
+         "Allocation buffer index out of bounds: %s", dest.get_type_str());
+  assert(_alloc_buffers[dest.type()] != NULL,
+         "Allocation buffer is NULL: %s", dest.get_type_str());
+  return _alloc_buffers[dest.type()];
 }
 
-inline HeapWord* G1PLABAllocator::plab_allocate(InCSetState dest,
+inline HeapWord* G1PLABAllocator::plab_allocate(G1HeapRegionAttr dest,
                                                 size_t word_sz) {
   PLAB* buffer = alloc_buffer(dest);
   if (_survivor_alignment_bytes == 0 || !dest.is_young()) {
@@ -81,7 +81,7 @@
   }
 }
 
-inline HeapWord* G1PLABAllocator::allocate(InCSetState dest,
+inline HeapWord* G1PLABAllocator::allocate(G1HeapRegionAttr dest,
                                            size_t word_sz,
                                            bool* refill_failed) {
   HeapWord* const obj = plab_allocate(dest, word_sz);
--- a/src/hotspot/share/gc/g1/g1BiasedArray.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1BiasedArray.hpp	Wed May 15 13:54:43 2019 +0530
@@ -128,6 +128,11 @@
     return biased_base()[biased_index];
   }
 
+  T* get_ref_by_index(uintptr_t index) const {
+    verify_index(index);
+    return &this->base()[index];
+  }
+
   // Return the index of the element of the given array that covers the given
   // word in the heap.
   idx_t get_index_by_address(HeapWord* value) const {
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1536,7 +1536,7 @@
   _ref_processor_cm(NULL),
   _is_alive_closure_cm(this),
   _is_subject_to_discovery_cm(this),
-  _in_cset_fast_test() {
+  _region_attr() {
 
   _verifier = new G1HeapVerifier(this);
 
@@ -1772,7 +1772,7 @@
     HeapWord* end = _hrm->reserved().end();
     size_t granularity = HeapRegion::GrainBytes;
 
-    _in_cset_fast_test.initialize(start, end, granularity);
+    _region_attr.initialize(start, end, granularity);
     _humongous_reclaim_candidates.initialize(start, end, granularity);
   }
 
@@ -2626,7 +2626,7 @@
          G1EagerReclaimHumongousObjects && rem_set->is_empty();
 }
 
-class RegisterHumongousWithInCSetFastTestClosure : public HeapRegionClosure {
+class RegisterRegionsWithRegionAttrTableClosure : public HeapRegionClosure {
  private:
   size_t _total_humongous;
   size_t _candidate_humongous;
@@ -2690,24 +2690,26 @@
   }
 
  public:
-  RegisterHumongousWithInCSetFastTestClosure()
+  RegisterRegionsWithRegionAttrTableClosure()
   : _total_humongous(0),
     _candidate_humongous(0),
     _dcq(&G1BarrierSet::dirty_card_queue_set()) {
   }
 
   virtual bool do_heap_region(HeapRegion* r) {
+    G1CollectedHeap* g1h = G1CollectedHeap::heap();
+
     if (!r->is_starts_humongous()) {
+      g1h->register_region_with_region_attr(r);
       return false;
     }
-    G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
     bool is_candidate = humongous_region_is_candidate(g1h, r);
     uint rindex = r->hrm_index();
     g1h->set_humongous_reclaim_candidate(rindex, is_candidate);
     if (is_candidate) {
       _candidate_humongous++;
-      g1h->register_humongous_region_with_cset(rindex);
+      g1h->register_humongous_region_with_region_attr(rindex);
       // Is_candidate already filters out humongous object with large remembered sets.
       // If we have a humongous object with a few remembered sets, we simply flush these
       // remembered set entries into the DCQS. That will result in automatic
@@ -2743,8 +2745,14 @@
         // collecting remembered set entries for humongous regions that were not
         // reclaimed.
         r->rem_set()->set_state_complete();
+#ifdef ASSERT
+        G1HeapRegionAttr region_attr = g1h->region_attr(oop(r->bottom()));
+        assert(region_attr.needs_remset_update(), "must be");
+#endif
       }
       assert(r->rem_set()->is_empty(), "At this point any humongous candidate remembered set must be empty.");
+    } else {
+      g1h->register_region_with_region_attr(r);
     }
     _total_humongous++;
 
@@ -2757,21 +2765,15 @@
   void flush_rem_set_entries() { _dcq.flush(); }
 };
 
-void G1CollectedHeap::register_humongous_regions_with_cset() {
-  if (!G1EagerReclaimHumongousObjects) {
-    phase_times()->record_fast_reclaim_humongous_stats(0.0, 0, 0);
-    return;
-  }
-  double time = os::elapsed_counter();
-
-  // Collect reclaim candidate information and register candidates with cset.
-  RegisterHumongousWithInCSetFastTestClosure cl;
+void G1CollectedHeap::register_regions_with_region_attr() {
+  Ticks start = Ticks::now();
+
+  RegisterRegionsWithRegionAttrTableClosure cl;
   heap_region_iterate(&cl);
 
-  time = ((double)(os::elapsed_counter() - time) / os::elapsed_frequency()) * 1000.0;
-  phase_times()->record_fast_reclaim_humongous_stats(time,
-                                                     cl.total_humongous(),
-                                                     cl.candidate_humongous());
+  phase_times()->record_register_regions((Ticks::now() - start).seconds() * 1000.0,
+                                         cl.total_humongous(),
+                                         cl.candidate_humongous());
   _has_humongous_reclaim_candidates = cl.candidate_humongous() > 0;
 
   // Finally flush all remembered set entries to re-check into the global DCQS.
@@ -2861,7 +2863,7 @@
 
   collection_set()->start_incremental_building();
 
-  clear_cset_fast_test();
+  clear_region_attr();
 
   guarantee(_eden.length() == 0, "eden should have been cleared");
   policy()->transfer_survivors_to_cset(survivor());
@@ -3302,17 +3304,17 @@
     oop obj = *p;
     assert(obj != NULL, "the caller should have filtered out NULL values");
 
-    const InCSetState cset_state =_g1h->in_cset_state(obj);
-    if (!cset_state.is_in_cset_or_humongous()) {
+    const G1HeapRegionAttr region_attr =_g1h->region_attr(obj);
+    if (!region_attr.is_in_cset_or_humongous()) {
       return;
     }
-    if (cset_state.is_in_cset()) {
+    if (region_attr.is_in_cset()) {
       assert( obj->is_forwarded(), "invariant" );
       *p = obj->forwardee();
     } else {
       assert(!obj->is_forwarded(), "invariant" );
-      assert(cset_state.is_humongous(),
-             "Only allowed InCSet state is IsHumongous, but is %d", cset_state.value());
+      assert(region_attr.is_humongous(),
+             "Only allowed G1HeapRegionAttr state is IsHumongous, but is %d", region_attr.type());
      _g1h->set_humongous_is_live(obj);
     }
   }
@@ -3572,10 +3574,10 @@
   // Initialize the GC alloc regions.
   _allocator->init_gc_alloc_regions(evacuation_info);
 
-  register_humongous_regions_with_cset();
+  register_regions_with_region_attr();
   assert(_verifier->check_cset_fast_test(), "Inconsistency in the InCSetState table.");
 
-  rem_set()->prepare_for_oops_into_collection_set_do();
+  rem_set()->prepare_for_scan_rem_set();
   _preserved_marks_set.assert_empty();
 
 #if COMPILER2_OR_JVMCI
@@ -3788,7 +3790,7 @@
 void G1CollectedHeap::post_evacuate_collection_set(G1EvacuationInfo& evacuation_info, G1ParScanThreadStateSet* per_thread_states) {
   // Also cleans the card table from temporary duplicate detection information used
   // during UpdateRS/ScanRS.
-  rem_set()->cleanup_after_oops_into_collection_set_do();
+  rem_set()->cleanup_after_scan_rem_set();
 
   // Process any discovered reference objects - we have
   // to do this _before_ we retire the GC alloc regions
@@ -3970,7 +3972,7 @@
       G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
       assert(r->in_collection_set(), "Region %u should be in collection set.", r->hrm_index());
-      g1h->clear_in_cset(r);
+      g1h->clear_region_attr(r);
 
       if (r->is_young()) {
         assert(r->young_index_in_cset() != -1 && (uint)r->young_index_in_cset() < g1h->collection_set()->young_region_length(),
@@ -4031,7 +4033,7 @@
       G1Policy* policy = g1h->policy();
       policy->add_bytes_allocated_in_old_since_last_gc(_bytes_allocated_in_old_since_last_gc);
 
-      g1h->alloc_buffer_stats(InCSetState::Old)->add_failure_used_and_waste(_failure_used_words, _failure_waste_words);
+      g1h->alloc_buffer_stats(G1HeapRegionAttr::Old)->add_failure_used_and_waste(_failure_used_words, _failure_waste_words);
     }
   };
 
@@ -4365,7 +4367,7 @@
 public:
   virtual bool do_heap_region(HeapRegion* r) {
     assert(r->in_collection_set(), "Region %u must have been in collection set", r->hrm_index());
-    G1CollectedHeap::heap()->clear_in_cset(r);
+    G1CollectedHeap::heap()->clear_region_attr(r);
     r->set_young_index_in_cset(-1);
     return false;
   }
@@ -4582,7 +4584,7 @@
 
 // Methods for the GC alloc regions
 
-bool G1CollectedHeap::has_more_regions(InCSetState dest) {
+bool G1CollectedHeap::has_more_regions(G1HeapRegionAttr dest) {
   if (dest.is_old()) {
     return true;
   } else {
@@ -4590,7 +4592,7 @@
   }
 }
 
-HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size, InCSetState dest) {
+HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size, G1HeapRegionAttr dest) {
   assert(FreeList_lock->owned_by_self(), "pre-condition");
 
   if (!has_more_regions(dest)) {
@@ -4618,6 +4620,7 @@
       _verifier->check_bitmaps("Old Region Allocation", new_alloc_region);
     }
     _policy->remset_tracker()->update_at_allocate(new_alloc_region);
+    register_region_with_region_attr(new_alloc_region);
     _hr_printer.alloc(new_alloc_region);
     return new_alloc_region;
   }
@@ -4626,12 +4629,12 @@
 
 void G1CollectedHeap::retire_gc_alloc_region(HeapRegion* alloc_region,
                                              size_t allocated_bytes,
-                                             InCSetState dest) {
+                                             G1HeapRegionAttr dest) {
   policy()->record_bytes_copied_during_gc(allocated_bytes);
   if (dest.is_old()) {
     old_set_add(alloc_region);
   } else {
-    assert(dest.is_young(), "Retiring alloc region should be young(%d)", dest.value());
+    assert(dest.is_young(), "Retiring alloc region should be young (%d)", dest.type());
     _survivor.add_used_bytes(allocated_bytes);
   }
 
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.hpp	Wed May 15 13:54:43 2019 +0530
@@ -40,7 +40,7 @@
 #include "gc/g1/g1HeapTransition.hpp"
 #include "gc/g1/g1HeapVerifier.hpp"
 #include "gc/g1/g1HRPrinter.hpp"
-#include "gc/g1/g1InCSetState.hpp"
+#include "gc/g1/g1HeapRegionAttr.hpp"
 #include "gc/g1/g1MonitoringSupport.hpp"
 #include "gc/g1/g1SurvivorRegions.hpp"
 #include "gc/g1/g1YCTypes.hpp"
@@ -464,10 +464,10 @@
                                    size_t allocated_bytes);
 
   // For GC alloc regions.
-  bool has_more_regions(InCSetState dest);
-  HeapRegion* new_gc_alloc_region(size_t word_size, InCSetState dest);
+  bool has_more_regions(G1HeapRegionAttr dest);
+  HeapRegion* new_gc_alloc_region(size_t word_size, G1HeapRegionAttr dest);
   void retire_gc_alloc_region(HeapRegion* alloc_region,
-                              size_t allocated_bytes, InCSetState dest);
+                              size_t allocated_bytes, G1HeapRegionAttr dest);
 
   // - if explicit_gc is true, the GC is for a System.gc() etc,
   //   otherwise it's for a failed allocation.
@@ -551,10 +551,10 @@
   bool expand(size_t expand_bytes, WorkGang* pretouch_workers = NULL, double* expand_time_ms = NULL);
 
   // Returns the PLAB statistics for a given destination.
-  inline G1EvacStats* alloc_buffer_stats(InCSetState dest);
+  inline G1EvacStats* alloc_buffer_stats(G1HeapRegionAttr dest);
 
   // Determines PLAB size for a given destination.
-  inline size_t desired_plab_sz(InCSetState dest);
+  inline size_t desired_plab_sz(G1HeapRegionAttr dest);
 
   // Do anything common to GC's.
   void gc_prologue(bool full);
@@ -573,27 +573,24 @@
   inline void set_humongous_is_live(oop obj);
 
   // Register the given region to be part of the collection set.
-  inline void register_humongous_region_with_cset(uint index);
-  // Register regions with humongous objects (actually on the start region) in
-  // the in_cset_fast_test table.
-  void register_humongous_regions_with_cset();
+  inline void register_humongous_region_with_region_attr(uint index);
+  // Update region attributes table with information about all regions.
+  void register_regions_with_region_attr();
   // We register a region with the fast "in collection set" test. We
   // simply set to true the array slot corresponding to this region.
-  void register_young_region_with_cset(HeapRegion* r) {
-    _in_cset_fast_test.set_in_young(r->hrm_index());
-  }
-  void register_old_region_with_cset(HeapRegion* r) {
-    _in_cset_fast_test.set_in_old(r->hrm_index());
+  void register_young_region_with_region_attr(HeapRegion* r) {
+    _region_attr.set_in_young(r->hrm_index());
   }
-  void register_optional_region_with_cset(HeapRegion* r) {
-    _in_cset_fast_test.set_optional(r->hrm_index());
-  }
-  void clear_in_cset(const HeapRegion* hr) {
-    _in_cset_fast_test.clear(hr);
+  inline void register_region_with_region_attr(HeapRegion* r);
+  inline void register_old_region_with_region_attr(HeapRegion* r);
+  inline void register_optional_region_with_region_attr(HeapRegion* r);
+
+  void clear_region_attr(const HeapRegion* hr) {
+    _region_attr.clear(hr);
   }
 
-  void clear_cset_fast_test() {
-    _in_cset_fast_test.clear();
+  void clear_region_attr() {
+    _region_attr.clear();
   }
 
   bool is_user_requested_concurrent_full_gc(GCCause::Cause cause);
@@ -1110,11 +1107,11 @@
   // This array is used for a quick test on whether a reference points into
   // the collection set or not. Each of the array's elements denotes whether the
   // corresponding region is in the collection set or not.
-  G1InCSetStateFastTestBiasedMappedArray _in_cset_fast_test;
+  G1HeapRegionAttrBiasedMappedArray _region_attr;
 
  public:
 
-  inline InCSetState in_cset_state(const oop obj);
+  inline G1HeapRegionAttr region_attr(const oop obj);
 
   // Return "TRUE" iff the given object address is in the reserved
   // region of g1.
--- a/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1CollectedHeap.inline.hpp	Wed May 15 13:54:43 2019 +0530
@@ -30,6 +30,7 @@
 #include "gc/g1/g1CollectorState.hpp"
 #include "gc/g1/g1Policy.hpp"
 #include "gc/g1/heapRegionManager.inline.hpp"
+#include "gc/g1/heapRegionRemSet.hpp"
 #include "gc/g1/heapRegionSet.inline.hpp"
 #include "gc/shared/taskqueue.inline.hpp"
 #include "runtime/orderAccess.hpp"
@@ -38,11 +39,11 @@
   return _policy->phase_times();
 }
 
-G1EvacStats* G1CollectedHeap::alloc_buffer_stats(InCSetState dest) {
-  switch (dest.value()) {
-    case InCSetState::Young:
+G1EvacStats* G1CollectedHeap::alloc_buffer_stats(G1HeapRegionAttr dest) {
+  switch (dest.type()) {
+    case G1HeapRegionAttr::Young:
       return &_survivor_evac_stats;
-    case InCSetState::Old:
+    case G1HeapRegionAttr::Old:
       return &_old_evac_stats;
     default:
       ShouldNotReachHere();
@@ -50,7 +51,7 @@
   }
 }
 
-size_t G1CollectedHeap::desired_plab_sz(InCSetState dest) {
+size_t G1CollectedHeap::desired_plab_sz(G1HeapRegionAttr dest) {
   size_t gclab_word_size = alloc_buffer_stats(dest)->desired_plab_sz(workers()->active_workers());
   // Prevent humongous PLAB sizes for two reasons:
   // * PLABs are allocated using a similar paths as oops, but should
@@ -150,23 +151,35 @@
 }
 
 inline bool G1CollectedHeap::is_in_cset(HeapWord* addr) {
-  return _in_cset_fast_test.is_in_cset(addr);
+  return _region_attr.is_in_cset(addr);
 }
 
 bool G1CollectedHeap::is_in_cset(const HeapRegion* hr) {
-  return _in_cset_fast_test.is_in_cset(hr);
+  return _region_attr.is_in_cset(hr);
 }
 
 bool G1CollectedHeap::is_in_cset_or_humongous(const oop obj) {
-  return _in_cset_fast_test.is_in_cset_or_humongous((HeapWord*)obj);
+  return _region_attr.is_in_cset_or_humongous((HeapWord*)obj);
+}
+
+G1HeapRegionAttr G1CollectedHeap::region_attr(const oop obj) {
+  return _region_attr.at((HeapWord*)obj);
+}
+
+void G1CollectedHeap::register_humongous_region_with_region_attr(uint index) {
+  _region_attr.set_humongous(index, region_at(index)->rem_set()->is_tracked());
 }
 
-InCSetState G1CollectedHeap::in_cset_state(const oop obj) {
-  return _in_cset_fast_test.at((HeapWord*)obj);
+void G1CollectedHeap::register_region_with_region_attr(HeapRegion* r) {
+  _region_attr.set_has_remset(r->hrm_index(), r->rem_set()->is_tracked());
 }
 
-void G1CollectedHeap::register_humongous_region_with_cset(uint index) {
-  _in_cset_fast_test.set_humongous(index);
+void G1CollectedHeap::register_old_region_with_region_attr(HeapRegion* r) {
+  _region_attr.set_in_old(r->hrm_index(), r->rem_set()->is_tracked());
+}
+
+void G1CollectedHeap::register_optional_region_with_region_attr(HeapRegion* r) {
+  _region_attr.set_optional(r->hrm_index(), r->rem_set()->is_tracked());
 }
 
 #ifndef PRODUCT
@@ -294,7 +307,7 @@
   // thread (i.e. within the VM thread).
   if (is_humongous_reclaim_candidate(region)) {
     set_humongous_reclaim_candidate(region, false);
-    _in_cset_fast_test.clear_humongous(region);
+    _region_attr.clear_humongous(region);
   }
 }
 
--- a/src/hotspot/share/gc/g1/g1CollectionSet.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1CollectionSet.cpp	Wed May 15 13:54:43 2019 +0530
@@ -121,7 +121,7 @@
   assert(hr->is_old(), "the region should be old");
 
   assert(!hr->in_collection_set(), "should not already be in the collection set");
-  _g1h->register_old_region_with_cset(hr);
+  _g1h->register_old_region_with_region_attr(hr);
 
   _collection_set_regions[_collection_set_cur_length++] = hr->hrm_index();
   assert(_collection_set_cur_length <= _collection_set_max_length, "Collection set now larger than maximum size.");
@@ -137,7 +137,7 @@
   assert(hr->is_old(), "the region should be old");
   assert(!hr->in_collection_set(), "should not already be in the CSet");
 
-  _g1h->register_optional_region_with_cset(hr);
+  _g1h->register_optional_region_with_region_attr(hr);
 
   hr->set_index_in_opt_cset(_num_optional_regions++);
 }
@@ -316,7 +316,7 @@
   }
 
   assert(!hr->in_collection_set(), "invariant");
-  _g1h->register_young_region_with_cset(hr);
+  _g1h->register_young_region_with_region_attr(hr);
 }
 
 void G1CollectionSet::add_survivor_regions(HeapRegion* hr) {
@@ -492,7 +492,7 @@
     HeapRegion* r = candidates()->at(candidate_idx + i);
     // This potentially optional candidate region is going to be an actual collection
     // set region. Clear cset marker.
-    _g1h->clear_in_cset(r);
+    _g1h->clear_region_attr(r);
     add_old_region(r);
   }
   candidates()->remove(num_old_candidate_regions);
@@ -526,7 +526,7 @@
   for (uint i = 0; i < _num_optional_regions; i++) {
     HeapRegion* r = candidates()->at(candidates()->cur_idx() + i);
     pss->record_unused_optional_region(r);
-    _g1h->clear_in_cset(r);
+    _g1h->clear_region_attr(r);
     r->clear_index_in_opt_cset();
   }
   free_optional_regions();
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.cpp	Wed May 15 13:54:43 2019 +0530
@@ -170,7 +170,7 @@
   _recorded_total_free_cset_time_ms = 0.0;
   _recorded_serial_free_cset_time_ms = 0.0;
   _cur_fast_reclaim_humongous_time_ms = 0.0;
-  _cur_fast_reclaim_humongous_register_time_ms = 0.0;
+  _cur_region_register_time = 0.0;
   _cur_fast_reclaim_humongous_total = 0;
   _cur_fast_reclaim_humongous_candidates = 0;
   _cur_fast_reclaim_humongous_reclaimed = 0;
@@ -364,7 +364,7 @@
   const double sum_ms = _root_region_scan_wait_time_ms +
                         _recorded_young_cset_choice_time_ms +
                         _recorded_non_young_cset_choice_time_ms +
-                        _cur_fast_reclaim_humongous_register_time_ms +
+                        _cur_region_register_time +
                         _recorded_clear_claimed_marks_time_ms;
 
   info_time("Pre Evacuate Collection Set", sum_ms);
@@ -374,8 +374,8 @@
   }
   debug_time("Prepare TLABs", _cur_prepare_tlab_time_ms);
   debug_time("Choose Collection Set", (_recorded_young_cset_choice_time_ms + _recorded_non_young_cset_choice_time_ms));
+  debug_time("Region Register", _cur_region_register_time);
   if (G1EagerReclaimHumongousObjects) {
-    debug_time("Humongous Register", _cur_fast_reclaim_humongous_register_time_ms);
     trace_count("Humongous Total", _cur_fast_reclaim_humongous_total);
     trace_count("Humongous Candidate", _cur_fast_reclaim_humongous_candidates);
   }
--- a/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1GCPhaseTimes.hpp	Wed May 15 13:54:43 2019 +0530
@@ -176,8 +176,9 @@
 
   double _recorded_serial_free_cset_time_ms;
 
+  double _cur_region_register_time;
+
   double _cur_fast_reclaim_humongous_time_ms;
-  double _cur_fast_reclaim_humongous_register_time_ms;
   size_t _cur_fast_reclaim_humongous_total;
   size_t _cur_fast_reclaim_humongous_candidates;
   size_t _cur_fast_reclaim_humongous_reclaimed;
@@ -305,8 +306,8 @@
     _recorded_serial_free_cset_time_ms = time_ms;
   }
 
-  void record_fast_reclaim_humongous_stats(double time_ms, size_t total, size_t candidates) {
-    _cur_fast_reclaim_humongous_register_time_ms = time_ms;
+  void record_register_regions(double time_ms, size_t total, size_t candidates) {
+    _cur_region_register_time = time_ms;
     _cur_fast_reclaim_humongous_total = total;
     _cur_fast_reclaim_humongous_candidates = candidates;
   }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/g1/g1HeapRegionAttr.hpp	Wed May 15 13:54:43 2019 +0530
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_GC_G1_G1HEAPREGIONATTR_HPP
+#define SHARE_GC_G1_G1HEAPREGIONATTR_HPP
+
+#include "gc/g1/g1BiasedArray.hpp"
+#include "gc/g1/heapRegion.hpp"
+
+// Per-region attributes often used during garbage collection to avoid costly
+// lookups for that information all over the place.
+struct G1HeapRegionAttr {
+public:
+  // We use different types to represent the state value depending on platform as
+  // some have issues loading parts of words.
+#ifdef SPARC
+  typedef int32_t region_type_t;
+  typedef uint32_t needs_remset_update_t;
+#else
+  typedef int8_t region_type_t;
+  typedef uint8_t needs_remset_update_t;
+#endif
+
+private:
+  needs_remset_update_t _needs_remset_update;
+  region_type_t _type;
+
+public:
+  // Selection of the values for the _type field were driven to micro-optimize the
+  // encoding and frequency of the checks.
+  // The most common check for a given reference is whether the region is in the
+  // collection set or not, and which generation this region is in.
+  // The selected encoding allows us to use a single check (> NotInCSet) for the
+  // former.
+  //
+  // The other values are used for objects requiring various special cases,
+  // for example eager reclamation of humongous objects or optional regions.
+  static const region_type_t Optional     =  -2;    // The region is optional and NOT in the current collection set.
+  static const region_type_t Humongous    =  -1;    // The region is a humongous candidate not in the current collection set.
+  static const region_type_t NotInCSet    =   0;    // The region is not in the collection set.
+  static const region_type_t Young        =   1;    // The region is in the collection set and a young region.
+  static const region_type_t Old          =   2;    // The region is in the collection set and an old region.
+  static const region_type_t Num          =   3;
+
+  G1HeapRegionAttr(region_type_t type = NotInCSet, bool needs_remset_update = false) :
+    _needs_remset_update(needs_remset_update), _type(type) {
+
+    assert(is_valid(), "Invalid type %d", _type);
+  }
+
+  region_type_t type() const           { return _type; }
+
+  const char* get_type_str() const {
+    switch (type()) {
+      case Optional: return "Optional";
+      case Humongous: return "Humongous";
+      case NotInCSet: return "NotInCSet";
+      case Young: return "Young";
+      case Old: return "Old";
+      default: ShouldNotReachHere(); return "";
+    }
+  }
+
+  bool needs_remset_update() const     { return _needs_remset_update != 0; }
+
+  void set_old()                       { _type = Old; }
+  void clear_humongous()               {
+    assert(is_humongous() || !is_in_cset(), "must be");
+    _type = NotInCSet;
+  }
+  void set_has_remset(bool value)      { _needs_remset_update = value ? 1 : 0; }
+
+  bool is_in_cset_or_humongous() const { return is_in_cset() || is_humongous(); }
+  bool is_in_cset() const              { return type() > NotInCSet; }
+
+  bool is_humongous() const            { return type() == Humongous; }
+  bool is_young() const                { return type() == Young; }
+  bool is_old() const                  { return type() == Old; }
+  bool is_optional() const             { return type() == Optional; }
+
+#ifdef ASSERT
+  bool is_default() const              { return type() == NotInCSet; }
+  bool is_valid() const                { return (type() >= Optional && type() < Num); }
+  bool is_valid_gen() const            { return (type() >= Young && type() <= Old); }
+#endif
+};
+
+// Table for all regions in the heap for above.
+//
+// We use this to speed up reference processing during young collection and
+// quickly reclaim humongous objects. For the latter, at the start of GC, by adding
+// it as a humongous region we enable special handling for that region. During the
+// reference iteration closures, when we see a humongous region, we then simply mark
+// it as referenced, i.e. live, and remove it from this table to prevent further
+// processing on it.
+//
+// This means that this does NOT completely correspond to the information stored
+// in a HeapRegion, but only to what is interesting for the current young collection.
+class G1HeapRegionAttrBiasedMappedArray : public G1BiasedMappedArray<G1HeapRegionAttr> {
+ protected:
+  G1HeapRegionAttr default_value() const { return G1HeapRegionAttr(G1HeapRegionAttr::NotInCSet); }
+ public:
+  void set_optional(uintptr_t index, bool needs_remset_update) {
+    assert(get_by_index(index).is_default(),
+           "Region attributes at index " INTPTR_FORMAT " should be default but is %s", index, get_by_index(index).get_type_str());
+    set_by_index(index, G1HeapRegionAttr(G1HeapRegionAttr::Optional, needs_remset_update));
+  }
+
+  void set_humongous(uintptr_t index, bool needs_remset_update) {
+    assert(get_by_index(index).is_default(),
+           "Region attributes at index " INTPTR_FORMAT " should be default but is %s", index, get_by_index(index).get_type_str());
+    set_by_index(index, G1HeapRegionAttr(G1HeapRegionAttr::Humongous, needs_remset_update));
+  }
+
+  void clear_humongous(uintptr_t index) {
+    get_ref_by_index(index)->clear_humongous();
+  }
+
+  void set_has_remset(uintptr_t index, bool needs_remset_update) {
+    get_ref_by_index(index)->set_has_remset(needs_remset_update);
+  }
+
+  void set_in_young(uintptr_t index) {
+    assert(get_by_index(index).is_default(),
+           "Region attributes at index " INTPTR_FORMAT " should be default but is %s", index, get_by_index(index).get_type_str());
+    set_by_index(index, G1HeapRegionAttr(G1HeapRegionAttr::Young, true));
+  }
+
+  void set_in_old(uintptr_t index, bool needs_remset_update) {
+    assert(get_by_index(index).is_default(),
+           "Region attributes at index " INTPTR_FORMAT " should be default but is %s", index, get_by_index(index).get_type_str());
+    set_by_index(index, G1HeapRegionAttr(G1HeapRegionAttr::Old, needs_remset_update));
+  }
+
+  bool is_in_cset_or_humongous(HeapWord* addr) const { return at(addr).is_in_cset_or_humongous(); }
+  bool is_in_cset(HeapWord* addr) const { return at(addr).is_in_cset(); }
+  bool is_in_cset(const HeapRegion* hr) const { return get_by_index(hr->hrm_index()).is_in_cset(); }
+  G1HeapRegionAttr at(HeapWord* addr) const { return get_by_address(addr); }
+  void clear() { G1BiasedMappedArray<G1HeapRegionAttr>::clear(); }
+  void clear(const HeapRegion* hr) { return set_by_index(hr->hrm_index(), G1HeapRegionAttr(G1HeapRegionAttr::NotInCSet)); }
+};
+
+#endif // SHARE_GC_G1_G1HEAPREGIONATTR_HPP
--- a/src/hotspot/share/gc/g1/g1HeapVerifier.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1HeapVerifier.cpp	Wed May 15 13:54:43 2019 +0530
@@ -790,50 +790,50 @@
 
   virtual bool do_heap_region(HeapRegion* hr) {
     uint i = hr->hrm_index();
-    InCSetState cset_state = (InCSetState) G1CollectedHeap::heap()->_in_cset_fast_test.get_by_index(i);
+    G1HeapRegionAttr region_attr = (G1HeapRegionAttr) G1CollectedHeap::heap()->_region_attr.get_by_index(i);
     if (hr->is_humongous()) {
       if (hr->in_collection_set()) {
         log_error(gc, verify)("## humongous region %u in CSet", i);
         _failures = true;
         return true;
       }
-      if (cset_state.is_in_cset()) {
-        log_error(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for humongous region %u", cset_state.value(), i);
+      if (region_attr.is_in_cset()) {
+        log_error(gc, verify)("## inconsistent region attr type %s for humongous region %u", region_attr.get_type_str(), i);
         _failures = true;
         return true;
       }
-      if (hr->is_continues_humongous() && cset_state.is_humongous()) {
-        log_error(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for continues humongous region %u", cset_state.value(), i);
+      if (hr->is_continues_humongous() && region_attr.is_humongous()) {
+        log_error(gc, verify)("## inconsistent region attr type %s for continues humongous region %u", region_attr.get_type_str(), i);
         _failures = true;
         return true;
       }
     } else {
-      if (cset_state.is_humongous()) {
-        log_error(gc, verify)("## inconsistent cset state " CSETSTATE_FORMAT " for non-humongous region %u", cset_state.value(), i);
+      if (region_attr.is_humongous()) {
+        log_error(gc, verify)("## inconsistent region attr type %s for non-humongous region %u", region_attr.get_type_str(), i);
         _failures = true;
         return true;
       }
-      if (hr->in_collection_set() != cset_state.is_in_cset()) {
-        log_error(gc, verify)("## in CSet %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
-                             hr->in_collection_set(), cset_state.value(), i);
+      if (hr->in_collection_set() != region_attr.is_in_cset()) {
+        log_error(gc, verify)("## in CSet %d / region attr type %s inconsistency for region %u",
+                             hr->in_collection_set(), region_attr.get_type_str(), i);
         _failures = true;
         return true;
       }
-      if (cset_state.is_in_cset()) {
+      if (region_attr.is_in_cset()) {
         if (hr->is_archive()) {
           log_error(gc, verify)("## is_archive in collection set for region %u", i);
           _failures = true;
           return true;
         }
-        if (hr->is_young() != (cset_state.is_young())) {
-          log_error(gc, verify)("## is_young %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
-                               hr->is_young(), cset_state.value(), i);
+        if (hr->is_young() != (region_attr.is_young())) {
+          log_error(gc, verify)("## is_young %d / region attr type %s inconsistency for region %u",
+                               hr->is_young(), region_attr.get_type_str(), i);
           _failures = true;
           return true;
         }
-        if (hr->is_old() != (cset_state.is_old())) {
-          log_error(gc, verify)("## is_old %d / cset state " CSETSTATE_FORMAT " inconsistency for region %u",
-                               hr->is_old(), cset_state.value(), i);
+        if (hr->is_old() != (region_attr.is_old())) {
+          log_error(gc, verify)("## is_old %d / region attr type %s inconsistency for region %u",
+                               hr->is_old(), region_attr.get_type_str(), i);
           _failures = true;
           return true;
         }
--- a/src/hotspot/share/gc/g1/g1InCSetState.hpp	Tue May 14 11:23:08 2019 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#ifndef SHARE_GC_G1_G1INCSETSTATE_HPP
-#define SHARE_GC_G1_G1INCSETSTATE_HPP
-
-#include "gc/g1/g1BiasedArray.hpp"
-#include "gc/g1/heapRegion.hpp"
-
-// Per-region state during garbage collection.
-struct InCSetState {
- public:
-  // We use different types to represent the state value. Particularly SPARC puts
-  // values in structs from "left to right", i.e. MSB to LSB. This results in many
-  // unnecessary shift operations when loading and storing values of this type.
-  // This degrades performance significantly (>10%) on that platform.
-  // Other tested ABIs do not seem to have this problem, and actually tend to
-  // favor smaller types, so we use the smallest usable type there.
-#ifdef SPARC
-  #define CSETSTATE_FORMAT INTPTR_FORMAT
-  typedef intptr_t in_cset_state_t;
-#else
-  #define CSETSTATE_FORMAT "%d"
-  typedef int8_t in_cset_state_t;
-#endif
- private:
-  in_cset_state_t _value;
- public:
-  enum {
-    // Selection of the values were driven to micro-optimize the encoding and
-    // frequency of the checks.
-    // The most common check is whether the region is in the collection set or not,
-    // this encoding allows us to use an > 0 check.
-    // The positive values are encoded in increasing generation order, which
-    // makes getting the next generation fast by a simple increment. They are also
-    // used to index into arrays.
-    // The negative values are used for objects requiring various special cases,
-    // for example eager reclamation of humongous objects or optional regions.
-    Optional     = -2,    // The region is optional
-    Humongous    = -1,    // The region is humongous
-    NotInCSet    =  0,    // The region is not in the collection set.
-    Young        =  1,    // The region is in the collection set and a young region.
-    Old          =  2,    // The region is in the collection set and an old region.
-    Num
-  };
-
-  InCSetState(in_cset_state_t value = NotInCSet) : _value(value) {
-    assert(is_valid(), "Invalid state %d", _value);
-  }
-
-  in_cset_state_t value() const        { return _value; }
-
-  void set_old()                       { _value = Old; }
-
-  bool is_in_cset_or_humongous() const { return is_in_cset() || is_humongous(); }
-  bool is_in_cset() const              { return _value > NotInCSet; }
-
-  bool is_humongous() const            { return _value == Humongous; }
-  bool is_young() const                { return _value == Young; }
-  bool is_old() const                  { return _value == Old; }
-  bool is_optional() const             { return _value == Optional; }
-
-#ifdef ASSERT
-  bool is_default() const              { return _value == NotInCSet; }
-  bool is_valid() const                { return (_value >= Optional) && (_value < Num); }
-  bool is_valid_gen() const            { return (_value >= Young && _value <= Old); }
-#endif
-};
-
-// Instances of this class are used for quick tests on whether a reference points
-// into the collection set and into which generation or is a humongous object
-//
-// Each of the array's elements indicates whether the corresponding region is in
-// the collection set and if so in which generation, or a humongous region.
-//
-// We use this to speed up reference processing during young collection and
-// quickly reclaim humongous objects. For the latter, by making a humongous region
-// succeed this test, we sort-of add it to the collection set. During the reference
-// iteration closures, when we see a humongous region, we then simply mark it as
-// referenced, i.e. live.
-class G1InCSetStateFastTestBiasedMappedArray : public G1BiasedMappedArray<InCSetState> {
- protected:
-  InCSetState default_value() const { return InCSetState::NotInCSet; }
- public:
-  void set_optional(uintptr_t index) {
-    assert(get_by_index(index).is_default(),
-           "State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value());
-    set_by_index(index, InCSetState::Optional);
-  }
-
-  void set_humongous(uintptr_t index) {
-    assert(get_by_index(index).is_default(),
-           "State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value());
-    set_by_index(index, InCSetState::Humongous);
-  }
-
-  void clear_humongous(uintptr_t index) {
-    set_by_index(index, InCSetState::NotInCSet);
-  }
-
-  void set_in_young(uintptr_t index) {
-    assert(get_by_index(index).is_default(),
-           "State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value());
-    set_by_index(index, InCSetState::Young);
-  }
-
-  void set_in_old(uintptr_t index) {
-    assert(get_by_index(index).is_default(),
-           "State at index " INTPTR_FORMAT " should be default but is " CSETSTATE_FORMAT, index, get_by_index(index).value());
-    set_by_index(index, InCSetState::Old);
-  }
-
-  bool is_in_cset_or_humongous(HeapWord* addr) const { return at(addr).is_in_cset_or_humongous(); }
-  bool is_in_cset(HeapWord* addr) const { return at(addr).is_in_cset(); }
-  bool is_in_cset(const HeapRegion* hr) const { return get_by_index(hr->hrm_index()).is_in_cset(); }
-  InCSetState at(HeapWord* addr) const { return get_by_address(addr); }
-  void clear() { G1BiasedMappedArray<InCSetState>::clear(); }
-  void clear(const HeapRegion* hr) { return set_by_index(hr->hrm_index(), InCSetState::NotInCSet); }
-};
-
-#endif // SHARE_GC_G1_G1INCSETSTATE_HPP
--- a/src/hotspot/share/gc/g1/g1OopClosures.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1OopClosures.hpp	Wed May 15 13:54:43 2019 +0530
@@ -25,7 +25,7 @@
 #ifndef SHARE_GC_G1_G1OOPCLOSURES_HPP
 #define SHARE_GC_G1_G1OOPCLOSURES_HPP
 
-#include "gc/g1/g1InCSetState.hpp"
+#include "gc/g1/g1HeapRegionAttr.hpp"
 #include "memory/iterator.hpp"
 #include "oops/markOop.hpp"
 
@@ -52,18 +52,18 @@
   inline void prefetch_and_push(T* p, oop const obj);
 
   template <class T>
-  inline void handle_non_cset_obj_common(InCSetState const state, T* p, oop const obj);
+  inline void handle_non_cset_obj_common(G1HeapRegionAttr const region_attr, T* p, oop const obj);
 public:
   virtual ReferenceIterationMode reference_iteration_mode() { return DO_FIELDS; }
 
   inline void trim_queue_partially();
 };
 
-// Used during the Update RS phase to refine remaining cards in the DCQ during garbage collection.
-class G1ScanObjsDuringUpdateRSClosure : public G1ScanClosureBase {
+// Used to scan cards from the DCQS or the remembered sets during garbage collection.
+class G1ScanCardClosure : public G1ScanClosureBase {
 public:
-  G1ScanObjsDuringUpdateRSClosure(G1CollectedHeap* g1h,
-                                  G1ParScanThreadState* pss) :
+  G1ScanCardClosure(G1CollectedHeap* g1h,
+                    G1ParScanThreadState* pss) :
     G1ScanClosureBase(g1h, pss) { }
 
   template <class T> void do_oop_work(T* p);
@@ -71,23 +71,11 @@
   virtual void do_oop(oop* p)       { do_oop_work(p); }
 };
 
-// Used during the Scan RS phase to scan cards from the remembered set during garbage collection.
-class G1ScanObjsDuringScanRSClosure : public G1ScanClosureBase {
-public:
-  G1ScanObjsDuringScanRSClosure(G1CollectedHeap* g1h,
-                                G1ParScanThreadState* par_scan_state):
-    G1ScanClosureBase(g1h, par_scan_state) { }
-
-  template <class T> void do_oop_work(T* p);
-  virtual void do_oop(oop* p)          { do_oop_work(p); }
-  virtual void do_oop(narrowOop* p)    { do_oop_work(p); }
-};
-
 // Used during Optional RS scanning to make sure we trim the queues in a timely manner.
 class G1ScanRSForOptionalClosure : public OopClosure {
-  G1ScanObjsDuringScanRSClosure* _scan_cl;
+  G1ScanCardClosure* _scan_cl;
 public:
-  G1ScanRSForOptionalClosure(G1ScanObjsDuringScanRSClosure* cl) : _scan_cl(cl) { }
+  G1ScanRSForOptionalClosure(G1ScanCardClosure* cl) : _scan_cl(cl) { }
 
   template <class T> void do_oop_work(T* p);
   virtual void do_oop(oop* p)          { do_oop_work(p); }
--- a/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1OopClosures.inline.hpp	Wed May 15 13:54:43 2019 +0530
@@ -61,10 +61,10 @@
 }
 
 template <class T>
-inline void G1ScanClosureBase::handle_non_cset_obj_common(InCSetState const state, T* p, oop const obj) {
-  if (state.is_humongous()) {
+inline void G1ScanClosureBase::handle_non_cset_obj_common(G1HeapRegionAttr const region_attr, T* p, oop const obj) {
+  if (region_attr.is_humongous()) {
     _g1h->set_humongous_is_live(obj);
-  } else if (state.is_optional()) {
+  } else if (region_attr.is_optional()) {
     _par_scan_state->remember_reference_into_optional_region(p);
   }
 }
@@ -81,16 +81,16 @@
     return;
   }
   oop obj = CompressedOops::decode_not_null(heap_oop);
-  const InCSetState state = _g1h->in_cset_state(obj);
-  if (state.is_in_cset()) {
+  const G1HeapRegionAttr region_attr = _g1h->region_attr(obj);
+  if (region_attr.is_in_cset()) {
     prefetch_and_push(p, obj);
   } else if (!HeapRegion::is_in_same_region(p, obj)) {
-    handle_non_cset_obj_common(state, p, obj);
+    handle_non_cset_obj_common(region_attr, p, obj);
     assert(_scanning_in_young != Uninitialized, "Scan location has not been initialized.");
     if (_scanning_in_young == True) {
       return;
     }
-    _par_scan_state->enqueue_card_if_tracked(p, obj);
+    _par_scan_state->enqueue_card_if_tracked(region_attr, p, obj);
   }
 }
 
@@ -160,7 +160,7 @@
 }
 
 template <class T>
-inline void G1ScanObjsDuringUpdateRSClosure::do_oop_work(T* p) {
+inline void G1ScanCardClosure::do_oop_work(T* p) {
   T o = RawAccess<>::oop_load(p);
   if (CompressedOops::is_null(o)) {
     return;
@@ -169,31 +169,15 @@
 
   check_obj_during_refinement(p, obj);
 
-  assert(!_g1h->is_in_cset((HeapWord*)p), "Oop originates from " PTR_FORMAT " (region: %u) which is in the collection set.", p2i(p), _g1h->addr_to_region((HeapWord*)p));
-  const InCSetState state = _g1h->in_cset_state(obj);
-  if (state.is_in_cset()) {
-    // Since the source is always from outside the collection set, here we implicitly know
-    // that this is a cross-region reference too.
+  // We can not check for references from the collection set: the remembered sets
+  // may contain such entries and we do not filter them before.
+
+  const G1HeapRegionAttr region_attr = _g1h->region_attr(obj);
+  if (region_attr.is_in_cset()) {
     prefetch_and_push(p, obj);
   } else if (!HeapRegion::is_in_same_region(p, obj)) {
-    handle_non_cset_obj_common(state, p, obj);
-    _par_scan_state->enqueue_card_if_tracked(p, obj);
-  }
-}
-
-template <class T>
-inline void G1ScanObjsDuringScanRSClosure::do_oop_work(T* p) {
-  T heap_oop = RawAccess<>::oop_load(p);
-  if (CompressedOops::is_null(heap_oop)) {
-    return;
-  }
-  oop obj = CompressedOops::decode_not_null(heap_oop);
-
-  const InCSetState state = _g1h->in_cset_state(obj);
-  if (state.is_in_cset()) {
-    prefetch_and_push(p, obj);
-  } else if (!HeapRegion::is_in_same_region(p, obj)) {
-    handle_non_cset_obj_common(state, p, obj);
+    handle_non_cset_obj_common(region_attr, p, obj);
+    _par_scan_state->enqueue_card_if_tracked(region_attr, p, obj);
   }
 }
 
@@ -233,7 +217,7 @@
 
   assert(_worker_id == _par_scan_state->worker_id(), "sanity");
 
-  const InCSetState state = _g1h->in_cset_state(obj);
+  const G1HeapRegionAttr state = _g1h->region_attr(obj);
   if (state.is_in_cset()) {
     oop forwardee;
     markOop m = obj->mark_raw();
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.cpp	Wed May 15 13:54:43 2019 +0530
@@ -75,11 +75,11 @@
 
   _plab_allocator = new G1PLABAllocator(_g1h->allocator());
 
-  _dest[InCSetState::NotInCSet]    = InCSetState::NotInCSet;
+  _dest[G1HeapRegionAttr::NotInCSet] = G1HeapRegionAttr::NotInCSet;
   // The dest for Young is used when the objects are aged enough to
   // need to be moved to the next space.
-  _dest[InCSetState::Young]        = InCSetState::Old;
-  _dest[InCSetState::Old]          = InCSetState::Old;
+  _dest[G1HeapRegionAttr::Young] = G1HeapRegionAttr::Old;
+  _dest[G1HeapRegionAttr::Old]   = G1HeapRegionAttr::Old;
 
   _closures = G1EvacuationRootClosures::create_root_closures(this, _g1h);
 
@@ -157,18 +157,18 @@
   } while (!_refs->is_empty());
 }
 
-HeapWord* G1ParScanThreadState::allocate_in_next_plab(InCSetState const state,
-                                                      InCSetState* dest,
+HeapWord* G1ParScanThreadState::allocate_in_next_plab(G1HeapRegionAttr const region_attr,
+                                                      G1HeapRegionAttr* dest,
                                                       size_t word_sz,
                                                       bool previous_plab_refill_failed) {
-  assert(state.is_in_cset_or_humongous(), "Unexpected state: " CSETSTATE_FORMAT, state.value());
-  assert(dest->is_in_cset_or_humongous(), "Unexpected dest: " CSETSTATE_FORMAT, dest->value());
+  assert(region_attr.is_in_cset_or_humongous(), "Unexpected region attr type: %s", region_attr.get_type_str());
+  assert(dest->is_in_cset_or_humongous(), "Unexpected dest: %s region attr", dest->get_type_str());
 
   // Right now we only have two types of regions (young / old) so
   // let's keep the logic here simple. We can generalize it when necessary.
   if (dest->is_young()) {
     bool plab_refill_in_old_failed = false;
-    HeapWord* const obj_ptr = _plab_allocator->allocate(InCSetState::Old,
+    HeapWord* const obj_ptr = _plab_allocator->allocate(G1HeapRegionAttr::Old,
                                                         word_sz,
                                                         &plab_refill_in_old_failed);
     // Make sure that we won't attempt to copy any other objects out
@@ -190,38 +190,38 @@
     return obj_ptr;
   } else {
     _old_gen_is_full = previous_plab_refill_failed;
-    assert(dest->is_old(), "Unexpected dest: " CSETSTATE_FORMAT, dest->value());
+    assert(dest->is_old(), "Unexpected dest region attr: %s", dest->get_type_str());
     // no other space to try.
     return NULL;
   }
 }
 
-InCSetState G1ParScanThreadState::next_state(InCSetState const state, markOop const m, uint& age) {
-  if (state.is_young()) {
+G1HeapRegionAttr G1ParScanThreadState::next_region_attr(G1HeapRegionAttr const region_attr, markOop const m, uint& age) {
+  if (region_attr.is_young()) {
     age = !m->has_displaced_mark_helper() ? m->age()
                                           : m->displaced_mark_helper()->age();
     if (age < _tenuring_threshold) {
-      return state;
+      return region_attr;
     }
   }
-  return dest(state);
+  return dest(region_attr);
 }
 
-void G1ParScanThreadState::report_promotion_event(InCSetState const dest_state,
+void G1ParScanThreadState::report_promotion_event(G1HeapRegionAttr const dest_attr,
                                                   oop const old, size_t word_sz, uint age,
                                                   HeapWord * const obj_ptr) const {
-  PLAB* alloc_buf = _plab_allocator->alloc_buffer(dest_state);
+  PLAB* alloc_buf = _plab_allocator->alloc_buffer(dest_attr);
   if (alloc_buf->contains(obj_ptr)) {
     _g1h->_gc_tracer_stw->report_promotion_in_new_plab_event(old->klass(), word_sz * HeapWordSize, age,
-                                                             dest_state.value() == InCSetState::Old,
+                                                             dest_attr.type() == G1HeapRegionAttr::Old,
                                                              alloc_buf->word_sz() * HeapWordSize);
   } else {
     _g1h->_gc_tracer_stw->report_promotion_outside_plab_event(old->klass(), word_sz * HeapWordSize, age,
-                                                              dest_state.value() == InCSetState::Old);
+                                                              dest_attr.type() == G1HeapRegionAttr::Old);
   }
 }
 
-oop G1ParScanThreadState::copy_to_survivor_space(InCSetState const state,
+oop G1ParScanThreadState::copy_to_survivor_space(G1HeapRegionAttr const region_attr,
                                                  oop const old,
                                                  markOop const old_mark) {
   const size_t word_sz = old->size();
@@ -232,21 +232,21 @@
          (!from_region->is_young() && young_index == 0), "invariant" );
 
   uint age = 0;
-  InCSetState dest_state = next_state(state, old_mark, age);
+  G1HeapRegionAttr dest_attr = next_region_attr(region_attr, old_mark, age);
   // The second clause is to prevent premature evacuation failure in case there
   // is still space in survivor, but old gen is full.
-  if (_old_gen_is_full && dest_state.is_old()) {
+  if (_old_gen_is_full && dest_attr.is_old()) {
     return handle_evacuation_failure_par(old, old_mark);
   }
-  HeapWord* obj_ptr = _plab_allocator->plab_allocate(dest_state, word_sz);
+  HeapWord* obj_ptr = _plab_allocator->plab_allocate(dest_attr, word_sz);
 
   // PLAB allocations should succeed most of the time, so we'll
   // normally check against NULL once and that's it.
   if (obj_ptr == NULL) {
     bool plab_refill_failed = false;
-    obj_ptr = _plab_allocator->allocate_direct_or_new_plab(dest_state, word_sz, &plab_refill_failed);
+    obj_ptr = _plab_allocator->allocate_direct_or_new_plab(dest_attr, word_sz, &plab_refill_failed);
     if (obj_ptr == NULL) {
-      obj_ptr = allocate_in_next_plab(state, &dest_state, word_sz, plab_refill_failed);
+      obj_ptr = allocate_in_next_plab(region_attr, &dest_attr, word_sz, plab_refill_failed);
       if (obj_ptr == NULL) {
         // This will either forward-to-self, or detect that someone else has
         // installed a forwarding pointer.
@@ -255,7 +255,7 @@
     }
     if (_g1h->_gc_tracer_stw->should_report_promotion_events()) {
       // The events are checked individually as part of the actual commit
-      report_promotion_event(dest_state, old, word_sz, age, obj_ptr);
+      report_promotion_event(dest_attr, old, word_sz, age, obj_ptr);
     }
   }
 
@@ -267,7 +267,7 @@
   if (_g1h->evacuation_should_fail()) {
     // Doing this after all the allocation attempts also tests the
     // undo_allocation() method too.
-    _plab_allocator->undo_allocation(dest_state, obj_ptr, word_sz);
+    _plab_allocator->undo_allocation(dest_attr, obj_ptr, word_sz);
     return handle_evacuation_failure_par(old, old_mark);
   }
 #endif // !PRODUCT
@@ -280,7 +280,7 @@
   if (forward_ptr == NULL) {
     Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz);
 
-    if (dest_state.is_young()) {
+    if (dest_attr.is_young()) {
       if (age < markOopDesc::max_age) {
         age++;
       }
@@ -300,8 +300,8 @@
     }
 
     if (G1StringDedup::is_enabled()) {
-      const bool is_from_young = state.is_young();
-      const bool is_to_young = dest_state.is_young();
+      const bool is_from_young = region_attr.is_young();
+      const bool is_to_young = dest_attr.is_young();
       assert(is_from_young == _g1h->heap_region_containing(old)->is_young(),
              "sanity");
       assert(is_to_young == _g1h->heap_region_containing(obj)->is_young(),
@@ -322,12 +322,12 @@
       oop* old_p = set_partial_array_mask(old);
       do_oop_partial_array(old_p);
     } else {
-      G1ScanInYoungSetter x(&_scanner, dest_state.is_young());
+      G1ScanInYoungSetter x(&_scanner, dest_attr.is_young());
       obj->oop_iterate_backwards(&_scanner);
     }
     return obj;
   } else {
-    _plab_allocator->undo_allocation(dest_state, obj_ptr, word_sz);
+    _plab_allocator->undo_allocation(dest_attr, obj_ptr, word_sz);
     return forward_ptr;
   }
 }
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.hpp	Wed May 15 13:54:43 2019 +0530
@@ -45,17 +45,17 @@
 
 class G1ParScanThreadState : public CHeapObj<mtGC> {
   G1CollectedHeap* _g1h;
-  RefToScanQueue*  _refs;
+  RefToScanQueue* _refs;
   G1DirtyCardQueue _dcq;
-  G1CardTable*     _ct;
+  G1CardTable* _ct;
   G1EvacuationRootClosures* _closures;
 
-  G1PLABAllocator*  _plab_allocator;
+  G1PLABAllocator* _plab_allocator;
 
-  AgeTable          _age_table;
-  InCSetState       _dest[InCSetState::Num];
+  AgeTable _age_table;
+  G1HeapRegionAttr _dest[G1HeapRegionAttr::Num];
   // Local tenuring threshold.
-  uint              _tenuring_threshold;
+  uint _tenuring_threshold;
   G1ScanEvacuatedObjClosure  _scanner;
 
   uint _worker_id;
@@ -80,12 +80,12 @@
   G1DirtyCardQueue& dirty_card_queue()           { return _dcq; }
   G1CardTable* ct()                              { return _ct; }
 
-  InCSetState dest(InCSetState original) const {
+  G1HeapRegionAttr dest(G1HeapRegionAttr original) const {
     assert(original.is_valid(),
-           "Original state invalid: " CSETSTATE_FORMAT, original.value());
-    assert(_dest[original.value()].is_valid_gen(),
-           "Dest state is invalid: " CSETSTATE_FORMAT, _dest[original.value()].value());
-    return _dest[original.value()];
+           "Original region attr invalid: %s", original.get_type_str());
+    assert(_dest[original.type()].is_valid_gen(),
+           "Dest region attr is invalid: %s", _dest[original.type()].get_type_str());
+    return _dest[original.type()];
   }
 
   size_t _num_optional_regions;
@@ -111,10 +111,19 @@
   template <class T> void do_oop_ext(T* ref);
   template <class T> void push_on_queue(T* ref);
 
-  template <class T> void enqueue_card_if_tracked(T* p, oop o) {
+  template <class T> void enqueue_card_if_tracked(G1HeapRegionAttr region_attr, T* p, oop o) {
     assert(!HeapRegion::is_in_same_region(p, o), "Should have filtered out cross-region references already.");
     assert(!_g1h->heap_region_containing(p)->is_young(), "Should have filtered out from-young references already.");
-    if (!_g1h->heap_region_containing((HeapWord*)o)->rem_set()->is_tracked()) {
+
+#ifdef ASSERT
+    HeapRegion* const hr_obj = _g1h->heap_region_containing((HeapWord*)o);
+    assert(region_attr.needs_remset_update() == hr_obj->rem_set()->is_tracked(),
+           "State flag indicating remset tracking disagrees (%s) with actual remembered set (%s) for region %u",
+           BOOL_TO_STR(region_attr.needs_remset_update()),
+           BOOL_TO_STR(hr_obj->rem_set()->is_tracked()),
+           hr_obj->hrm_index());
+#endif
+    if (!region_attr.needs_remset_update()) {
       return;
     }
     size_t card_index = ct()->index_for(p);
@@ -184,14 +193,14 @@
   // Returns a non-NULL pointer if successful, and updates dest if required.
   // Also determines whether we should continue to try to allocate into the various
   // generations or just end trying to allocate.
-  HeapWord* allocate_in_next_plab(InCSetState const state,
-                                  InCSetState* dest,
+  HeapWord* allocate_in_next_plab(G1HeapRegionAttr const region_attr,
+                                  G1HeapRegionAttr* dest,
                                   size_t word_sz,
                                   bool previous_plab_refill_failed);
 
-  inline InCSetState next_state(InCSetState const state, markOop const m, uint& age);
+  inline G1HeapRegionAttr next_region_attr(G1HeapRegionAttr const region_attr, markOop const m, uint& age);
 
-  void report_promotion_event(InCSetState const dest_state,
+  void report_promotion_event(G1HeapRegionAttr const dest_attr,
                               oop const old, size_t word_sz, uint age,
                               HeapWord * const obj_ptr) const;
 
@@ -200,7 +209,7 @@
 
   inline void trim_queue_to_threshold(uint threshold);
 public:
-  oop copy_to_survivor_space(InCSetState const state, oop const obj, markOop const old_mark);
+  oop copy_to_survivor_space(G1HeapRegionAttr const region_attr, oop const obj, markOop const old_mark);
 
   void trim_queue();
   void trim_queue_partially();
--- a/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1ParScanThreadState.inline.hpp	Wed May 15 13:54:43 2019 +0530
@@ -41,14 +41,14 @@
   // than one thread might claim the same card. So the same card may be
   // processed multiple times, and so we might get references into old gen here.
   // So we need to redo this check.
-  const InCSetState in_cset_state = _g1h->in_cset_state(obj);
+  const G1HeapRegionAttr region_attr = _g1h->region_attr(obj);
   // References pushed onto the work stack should never point to a humongous region
   // as they are not added to the collection set due to above precondition.
-  assert(!in_cset_state.is_humongous(),
+  assert(!region_attr.is_humongous(),
          "Obj " PTR_FORMAT " should not refer to humongous region %u from " PTR_FORMAT,
          p2i(obj), _g1h->addr_to_region((HeapWord*)obj), p2i(p));
 
-  if (!in_cset_state.is_in_cset()) {
+  if (!region_attr.is_in_cset()) {
     // In this case somebody else already did all the work.
     return;
   }
@@ -57,7 +57,7 @@
   if (m->is_marked()) {
     obj = (oop) m->decode_pointer();
   } else {
-    obj = copy_to_survivor_space(in_cset_state, obj, m);
+    obj = copy_to_survivor_space(region_attr, obj, m);
   }
   RawAccess<IS_NOT_NULL>::oop_store(p, obj);
 
@@ -67,7 +67,7 @@
   }
   HeapRegion* from = _g1h->heap_region_containing(p);
   if (!from->is_young()) {
-    enqueue_card_if_tracked(p, obj);
+    enqueue_card_if_tracked(_g1h->region_attr(obj), p, obj);
   }
 }
 
--- a/src/hotspot/share/gc/g1/g1Policy.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1Policy.hpp	Wed May 15 13:54:43 2019 +0530
@@ -27,7 +27,7 @@
 
 #include "gc/g1/g1CollectorState.hpp"
 #include "gc/g1/g1GCPhaseTimes.hpp"
-#include "gc/g1/g1InCSetState.hpp"
+#include "gc/g1/g1HeapRegionAttr.hpp"
 #include "gc/g1/g1InitialMarkToMixedTimeTracker.hpp"
 #include "gc/g1/g1MMUTracker.hpp"
 #include "gc/g1/g1RemSetTrackingPolicy.hpp"
--- a/src/hotspot/share/gc/g1/g1RemSet.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1RemSet.cpp	Wed May 15 13:54:43 2019 +0530
@@ -305,7 +305,7 @@
 }
 
 G1ScanRSForRegionClosure::G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
-                                                   G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
+                                                   G1ScanCardClosure* scan_obj_on_card,
                                                    G1ParScanThreadState* pss,
                                                    G1GCPhaseTimes::GCParPhases phase,
                                                    uint worker_i) :
@@ -345,7 +345,7 @@
 
   G1OopStarChunkedList* opt_rem_set_list = _pss->oops_into_optional_region(r);
 
-  G1ScanObjsDuringScanRSClosure scan_cl(_g1h, _pss);
+  G1ScanCardClosure scan_cl(_g1h, _pss);
   G1ScanRSForOptionalClosure cl(&scan_cl);
   _opt_refs_scanned += opt_rem_set_list->oops_do(&cl, _pss->closures()->raw_strong_oops());
   _opt_refs_memory_used += opt_rem_set_list->used_memory();
@@ -464,7 +464,7 @@
                             G1GCPhaseTimes::GCParPhases coderoots_phase) {
   assert(pss->trim_ticks().value() == 0, "Queues must have been trimmed before entering.");
 
-  G1ScanObjsDuringScanRSClosure scan_cl(_g1h, pss);
+  G1ScanCardClosure scan_cl(_g1h, pss);
   G1ScanRSForRegionClosure cl(_scan_state, &scan_cl, pss, scan_phase, worker_i);
   _g1h->collection_set_iterate_increment_from(&cl, worker_i);
 
@@ -489,12 +489,12 @@
 // Closure used for updating rem sets. Only called during an evacuation pause.
 class G1RefineCardClosure: public G1CardTableEntryClosure {
   G1RemSet* _g1rs;
-  G1ScanObjsDuringUpdateRSClosure* _update_rs_cl;
+  G1ScanCardClosure* _update_rs_cl;
 
   size_t _cards_scanned;
   size_t _cards_skipped;
 public:
-  G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanObjsDuringUpdateRSClosure* update_rs_cl) :
+  G1RefineCardClosure(G1CollectedHeap* g1h, G1ScanCardClosure* update_rs_cl) :
     _g1rs(g1h->rem_set()), _update_rs_cl(update_rs_cl), _cards_scanned(0), _cards_skipped(0)
   {}
 
@@ -527,7 +527,7 @@
   if (G1HotCardCache::default_use_cache()) {
     G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::ScanHCC, worker_i);
 
-    G1ScanObjsDuringUpdateRSClosure scan_hcc_cl(_g1h, pss);
+    G1ScanCardClosure scan_hcc_cl(_g1h, pss);
     G1RefineCardClosure refine_card_cl(_g1h, &scan_hcc_cl);
     _g1h->iterate_hcc_closure(&refine_card_cl, worker_i);
   }
@@ -536,7 +536,7 @@
   {
     G1EvacPhaseTimesTracker x(p, pss, G1GCPhaseTimes::UpdateRS, worker_i);
 
-    G1ScanObjsDuringUpdateRSClosure update_rs_cl(_g1h, pss);
+    G1ScanCardClosure update_rs_cl(_g1h, pss);
     G1RefineCardClosure refine_card_cl(_g1h, &update_rs_cl);
     _g1h->iterate_dirty_card_closure(&refine_card_cl, worker_i);
 
@@ -545,12 +545,12 @@
   }
 }
 
-void G1RemSet::prepare_for_oops_into_collection_set_do() {
+void G1RemSet::prepare_for_scan_rem_set() {
   G1BarrierSet::dirty_card_queue_set().concatenate_logs();
   _scan_state->reset();
 }
 
-void G1RemSet::cleanup_after_oops_into_collection_set_do() {
+void G1RemSet::cleanup_after_scan_rem_set() {
   G1GCPhaseTimes* phase_times = _g1h->phase_times();
 
   // Set all cards back to clean.
@@ -712,7 +712,7 @@
 }
 
 bool G1RemSet::refine_card_during_gc(CardValue* card_ptr,
-                                     G1ScanObjsDuringUpdateRSClosure* update_rs_cl) {
+                                     G1ScanCardClosure* update_rs_cl) {
   assert(_g1h->is_gc_active(), "Only call during GC");
 
   // Construct the region representing the card.
--- a/src/hotspot/share/gc/g1/g1RemSet.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/g1/g1RemSet.hpp	Wed May 15 13:54:43 2019 +0530
@@ -47,8 +47,7 @@
 class G1RemSetScanState;
 class G1ParScanThreadState;
 class G1Policy;
-class G1ScanObjsDuringScanRSClosure;
-class G1ScanObjsDuringUpdateRSClosure;
+class G1ScanCardClosure;
 class HeapRegionClaimer;
 
 // A G1RemSet in which each heap region has a rem set that records the
@@ -99,11 +98,10 @@
   // into the collection set or update the remembered set.
   void update_rem_set(G1ParScanThreadState* pss, uint worker_i);
 
-  // Prepare for and cleanup after an oops_into_collection_set_do
-  // call.  Must call each of these once before and after (in sequential
-  // code) any thread calls oops_into_collection_set_do.
-  void prepare_for_oops_into_collection_set_do();
-  void cleanup_after_oops_into_collection_set_do();
+  // Prepare for and cleanup after scanning the remembered sets.  Must be called
+  // once before and after in sequential code.
+  void prepare_for_scan_rem_set();
+  void cleanup_after_scan_rem_set();
 
   G1RemSetScanState* scan_state() const { return _scan_state; }
 
@@ -115,7 +113,7 @@
   // Refine the card corresponding to "card_ptr", applying the given closure to
   // all references found. Must only be called during gc.
   // Returns whether the card has been scanned.
-  bool refine_card_during_gc(CardValue* card_ptr, G1ScanObjsDuringUpdateRSClosure* update_rs_cl);
+  bool refine_card_during_gc(CardValue* card_ptr, G1ScanCardClosure* update_rs_cl);
 
   // Print accumulated summary info from the start of the VM.
   void print_summary_info();
@@ -135,7 +133,7 @@
   G1CardTable *_ct;
 
   G1ParScanThreadState* _pss;
-  G1ScanObjsDuringScanRSClosure* _scan_objs_on_card_cl;
+  G1ScanCardClosure* _scan_objs_on_card_cl;
 
   G1RemSetScanState* _scan_state;
 
@@ -164,7 +162,7 @@
   void scan_strong_code_roots(HeapRegion* r);
 public:
   G1ScanRSForRegionClosure(G1RemSetScanState* scan_state,
-                           G1ScanObjsDuringScanRSClosure* scan_obj_on_card,
+                           G1ScanCardClosure* scan_obj_on_card,
                            G1ParScanThreadState* pss,
                            G1GCPhaseTimes::GCParPhases phase,
                            uint worker_i);
--- a/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp	Wed May 15 13:54:43 2019 +0530
@@ -43,7 +43,7 @@
     ShenandoahStore,
     ShenandoahValue,
     ShenandoahOopStore,
-    ShenandoahNone,
+    ShenandoahNone
   };
 
   static bool verify_helper(Node* in, Node_Stack& phis, VectorSet& visited, verify_type t, bool trace, Unique_Node_List& barriers_used);
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp	Wed May 15 13:54:43 2019 +0530
@@ -73,9 +73,9 @@
   // ShenandoahGarbageThreshold is the soft threshold which would be ignored until min_garbage is hit.
 
   size_t capacity    = ShenandoahHeap::heap()->max_capacity();
-  size_t free_target = ShenandoahMinFreeThreshold * capacity / 100;
+  size_t free_target = capacity / 100 * ShenandoahMinFreeThreshold;
   size_t min_garbage = free_target > actual_free ? (free_target - actual_free) : 0;
-  size_t max_cset    = (size_t)(1.0 * ShenandoahEvacReserve * capacity / 100 / ShenandoahEvacWaste);
+  size_t max_cset    = (size_t)((1.0 * capacity / 100 * ShenandoahEvacReserve) / ShenandoahEvacWaste);
 
   log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "M, Actual Free: "
                      SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M, Min Garbage: " SIZE_FORMAT "M",
@@ -128,7 +128,7 @@
 
   // Check if we are falling below the worst limit, time to trigger the GC, regardless of
   // anything else.
-  size_t min_threshold = ShenandoahMinFreeThreshold * heap->max_capacity() / 100;
+  size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold;
   if (available < min_threshold) {
     log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below minimum threshold (" SIZE_FORMAT "M)",
                  available / M, min_threshold / M);
@@ -138,7 +138,7 @@
   // Check if are need to learn a bit about the application
   const size_t max_learn = ShenandoahLearningSteps;
   if (_gc_times_learned < max_learn) {
-    size_t init_threshold = ShenandoahInitFreeThreshold * heap->max_capacity() / 100;
+    size_t init_threshold = capacity / 100 * ShenandoahInitFreeThreshold;
     if (available < init_threshold) {
       log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "M) is below initial threshold (" SIZE_FORMAT "M)",
                    _gc_times_learned + 1, max_learn, available / M, init_threshold / M);
@@ -152,8 +152,8 @@
 
   size_t allocation_headroom = available;
 
-  size_t spike_headroom = ShenandoahAllocSpikeFactor * capacity / 100;
-  size_t penalties      = _gc_time_penalties         * capacity / 100;
+  size_t spike_headroom = capacity / 100 * ShenandoahAllocSpikeFactor;
+  size_t penalties      = capacity / 100 * _gc_time_penalties;
 
   allocation_headroom -= MIN2(allocation_headroom, spike_headroom);
   allocation_headroom -= MIN2(allocation_headroom, penalties);
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp	Wed May 15 13:54:43 2019 +0530
@@ -52,9 +52,11 @@
 bool ShenandoahCompactHeuristics::should_start_normal_gc() const {
   ShenandoahHeap* heap = ShenandoahHeap::heap();
 
+  size_t capacity = heap->max_capacity();
   size_t available = heap->free_set()->available();
-  size_t threshold_bytes_allocated = heap->max_capacity() * ShenandoahAllocationThreshold / 100;
-  size_t min_threshold = ShenandoahMinFreeThreshold * heap->max_capacity() / 100;
+
+  size_t threshold_bytes_allocated = capacity / 100 * ShenandoahAllocationThreshold;
+  size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold;
 
   if (available < min_threshold) {
     log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below minimum threshold (" SIZE_FORMAT "M)",
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahPassiveHeuristics.cpp	Wed May 15 13:54:43 2019 +0530
@@ -82,7 +82,7 @@
   // Do not select too large CSet that would overflow the available free space.
   // Take at least the entire evacuation reserve, and be free to overflow to free space.
   size_t capacity  = ShenandoahHeap::heap()->max_capacity();
-  size_t available = MAX2(ShenandoahEvacReserve * capacity / 100, actual_free);
+  size_t available = MAX2(capacity / 100 * ShenandoahEvacReserve, actual_free);
   size_t max_cset  = (size_t)(available / ShenandoahEvacWaste);
 
   log_info(gc, ergo)("CSet Selection. Actual Free: " SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M",
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp	Wed May 15 13:54:43 2019 +0530
@@ -54,7 +54,7 @@
 
   size_t capacity = heap->max_capacity();
   size_t available = heap->free_set()->available();
-  size_t threshold_available = (capacity * ShenandoahFreeThreshold) / 100;
+  size_t threshold_available = capacity / 100 * ShenandoahFreeThreshold;
 
   if (available < threshold_available) {
     log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below free threshold (" SIZE_FORMAT "M)",
--- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahTraversalHeuristics.cpp	Wed May 15 13:54:43 2019 +0530
@@ -119,9 +119,9 @@
 
   size_t capacity    = heap->max_capacity();
   size_t actual_free = heap->free_set()->available();
-  size_t free_target = ShenandoahMinFreeThreshold * capacity / 100;
+  size_t free_target = capacity / 100 * ShenandoahMinFreeThreshold;
   size_t min_garbage = free_target > actual_free ? (free_target - actual_free) : 0;
-  size_t max_cset    = (size_t)(1.0 * ShenandoahEvacReserve * capacity / 100 / ShenandoahEvacWaste);
+  size_t max_cset    = (size_t)((1.0 * capacity / 100 * ShenandoahEvacReserve) / ShenandoahEvacWaste);
 
   log_info(gc, ergo)("Adaptive CSet Selection. Target Free: " SIZE_FORMAT "M, Actual Free: "
                      SIZE_FORMAT "M, Max CSet: " SIZE_FORMAT "M, Min Garbage: " SIZE_FORMAT "M",
@@ -211,7 +211,7 @@
 
   // Check if we are falling below the worst limit, time to trigger the GC, regardless of
   // anything else.
-  size_t min_threshold = ShenandoahMinFreeThreshold * heap->max_capacity() / 100;
+  size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold;
   if (available < min_threshold) {
     log_info(gc)("Trigger: Free (" SIZE_FORMAT "M) is below minimum threshold (" SIZE_FORMAT "M)",
                  available / M, min_threshold / M);
@@ -221,7 +221,7 @@
   // Check if are need to learn a bit about the application
   const size_t max_learn = ShenandoahLearningSteps;
   if (_gc_times_learned < max_learn) {
-    size_t init_threshold = ShenandoahInitFreeThreshold * heap->max_capacity() / 100;
+    size_t init_threshold = capacity / 100 * ShenandoahInitFreeThreshold;
     if (available < init_threshold) {
       log_info(gc)("Trigger: Learning " SIZE_FORMAT " of " SIZE_FORMAT ". Free (" SIZE_FORMAT "M) is below initial threshold (" SIZE_FORMAT "M)",
                    _gc_times_learned + 1, max_learn, available / M, init_threshold / M);
@@ -235,8 +235,8 @@
 
   size_t allocation_headroom = available;
 
-  size_t spike_headroom = ShenandoahAllocSpikeFactor * capacity / 100;
-  size_t penalties      = _gc_time_penalties         * capacity / 100;
+  size_t spike_headroom = capacity / 100 * ShenandoahAllocSpikeFactor;
+  size_t penalties      = capacity / 100 * _gc_time_penalties;
 
   allocation_headroom -= MIN2(allocation_headroom, spike_headroom);
   allocation_headroom -= MIN2(allocation_headroom, penalties);
--- a/src/hotspot/share/gc/shenandoah/shenandoahAllocRequest.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahAllocRequest.hpp	Wed May 15 13:54:43 2019 +0530
@@ -33,7 +33,7 @@
     _alloc_shared_gc,   // Allocate common, outside of GCLAB
     _alloc_tlab,        // Allocate TLAB
     _alloc_gclab,       // Allocate GCLAB
-    _ALLOC_LIMIT,
+    _ALLOC_LIMIT
   };
 
   static const char* alloc_type_to_string(Type type) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp	Wed May 15 13:54:43 2019 +0530
@@ -204,7 +204,7 @@
 
 void ShenandoahArguments::initialize_alignments() {
   // Need to setup sizes early to get correct alignments.
-  ShenandoahHeapRegion::setup_sizes(InitialHeapSize, MaxHeapSize);
+  ShenandoahHeapRegion::setup_sizes(MaxHeapSize);
 
   // This is expected by our algorithm for ShenandoahHeap::heap_region_containing().
   size_t align = ShenandoahHeapRegion::region_size_bytes();
--- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.hpp	Wed May 15 13:54:43 2019 +0530
@@ -35,7 +35,7 @@
     _safe_unknown,
     _safe_oop,
     _safe_oop_fwd,
-    _safe_all,
+    _safe_all
   };
 
   static void print_obj(ShenandoahMessageBuffer &msg, oop obj);
--- a/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahBarrierSet.hpp	Wed May 15 13:54:43 2019 +0530
@@ -32,12 +32,13 @@
 class ShenandoahBarrierSetAssembler;
 
 class ShenandoahBarrierSet: public BarrierSet {
-private:
+public:
   enum ArrayCopyStoreValMode {
     NONE,
     READ_BARRIER,
     WRITE_BARRIER
   };
+private:
 
   ShenandoahHeap* _heap;
   ShenandoahSATBMarkQueueSet _satb_mark_queue_set;
--- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp	Wed May 15 13:54:43 2019 +0530
@@ -59,7 +59,7 @@
     concurrent_traversal,
     concurrent_normal,
     stw_degenerated,
-    stw_full,
+    stw_full
   } GCMode;
 
   // While we could have a single lock for these, it may risk unblocking
--- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp	Wed May 15 13:54:43 2019 +0530
@@ -430,7 +430,7 @@
   }
 
   // Evac reserve: reserve trailing space for evacuations
-  size_t to_reserve = ShenandoahEvacReserve * _heap->max_capacity() / 100;
+  size_t to_reserve = _heap->max_capacity() / 100 * ShenandoahEvacReserve;
   size_t reserved = 0;
 
   for (size_t idx = _heap->num_regions() - 1; idx > 0; idx--) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp	Wed May 15 13:54:43 2019 +0530
@@ -244,7 +244,7 @@
     UPDATEREFS_BITPOS = 3,
 
     // Heap is under traversal collection
-    TRAVERSAL_BITPOS  = 4,
+    TRAVERSAL_BITPOS  = 4
   };
 
   enum GCState {
@@ -253,7 +253,7 @@
     MARKING       = 1 << MARKING_BITPOS,
     EVACUATION    = 1 << EVACUATION_BITPOS,
     UPDATEREFS    = 1 << UPDATEREFS_BITPOS,
-    TRAVERSAL     = 1 << TRAVERSAL_BITPOS,
+    TRAVERSAL     = 1 << TRAVERSAL_BITPOS
   };
 
 private:
@@ -303,7 +303,7 @@
     _degenerated_mark,
     _degenerated_evac,
     _degenerated_updaterefs,
-    _DEGENERATED_LIMIT,
+    _DEGENERATED_LIMIT
   };
 
   static const char* degen_point_to_string(ShenandoahDegenPoint point) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp	Wed May 15 13:54:43 2019 +0530
@@ -516,7 +516,7 @@
   }
 }
 
-void ShenandoahHeapRegion::setup_sizes(size_t initial_heap_size, size_t max_heap_size) {
+void ShenandoahHeapRegion::setup_sizes(size_t max_heap_size) {
   // Absolute minimums we should not ever break.
   static const size_t MIN_REGION_SIZE = 256*K;
 
@@ -526,10 +526,10 @@
 
   size_t region_size;
   if (FLAG_IS_DEFAULT(ShenandoahHeapRegionSize)) {
-    if (ShenandoahMinRegionSize > initial_heap_size / MIN_NUM_REGIONS) {
-      err_msg message("Initial heap size (" SIZE_FORMAT "K) is too low to afford the minimum number "
+    if (ShenandoahMinRegionSize > max_heap_size / MIN_NUM_REGIONS) {
+      err_msg message("Max heap size (" SIZE_FORMAT "K) is too low to afford the minimum number "
                       "of regions (" SIZE_FORMAT ") of minimum region size (" SIZE_FORMAT "K).",
-                      initial_heap_size/K, MIN_NUM_REGIONS, ShenandoahMinRegionSize/K);
+                      max_heap_size/K, MIN_NUM_REGIONS, ShenandoahMinRegionSize/K);
       vm_exit_during_initialization("Invalid -XX:ShenandoahMinRegionSize option", message);
     }
     if (ShenandoahMinRegionSize < MIN_REGION_SIZE) {
@@ -562,10 +562,10 @@
     region_size = MIN2(ShenandoahMaxRegionSize, region_size);
 
   } else {
-    if (ShenandoahHeapRegionSize > initial_heap_size / MIN_NUM_REGIONS) {
-      err_msg message("Initial heap size (" SIZE_FORMAT "K) is too low to afford the minimum number "
+    if (ShenandoahHeapRegionSize > max_heap_size / MIN_NUM_REGIONS) {
+      err_msg message("Max heap size (" SIZE_FORMAT "K) is too low to afford the minimum number "
                               "of regions (" SIZE_FORMAT ") of requested size (" SIZE_FORMAT "K).",
-                      initial_heap_size/K, MIN_NUM_REGIONS, ShenandoahHeapRegionSize/K);
+                      max_heap_size/K, MIN_NUM_REGIONS, ShenandoahHeapRegionSize/K);
       vm_exit_during_initialization("Invalid -XX:ShenandoahHeapRegionSize option", message);
     }
     if (ShenandoahHeapRegionSize < ShenandoahMinRegionSize) {
--- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp	Wed May 15 13:54:43 2019 +0530
@@ -114,7 +114,7 @@
     _cset,                    // region is in collection set
     _pinned,                  // region is pinned
     _pinned_cset,             // region is pinned and in cset (evac failure path)
-    _trash,                   // region contains only trash
+    _trash                    // region contains only trash
   };
 
   const char* region_state_to_string(RegionState s) const {
@@ -257,7 +257,7 @@
 
   static const size_t MIN_NUM_REGIONS = 10;
 
-  static void setup_sizes(size_t initial_heap_size, size_t max_heap_size);
+  static void setup_sizes(size_t max_heap_size);
 
   double empty_time() {
     return _empty_time;
--- a/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahNumberSeq.hpp	Wed May 15 13:54:43 2019 +0530
@@ -39,7 +39,7 @@
   enum PrivateConstants {
     ValBuckets = 512,
     MagBuckets = 24,
-    MagMinimum = -12,
+    MagMinimum = -12
   };
   int** _hdr;
 
--- a/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahOopClosures.hpp	Wed May 15 13:54:43 2019 +0530
@@ -41,7 +41,7 @@
 
 enum StringDedupMode {
   NO_DEDUP,      // Do not do anything for String deduplication
-  ENQUEUE_DEDUP, // Enqueue candidate Strings for deduplication
+  ENQUEUE_DEDUP  // Enqueue candidate Strings for deduplication
 };
 
 class ShenandoahMarkRefsSuperClosure : public MetadataVisitingOopIterateClosure {
--- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp	Wed May 15 13:54:43 2019 +0530
@@ -153,7 +153,7 @@
 void ShenandoahPacer::setup_for_idle() {
   assert(ShenandoahPacing, "Only be here when pacing is enabled");
 
-  size_t initial = _heap->max_capacity() * ShenandoahPacingIdleSlack / 100;
+  size_t initial = _heap->max_capacity() / 100 * ShenandoahPacingIdleSlack;
   double tax = 1;
 
   restart_with(initial, tax);
--- a/src/hotspot/share/gc/shenandoah/shenandoahSharedVariables.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahSharedVariables.hpp	Wed May 15 13:54:43 2019 +0530
@@ -35,7 +35,7 @@
 typedef struct ShenandoahSharedFlag {
   enum {
     UNSET = 0,
-    SET = 1,
+    SET = 1
   };
 
   DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, sizeof(volatile ShenandoahSharedValue));
@@ -62,8 +62,8 @@
     return OrderAccess::load_acquire(&value) == UNSET;
   }
 
-  void set_cond(bool value) {
-    if (value) {
+  void set_cond(bool val) {
+    if (val) {
       set();
     } else {
       unset();
@@ -167,8 +167,8 @@
     return (OrderAccess::load_acquire(&value)) == 0;
   }
 
-  void set_cond(uint mask, bool value) {
-    if (value) {
+  void set_cond(uint mask, bool val) {
+    if (val) {
       set(mask);
     } else {
       unset(mask);
--- a/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahTaskqueue.hpp	Wed May 15 13:54:43 2019 +0530
@@ -125,12 +125,12 @@
   enum {
     chunk_bits   = 10,
     pow_bits     = 5,
-    oop_bits     = sizeof(uintptr_t)*8 - chunk_bits - pow_bits,
+    oop_bits     = sizeof(uintptr_t)*8 - chunk_bits - pow_bits
   };
   enum {
     oop_shift    = 0,
     pow_shift    = oop_shift + oop_bits,
-    chunk_shift  = pow_shift + pow_bits,
+    chunk_shift  = pow_shift + pow_bits
   };
 
 public:
--- a/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/shenandoah/shenandoahVerifier.hpp	Wed May 15 13:54:43 2019 +0530
@@ -73,7 +73,7 @@
     _verify_marked_incomplete,
 
     // Objects should be marked in "complete" bitmap.
-    _verify_marked_complete,
+    _verify_marked_complete
   } VerifyMarked;
 
   typedef enum {
@@ -84,7 +84,7 @@
     _verify_forwarded_none,
 
     // Objects may have forwardees.
-    _verify_forwarded_allow,
+    _verify_forwarded_allow
   } VerifyForwarded;
 
   typedef enum {
@@ -97,7 +97,7 @@
     // May have references to cset, all should be forwarded.
     // Note: Allowing non-forwarded references to cset is equivalent
     // to _verify_cset_disable.
-    _verify_cset_forwarded,
+    _verify_cset_forwarded
   } VerifyCollectionSet;
 
   typedef enum {
@@ -109,7 +109,7 @@
 
     // All objects should belong to live regions,
     // and liveness data should be accurate
-    _verify_liveness_complete,
+    _verify_liveness_complete
   } VerifyLiveness;
 
   typedef enum {
@@ -123,7 +123,7 @@
     _verify_regions_nocset,
 
     // No trash and no cset regions allowed
-    _verify_regions_notrash_nocset,
+    _verify_regions_notrash_nocset
   } VerifyRegions;
 
   typedef enum {
@@ -137,7 +137,7 @@
     _verify_gcstate_forwarded,
 
     // Evacuation is in progress, some objects are forwarded
-    _verify_gcstate_evacuation,
+    _verify_gcstate_evacuation
   } VerifyGCState;
 
   struct VerifyOptions {
--- a/src/hotspot/share/gc/z/vmStructs_z.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/vmStructs_z.hpp	Wed May 15 13:54:43 2019 +0530
@@ -30,7 +30,6 @@
 #include "gc/z/zGranuleMap.hpp"
 #include "gc/z/zHeap.hpp"
 #include "gc/z/zPageAllocator.hpp"
-#include "gc/z/zPhysicalMemory.hpp"
 #include "utilities/macros.hpp"
 
 // Expose some ZGC globals to the SA agent.
@@ -77,20 +76,18 @@
   nonstatic_field(ZPage,                        _virtual,             const ZVirtualMemory)          \
   volatile_nonstatic_field(ZPage,               _top,                 uintptr_t)                     \
                                                                                                      \
-  nonstatic_field(ZPageAllocator,               _physical,            ZPhysicalMemoryManager)        \
+  nonstatic_field(ZPageAllocator,               _max_capacity,        const size_t)                  \
+  nonstatic_field(ZPageAllocator,               _capacity,            size_t)                        \
   nonstatic_field(ZPageAllocator,               _used,                size_t)                        \
                                                                                                      \
   nonstatic_field(ZPageTable,                   _map,                 ZGranuleMapForPageTable)       \
                                                                                                      \
   nonstatic_field(ZGranuleMapForPageTable,      _map,                 ZPage** const)                 \
                                                                                                      \
-  nonstatic_field(ZVirtualMemory,               _start,               uintptr_t)                     \
-  nonstatic_field(ZVirtualMemory,               _end,                 uintptr_t)                     \
+  nonstatic_field(ZVirtualMemory,               _start,               const uintptr_t)               \
+  nonstatic_field(ZVirtualMemory,               _end,                 const uintptr_t)               \
                                                                                                      \
-  nonstatic_field(ZForwarding,                  _entries,             const ZAttachedArrayForForwarding) \
-                                                                                                     \
-  nonstatic_field(ZPhysicalMemoryManager,       _max_capacity,        const size_t)                  \
-  nonstatic_field(ZPhysicalMemoryManager,       _capacity,            size_t)
+  nonstatic_field(ZForwarding,                  _entries,             const ZAttachedArrayForForwarding)
 
 #define VM_INT_CONSTANTS_ZGC(declare_constant, declare_constant_with_value)                          \
   declare_constant(ZPhaseRelocate)                                                                   \
--- a/src/hotspot/share/gc/z/zCollectedHeap.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zCollectedHeap.cpp	Wed May 15 13:54:43 2019 +0530
@@ -48,6 +48,7 @@
     _heap(),
     _director(new ZDirector()),
     _driver(new ZDriver()),
+    _uncommitter(new ZUncommitter()),
     _stat(new ZStat()),
     _runtime_workers() {}
 
@@ -77,6 +78,7 @@
 void ZCollectedHeap::stop() {
   _director->stop();
   _driver->stop();
+  _uncommitter->stop();
   _stat->stop();
 }
 
@@ -272,6 +274,7 @@
 void ZCollectedHeap::gc_threads_do(ThreadClosure* tc) const {
   tc->do_thread(_director);
   tc->do_thread(_driver);
+  tc->do_thread(_uncommitter);
   tc->do_thread(_stat);
   _heap.worker_threads_do(tc);
   _runtime_workers.threads_do(tc);
@@ -331,6 +334,8 @@
   st->cr();
   _driver->print_on(st);
   st->cr();
+  _uncommitter->print_on(st);
+  st->cr();
   _stat->print_on(st);
   st->cr();
   _heap.print_worker_threads_on(st);
--- a/src/hotspot/share/gc/z/zCollectedHeap.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zCollectedHeap.hpp	Wed May 15 13:54:43 2019 +0530
@@ -29,10 +29,11 @@
 #include "gc/z/zBarrierSet.hpp"
 #include "gc/z/zDirector.hpp"
 #include "gc/z/zDriver.hpp"
+#include "gc/z/zHeap.hpp"
 #include "gc/z/zInitialize.hpp"
-#include "gc/z/zHeap.hpp"
 #include "gc/z/zRuntimeWorkers.hpp"
 #include "gc/z/zStat.hpp"
+#include "gc/z/zUncommitter.hpp"
 
 class ZCollectedHeap : public CollectedHeap {
   friend class VMStructs;
@@ -44,6 +45,7 @@
   ZHeap             _heap;
   ZDirector*        _director;
   ZDriver*          _driver;
+  ZUncommitter*     _uncommitter;
   ZStat*            _stat;
   ZRuntimeWorkers   _runtime_workers;
 
--- a/src/hotspot/share/gc/z/zHeap.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zHeap.cpp	Wed May 15 13:54:43 2019 +0530
@@ -22,6 +22,7 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/shared/gcArguments.hpp"
 #include "gc/shared/oopStorage.hpp"
 #include "gc/z/zAddress.hpp"
 #include "gc/z/zGlobals.hpp"
@@ -45,6 +46,7 @@
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
 #include "oops/oop.inline.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/safepoint.hpp"
 #include "runtime/thread.hpp"
 #include "utilities/align.hpp"
@@ -62,7 +64,7 @@
 ZHeap::ZHeap() :
     _workers(),
     _object_allocator(_workers.nworkers()),
-    _page_allocator(heap_min_size(), heap_max_size(), heap_max_reserve_size()),
+    _page_allocator(heap_min_size(), heap_initial_size(), heap_max_size(), heap_max_reserve_size()),
     _page_table(),
     _forwarding_table(),
     _mark(&_workers, &_page_table),
@@ -81,13 +83,15 @@
 }
 
 size_t ZHeap::heap_min_size() const {
-  const size_t aligned_min_size = align_up(InitialHeapSize, ZGranuleSize);
-  return MIN2(aligned_min_size, heap_max_size());
+  return MinHeapSize;
+}
+
+size_t ZHeap::heap_initial_size() const {
+  return InitialHeapSize;
 }
 
 size_t ZHeap::heap_max_size() const {
-  const size_t aligned_max_size = align_up(MaxHeapSize, ZGranuleSize);
-  return MIN2(aligned_max_size, ZAddressOffsetMax);
+  return MaxHeapSize;
 }
 
 size_t ZHeap::heap_max_reserve_size() const {
@@ -102,7 +106,7 @@
 }
 
 size_t ZHeap::min_capacity() const {
-  return heap_min_size();
+  return _page_allocator.min_capacity();
 }
 
 size_t ZHeap::max_capacity() const {
@@ -250,10 +254,14 @@
   _page_allocator.free_page(page, reclaimed);
 }
 
+uint64_t ZHeap::uncommit(uint64_t delay) {
+  return _page_allocator.uncommit(delay);
+}
+
 void ZHeap::before_flip() {
   if (ZVerifyViews) {
     // Unmap all pages
-    _page_allocator.unmap_all_pages();
+    _page_allocator.debug_unmap_all_pages();
   }
 }
 
@@ -262,8 +270,9 @@
     // Map all pages
     ZPageTableIterator iter(&_page_table);
     for (ZPage* page; iter.next(&page);) {
-      _page_allocator.map_page(page);
+      _page_allocator.debug_map_page(page);
     }
+    _page_allocator.debug_map_cached_pages();
   }
 }
 
--- a/src/hotspot/share/gc/z/zHeap.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zHeap.hpp	Wed May 15 13:54:43 2019 +0530
@@ -66,6 +66,7 @@
   ZServiceability     _serviceability;
 
   size_t heap_min_size() const;
+  size_t heap_initial_size() const;
   size_t heap_max_size() const;
   size_t heap_max_reserve_size() const;
 
@@ -129,6 +130,9 @@
   void undo_alloc_page(ZPage* page);
   void free_page(ZPage* page, bool reclaimed);
 
+  // Uncommit memory
+  uint64_t uncommit(uint64_t delay);
+
   // Object allocation
   uintptr_t alloc_tlab(size_t size);
   uintptr_t alloc_object(size_t size);
--- a/src/hotspot/share/gc/z/zList.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zList.hpp	Wed May 15 13:54:43 2019 +0530
@@ -210,11 +210,11 @@
 template <typename T, bool forward>
 class ZListIteratorImpl : public StackObj {
 private:
-  ZList<T>* const _list;
-  T*              _next;
+  const ZList<T>* const _list;
+  T*                    _next;
 
 public:
-  ZListIteratorImpl(ZList<T>* list);
+  ZListIteratorImpl(const ZList<T>* list);
 
   bool next(T** elem);
 };
@@ -226,14 +226,14 @@
 template <typename T>
 class ZListIterator : public ZListIteratorImpl<T, ZLIST_FORWARD> {
 public:
-  ZListIterator(ZList<T>* list) :
+  ZListIterator(const ZList<T>* list) :
       ZListIteratorImpl<T, ZLIST_FORWARD>(list) {}
 };
 
 template <typename T>
 class ZListReverseIterator : public ZListIteratorImpl<T, ZLIST_REVERSE> {
 public:
-  ZListReverseIterator(ZList<T>* list) :
+  ZListReverseIterator(const ZList<T>* list) :
       ZListIteratorImpl<T, ZLIST_REVERSE>(list) {}
 };
 
--- a/src/hotspot/share/gc/z/zList.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zList.inline.hpp	Wed May 15 13:54:43 2019 +0530
@@ -27,7 +27,7 @@
 #include "gc/z/zList.hpp"
 
 template <typename T, bool forward>
-ZListIteratorImpl<T, forward>::ZListIteratorImpl(ZList<T>* list) :
+ZListIteratorImpl<T, forward>::ZListIteratorImpl(const ZList<T>* list) :
     _list(list),
     _next(forward ? list->first() : list->last()) {}
 
--- a/src/hotspot/share/gc/z/zLiveMap.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zLiveMap.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,15 +34,19 @@
 static const ZStatCounter ZCounterMarkSeqNumResetContention("Contention", "Mark SeqNum Reset Contention", ZStatUnitOpsPerSecond);
 static const ZStatCounter ZCounterMarkSegmentResetContention("Contention", "Mark Segment Reset Contention", ZStatUnitOpsPerSecond);
 
+static size_t bitmap_size(uint32_t size, size_t nsegments) {
+  // We need at least one bit per segment
+  return MAX2<size_t>(size, nsegments) * 2;
+}
+
 ZLiveMap::ZLiveMap(uint32_t size) :
     _seqnum(0),
     _live_objects(0),
     _live_bytes(0),
     _segment_live_bits(0),
     _segment_claim_bits(0),
-    // We need at least one bit per segment.
-    _bitmap(MAX2<size_t>(size, nsegments) * 2),
-    _shift(exact_log2(segment_size())) {}
+    _bitmap(bitmap_size(size, nsegments)),
+    _segment_shift(exact_log2(segment_size())) {}
 
 void ZLiveMap::reset(size_t index) {
   const uint32_t seqnum_initializing = (uint32_t)-1;
@@ -121,3 +125,11 @@
   const bool success = set_segment_live_atomic(segment);
   assert(success, "Should never fail");
 }
+
+void ZLiveMap::resize(uint32_t size) {
+  const size_t new_bitmap_size = bitmap_size(size, nsegments);
+  if (_bitmap.size() != new_bitmap_size) {
+    _bitmap.reinitialize(new_bitmap_size, false /* clear */);
+    _segment_shift = exact_log2(segment_size());
+  }
+}
--- a/src/hotspot/share/gc/z/zLiveMap.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zLiveMap.hpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,13 +35,13 @@
 private:
   static const size_t nsegments = 64;
 
-  volatile uint32_t _seqnum;              // Mark sequence number
-  volatile uint32_t _live_objects;        // Number of live objects
-  volatile size_t   _live_bytes;          // Number of live bytes
-  BitMap::bm_word_t _segment_live_bits;   // Segment live bits
-  BitMap::bm_word_t _segment_claim_bits;  // Segment claim bits
-  ZBitMap           _bitmap;              // Mark bitmap
-  const size_t      _shift;               // Segment shift
+  volatile uint32_t _seqnum;
+  volatile uint32_t _live_objects;
+  volatile size_t   _live_bytes;
+  BitMap::bm_word_t _segment_live_bits;
+  BitMap::bm_word_t _segment_claim_bits;
+  ZBitMap           _bitmap;
+  size_t            _segment_shift;
 
   const BitMapView segment_live_bits() const;
   const BitMapView segment_claim_bits() const;
@@ -72,6 +72,7 @@
   ZLiveMap(uint32_t size);
 
   void reset();
+  void resize(uint32_t size);
 
   bool is_marked() const;
 
--- a/src/hotspot/share/gc/z/zLiveMap.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zLiveMap.inline.hpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -92,7 +92,7 @@
 }
 
 inline BitMap::idx_t ZLiveMap::index_to_segment(BitMap::idx_t index) const {
-  return index >> _shift;
+  return index >> _segment_shift;
 }
 
 inline bool ZLiveMap::get(size_t index) const {
--- a/src/hotspot/share/gc/z/zMemory.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zMemory.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,30 @@
   return UINTPTR_MAX;
 }
 
+uintptr_t ZMemoryManager::alloc_from_front_at_most(size_t size, size_t* allocated) {
+  ZMemory* area = _freelist.first();
+  if (area != NULL) {
+    if (area->size() <= size) {
+      // Smaller than or equal to requested, remove area
+      const uintptr_t start = area->start();
+      *allocated = area->size();
+      _freelist.remove(area);
+      delete area;
+      return start;
+    } else {
+      // Larger than requested, shrink area
+      const uintptr_t start = area->start();
+      area->shrink_from_front(size);
+      *allocated = size;
+      return start;
+    }
+  }
+
+  // Out of memory
+  *allocated = 0;
+  return UINTPTR_MAX;
+}
+
 uintptr_t ZMemoryManager::alloc_from_back(size_t size) {
   ZListReverseIterator<ZMemory> iter(&_freelist);
   for (ZMemory* area; iter.next(&area);) {
@@ -71,6 +95,29 @@
   return UINTPTR_MAX;
 }
 
+uintptr_t ZMemoryManager::alloc_from_back_at_most(size_t size, size_t* allocated) {
+  ZMemory* area = _freelist.last();
+  if (area != NULL) {
+    if (area->size() <= size) {
+      // Smaller than or equal to requested, remove area
+      const uintptr_t start = area->start();
+      *allocated = area->size();
+      _freelist.remove(area);
+      delete area;
+      return start;
+    } else {
+      // Larger than requested, shrink area
+      area->shrink_from_back(size);
+      *allocated = size;
+      return area->end();
+    }
+  }
+
+  // Out of memory
+  *allocated = 0;
+  return UINTPTR_MAX;
+}
+
 void ZMemoryManager::free(uintptr_t start, size_t size) {
   assert(start != UINTPTR_MAX, "Invalid address");
   const uintptr_t end = start + size;
--- a/src/hotspot/share/gc/z/zMemory.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zMemory.hpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -54,7 +54,9 @@
 
 public:
   uintptr_t alloc_from_front(size_t size);
+  uintptr_t alloc_from_front_at_most(size_t size, size_t* allocated);
   uintptr_t alloc_from_back(size_t size);
+  uintptr_t alloc_from_back_at_most(size_t size, size_t* allocated);
   void free(uintptr_t start, size_t size);
 };
 
--- a/src/hotspot/share/gc/z/zPage.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPage.cpp	Wed May 15 13:54:43 2019 +0530
@@ -28,30 +28,72 @@
 #include "utilities/align.hpp"
 #include "utilities/debug.hpp"
 
-ZPage::ZPage(uint8_t type, ZVirtualMemory vmem, ZPhysicalMemory pmem) :
+ZPage::ZPage(const ZVirtualMemory& vmem, const ZPhysicalMemory& pmem) :
+    _type(type_from_size(vmem.size())),
+    _numa_id((uint8_t)-1),
+    _seqnum(0),
+    _virtual(vmem),
+    _top(start()),
+    _livemap(object_max_count()),
+    _last_used(0),
+    _physical(pmem) {
+  assert_initialized();
+}
+
+ZPage::ZPage(uint8_t type, const ZVirtualMemory& vmem, const ZPhysicalMemory& pmem) :
     _type(type),
     _numa_id((uint8_t)-1),
     _seqnum(0),
     _virtual(vmem),
     _top(start()),
     _livemap(object_max_count()),
+    _last_used(0),
     _physical(pmem) {
-  assert(!_physical.is_null(), "Should not be null");
-  assert(!_virtual.is_null(), "Should not be null");
-  assert((type == ZPageTypeSmall && size() == ZPageSizeSmall) ||
-         (type == ZPageTypeMedium && size() == ZPageSizeMedium) ||
-         (type == ZPageTypeLarge && is_aligned(size(), ZGranuleSize)),
-         "Page type/size mismatch");
+  assert_initialized();
 }
 
-ZPage::~ZPage() {
-  assert(_physical.is_null(), "Should be null");
+void ZPage::assert_initialized() const {
+  assert(!_virtual.is_null(), "Should not be null");
+  assert(!_physical.is_null(), "Should not be null");
+  assert((_type == ZPageTypeSmall && size() == ZPageSizeSmall) ||
+         (_type == ZPageTypeMedium && size() == ZPageSizeMedium) ||
+         (_type == ZPageTypeLarge && is_aligned(size(), ZGranuleSize)),
+         "Page type/size mismatch");
 }
 
 void ZPage::reset() {
   _seqnum = ZGlobalSeqNum;
   _top = start();
   _livemap.reset();
+  _last_used = 0;
+}
+
+ZPage* ZPage::retype(uint8_t type) {
+  assert(_type != type, "Invalid retype");
+  _type = type;
+  _livemap.resize(object_max_count());
+  return this;
+}
+
+ZPage* ZPage::split(size_t size) {
+  return split(type_from_size(size), size);
+}
+
+ZPage* ZPage::split(uint8_t type, size_t size) {
+  assert(_virtual.size() > size, "Invalid split");
+
+  // Resize this page, keep _numa_id, _seqnum, and _last_used
+  const ZVirtualMemory vmem = _virtual.split(size);
+  const ZPhysicalMemory pmem = _physical.split(size);
+  _type = type_from_size(_virtual.size());
+  _top = start();
+  _livemap.resize(object_max_count());
+
+  // Create new page, inherit _seqnum and _last_used
+  ZPage* const page = new ZPage(type, vmem, pmem);
+  page->_seqnum = _seqnum;
+  page->_last_used = _last_used;
+  return page;
 }
 
 void ZPage::print_on(outputStream* out) const {
--- a/src/hotspot/share/gc/z/zPage.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPage.hpp	Wed May 15 13:54:43 2019 +0530
@@ -35,26 +35,27 @@
   friend class ZList<ZPage>;
 
 private:
-  // Always hot
-  const uint8_t        _type;             // Page type
-  uint8_t              _numa_id;          // NUMA node affinity
-  uint32_t             _seqnum;           // Allocation sequence number
-  const ZVirtualMemory _virtual;          // Virtual start/end address
-  volatile uintptr_t   _top;              // Virtual top address
-  ZLiveMap             _livemap;          // Live map
+  uint8_t            _type;
+  uint8_t            _numa_id;
+  uint32_t           _seqnum;
+  ZVirtualMemory     _virtual;
+  volatile uintptr_t _top;
+  ZLiveMap           _livemap;
+  uint64_t           _last_used;
+  ZPhysicalMemory    _physical;
+  ZListNode<ZPage>   _node;
 
-  // Hot when relocated and cached
-  ZPhysicalMemory      _physical;         // Physical memory for page
-  ZListNode<ZPage>     _node;             // Page list node
+  void assert_initialized() const;
 
+  uint8_t type_from_size(size_t size) const;
   const char* type_to_string() const;
 
   bool is_object_marked(uintptr_t addr) const;
   bool is_object_strongly_marked(uintptr_t addr) const;
 
 public:
-  ZPage(uint8_t type, ZVirtualMemory vmem, ZPhysicalMemory pmem);
-  ~ZPage();
+  ZPage(const ZVirtualMemory& vmem, const ZPhysicalMemory& pmem);
+  ZPage(uint8_t type, const ZVirtualMemory& vmem, const ZPhysicalMemory& pmem);
 
   uint32_t object_max_count() const;
   size_t object_alignment_shift() const;
@@ -67,17 +68,10 @@
   uintptr_t top() const;
   size_t remaining() const;
 
-  uint8_t numa_id();
-
-  ZPhysicalMemory& physical_memory();
+  const ZPhysicalMemory& physical_memory() const;
   const ZVirtualMemory& virtual_memory() const;
 
-  void reset();
-
-  bool is_in(uintptr_t addr) const;
-
-  uintptr_t block_start(uintptr_t addr) const;
-  bool block_is_obj(uintptr_t addr) const;
+  uint8_t numa_id();
 
   bool is_allocating() const;
   bool is_relocatable() const;
@@ -85,6 +79,20 @@
   bool is_mapped() const;
   void set_pre_mapped();
 
+  uint64_t last_used() const;
+  void set_last_used();
+
+  void reset();
+
+  ZPage* retype(uint8_t type);
+  ZPage* split(size_t size);
+  ZPage* split(uint8_t type, size_t size);
+
+  bool is_in(uintptr_t addr) const;
+
+  uintptr_t block_start(uintptr_t addr) const;
+  bool block_is_obj(uintptr_t addr) const;
+
   bool is_marked() const;
   bool is_object_live(uintptr_t addr) const;
   bool is_object_strongly_live(uintptr_t addr) const;
--- a/src/hotspot/share/gc/z/zPage.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPage.inline.hpp	Wed May 15 13:54:43 2019 +0530
@@ -34,10 +34,23 @@
 #include "gc/z/zVirtualMemory.inline.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/atomic.hpp"
-#include "runtime/orderAccess.hpp"
+#include "runtime/os.hpp"
 #include "utilities/align.hpp"
 #include "utilities/debug.hpp"
 
+inline uint8_t ZPage::type_from_size(size_t size) const {
+  switch (size) {
+  case ZPageSizeSmall:
+    return ZPageTypeSmall;
+
+  case ZPageSizeMedium:
+    return ZPageTypeMedium;
+
+  default:
+    return ZPageTypeLarge;
+  }
+}
+
 inline const char* ZPage::type_to_string() const {
   switch (type()) {
   case ZPageTypeSmall:
@@ -116,7 +129,7 @@
   return end() - top();
 }
 
-inline ZPhysicalMemory& ZPage::physical_memory() {
+inline const ZPhysicalMemory& ZPage::physical_memory() const {
   return _physical;
 }
 
@@ -132,23 +145,6 @@
   return _numa_id;
 }
 
-inline bool ZPage::is_in(uintptr_t addr) const {
-  const uintptr_t offset = ZAddress::offset(addr);
-  return offset >= start() && offset < top();
-}
-
-inline uintptr_t ZPage::block_start(uintptr_t addr) const {
-  if (block_is_obj(addr)) {
-    return addr;
-  } else {
-    return ZAddress::good(top());
-  }
-}
-
-inline bool ZPage::block_is_obj(uintptr_t addr) const {
-  return ZAddress::offset(addr) < top();
-}
-
 inline bool ZPage::is_allocating() const {
   return _seqnum == ZGlobalSeqNum;
 }
@@ -168,6 +164,31 @@
   _seqnum = 1;
 }
 
+inline uint64_t ZPage::last_used() const {
+  return _last_used;
+}
+
+inline void ZPage::set_last_used() {
+  _last_used = os::elapsedTime();
+}
+
+inline bool ZPage::is_in(uintptr_t addr) const {
+  const uintptr_t offset = ZAddress::offset(addr);
+  return offset >= start() && offset < top();
+}
+
+inline uintptr_t ZPage::block_start(uintptr_t addr) const {
+  if (block_is_obj(addr)) {
+    return addr;
+  } else {
+    return ZAddress::good(top());
+  }
+}
+
+inline bool ZPage::block_is_obj(uintptr_t addr) const {
+  return ZAddress::offset(addr) < top();
+}
+
 inline bool ZPage::is_marked() const {
   assert(is_relocatable(), "Invalid page state");
   return _livemap.is_marked();
--- a/src/hotspot/share/gc/z/zPageAllocator.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPageAllocator.cpp	Wed May 15 13:54:43 2019 +0530
@@ -22,6 +22,7 @@
  */
 
 #include "precompiled.hpp"
+#include "gc/shared/suspendibleThreadSet.hpp"
 #include "gc/z/zAddress.inline.hpp"
 #include "gc/z/zCollectedHeap.hpp"
 #include "gc/z/zFuture.inline.hpp"
@@ -30,14 +31,16 @@
 #include "gc/z/zPage.inline.hpp"
 #include "gc/z/zPageAllocator.hpp"
 #include "gc/z/zPageCache.inline.hpp"
-#include "gc/z/zPreMappedMemory.inline.hpp"
 #include "gc/z/zSafeDelete.inline.hpp"
 #include "gc/z/zStat.hpp"
 #include "gc/z/zTracer.inline.hpp"
 #include "runtime/init.hpp"
+#include "runtime/java.hpp"
+#include "utilities/debug.hpp"
 
 static const ZStatCounter       ZCounterAllocationRate("Memory", "Allocation Rate", ZStatUnitBytesPerSecond);
-static const ZStatCounter       ZCounterPageCacheEvict("Memory", "Page Cache Evict", ZStatUnitBytesPerSecond);
+static const ZStatCounter       ZCounterPageCacheFlush("Memory", "Page Cache Flush", ZStatUnitBytesPerSecond);
+static const ZStatCounter       ZCounterUncommit("Memory", "Uncommit", ZStatUnitBytesPerSecond);
 static const ZStatCriticalPhase ZCriticalPhaseAllocationStall("Allocation Stall");
 
 class ZPageAllocRequest : public StackObj {
@@ -85,37 +88,105 @@
 
 ZPage* const ZPageAllocator::gc_marker = (ZPage*)-1;
 
-ZPageAllocator::ZPageAllocator(size_t min_capacity, size_t max_capacity, size_t max_reserve) :
+ZPageAllocator::ZPageAllocator(size_t min_capacity,
+                               size_t initial_capacity,
+                               size_t max_capacity,
+                               size_t max_reserve) :
     _lock(),
     _virtual(),
-    _physical(max_capacity),
+    _physical(),
     _cache(),
+    _min_capacity(min_capacity),
+    _max_capacity(max_capacity),
     _max_reserve(max_reserve),
-    _pre_mapped(_virtual, _physical, try_ensure_unused_for_pre_mapped(min_capacity)),
+    _current_max_capacity(max_capacity),
+    _capacity(0),
     _used_high(0),
     _used_low(0),
     _used(0),
     _allocated(0),
     _reclaimed(0),
     _queue(),
-    _safe_delete() {}
+    _safe_delete(),
+    _uncommit(false),
+    _initialized(false) {
+
+  if (!_virtual.is_initialized() || !_physical.is_initialized()) {
+    return;
+  }
+
+  log_info(gc, init)("Min Capacity: " SIZE_FORMAT "M", min_capacity / M);
+  log_info(gc, init)("Initial Capacity: " SIZE_FORMAT "M", initial_capacity / M);
+  log_info(gc, init)("Max Capacity: " SIZE_FORMAT "M", max_capacity / M);
+  log_info(gc, init)("Max Reserve: " SIZE_FORMAT "M", max_reserve / M);
+  log_info(gc, init)("Pre-touch: %s", AlwaysPreTouch ? "Enabled" : "Disabled");
+
+  // Warn if system limits could stop us from reaching max capacity
+  _physical.warn_commit_limits(max_capacity);
+
+  // Commit initial capacity
+  _capacity = _physical.commit(initial_capacity);
+  if (_capacity != initial_capacity) {
+    log_error(gc)("Failed to allocate initial Java heap (" SIZE_FORMAT "M)", initial_capacity / M);
+    return;
+  }
+
+  // If uncommit is not explicitly disabled, max capacity is greater than
+  // min capacity, and uncommit is supported by the platform, then we will
+  // try to uncommit unused memory.
+  _uncommit = ZUncommit && (max_capacity > min_capacity) && _physical.supports_uncommit();
+  if (_uncommit) {
+    log_info(gc, init)("Uncommit: Enabled, Delay: " UINTX_FORMAT "s", ZUncommitDelay);
+  } else {
+    log_info(gc, init)("Uncommit: Disabled");
+  }
+
+  // Pre-map initial capacity
+  prime_cache(initial_capacity);
+
+  // Successfully initialized
+  _initialized = true;
+}
+
+void ZPageAllocator::prime_cache(size_t size) {
+  // Allocate physical memory
+  const ZPhysicalMemory pmem = _physical.alloc(size);
+  guarantee(!pmem.is_null(), "Invalid size");
+
+  // Allocate virtual memory
+  const ZVirtualMemory vmem = _virtual.alloc(size, true /* alloc_from_front */);
+  guarantee(!vmem.is_null(), "Invalid size");
+
+  // Allocate page
+  ZPage* const page = new ZPage(vmem, pmem);
+
+  // Map page
+  map_page(page);
+  page->set_pre_mapped();
+
+  // Add page to cache
+  page->set_last_used();
+  _cache.free_page(page);
+}
 
 bool ZPageAllocator::is_initialized() const {
-  return _physical.is_initialized() &&
-         _virtual.is_initialized() &&
-         _pre_mapped.is_initialized();
+  return _initialized;
+}
+
+size_t ZPageAllocator::min_capacity() const {
+  return _min_capacity;
 }
 
 size_t ZPageAllocator::max_capacity() const {
-  return _physical.max_capacity();
+  return _max_capacity;
 }
 
 size_t ZPageAllocator::current_max_capacity() const {
-  return _physical.current_max_capacity();
+  return _current_max_capacity;
 }
 
 size_t ZPageAllocator::capacity() const {
-  return _physical.capacity();
+  return _capacity;
 }
 
 size_t ZPageAllocator::max_reserve() const {
@@ -135,7 +206,7 @@
 }
 
 size_t ZPageAllocator::unused() const {
-  const ssize_t unused = (ssize_t)_physical.capacity() - (ssize_t)_used - (ssize_t)_max_reserve;
+  const ssize_t unused = (ssize_t)_capacity - (ssize_t)_used - (ssize_t)_max_reserve;
   return unused > 0 ? (size_t)unused : 0;
 }
 
@@ -181,83 +252,40 @@
   }
 }
 
-size_t ZPageAllocator::max_available(bool no_reserve) const {
-  size_t available = current_max_capacity() - used();
-
-  if (no_reserve) {
-    // The reserve should not be considered available
-    available -= MIN2(available, max_reserve());
-  }
-
-  return available;
-}
-
-size_t ZPageAllocator::try_ensure_unused(size_t size, bool no_reserve) {
-  // Ensure that we always have space available for the reserve. This
-  // is needed to avoid losing the reserve because of failure to map
-  // more memory before reaching max capacity.
-  _physical.try_ensure_unused_capacity(size + max_reserve());
-
-  size_t unused = _physical.unused_capacity();
-
-  if (no_reserve) {
-    // The reserve should not be considered unused
-    unused -= MIN2(unused, max_reserve());
-  }
-
-  return MIN2(size, unused);
-}
-
-size_t ZPageAllocator::try_ensure_unused_for_pre_mapped(size_t size) {
-  // This function is called during construction, where the
-  // physical memory manager might have failed to initialied.
-  if (!_physical.is_initialized()) {
-    return 0;
-  }
-
-  return try_ensure_unused(size, true /* no_reserve */);
-}
-
 ZPage* ZPageAllocator::create_page(uint8_t type, size_t size) {
-  // Allocate physical memory
-  const ZPhysicalMemory pmem = _physical.alloc(size);
-  if (pmem.is_null()) {
-    // Out of memory
-    return NULL;
-  }
-
   // Allocate virtual memory
   const ZVirtualMemory vmem = _virtual.alloc(size);
   if (vmem.is_null()) {
     // Out of address space
-    _physical.free(pmem);
     return NULL;
   }
 
+  // Allocate physical memory
+  const ZPhysicalMemory pmem = _physical.alloc(size);
+  assert(!pmem.is_null(), "Invalid size");
+
   // Allocate page
   return new ZPage(type, vmem, pmem);
 }
 
-void ZPageAllocator::flush_pre_mapped() {
-  if (_pre_mapped.available() == 0) {
-    return;
-  }
+void ZPageAllocator::destroy_page(ZPage* page) {
+  const ZVirtualMemory& vmem = page->virtual_memory();
+  const ZPhysicalMemory& pmem = page->physical_memory();
 
-  // Detach the memory mapping.
-  detach_memory(_pre_mapped.virtual_memory(), _pre_mapped.physical_memory());
+  // Unmap memory
+  _physical.unmap(pmem, vmem.start());
 
-  _pre_mapped.clear();
-}
+  // Free physical memory
+  _physical.free(pmem);
 
-void ZPageAllocator::destroy_page(ZPage* page) {
-  // Detach virtual and physical memory
-  detach_memory(page->virtual_memory(), page->physical_memory());
+  // Free virtual memory
+  _virtual.free(vmem);
 
   // Delete page safely
   _safe_delete(page);
 }
 
-void ZPageAllocator::map_page(ZPage* page) {
+void ZPageAllocator::map_page(const ZPage* page) const {
   // Map physical memory
   if (!page->is_mapped()) {
     _physical.map(page->physical_memory(), page->start());
@@ -266,57 +294,92 @@
   }
 }
 
-void ZPageAllocator::unmap_all_pages() {
-  ZPhysicalMemory pmem(ZPhysicalMemorySegment(0 /* start */, ZAddressOffsetMax));
-  _physical.debug_unmap(pmem, 0 /* offset */);
-  pmem.clear();
+size_t ZPageAllocator::max_available(bool no_reserve) const {
+  size_t available = _current_max_capacity - _used;
+
+  if (no_reserve) {
+    // The reserve should not be considered available
+    available -= MIN2(available, _max_reserve);
+  }
+
+  return available;
 }
 
-void ZPageAllocator::check_out_of_memory_during_initialization() {
-  if (!is_init_completed()) {
-    vm_exit_during_initialization("java.lang.OutOfMemoryError", "Java heap too small");
+bool ZPageAllocator::ensure_available(size_t size, bool no_reserve) {
+  if (max_available(no_reserve) < size) {
+    // Not enough free memory
+    return false;
+  }
+
+  // We add the max_reserve to the requested size to avoid losing
+  // the reserve because of failure to increase capacity before
+  // reaching max capacity.
+  size += _max_reserve;
+
+  // Don't try to increase capacity if enough unused capacity
+  // is available or if current max capacity has been reached.
+  const size_t available = _capacity - _used;
+  if (available < size && _capacity < _current_max_capacity) {
+    // Try to increase capacity
+    const size_t commit = MIN2(size - available, _current_max_capacity - _capacity);
+    const size_t committed = _physical.commit(commit);
+    _capacity += committed;
+
+    log_trace(gc, heap)("Make Available: Size: " SIZE_FORMAT "M, NoReserve: %s, "
+                        "Available: " SIZE_FORMAT "M, Commit: " SIZE_FORMAT "M, "
+                        "Committed: " SIZE_FORMAT "M, Capacity: " SIZE_FORMAT "M",
+                        size / M, no_reserve ? "True" : "False", available / M,
+                        commit / M, committed / M, _capacity / M);
+
+    if (committed != commit) {
+      // Failed, or partly failed, to increase capacity. Adjust current
+      // max capacity to avoid further attempts to increase capacity.
+      log_error(gc)("Forced to lower max Java heap size from "
+                    SIZE_FORMAT "M(%.0lf%%) to " SIZE_FORMAT "M(%.0lf%%)",
+                    _current_max_capacity / M, percent_of(_current_max_capacity, _max_capacity),
+                    _capacity / M, percent_of(_capacity, _max_capacity));
+
+      _current_max_capacity = _capacity;
+    }
+  }
+
+  if (!no_reserve) {
+    size -= _max_reserve;
+  }
+
+  const size_t new_available = _capacity - _used;
+  return new_available >= size;
+}
+
+void ZPageAllocator::ensure_uncached_available(size_t size) {
+  assert(_capacity - _used >= size, "Invalid size");
+  const size_t uncached_available = _capacity - _used - _cache.available();
+  if (size > uncached_available) {
+    flush_cache_for_allocation(size - uncached_available);
   }
 }
 
-ZPage* ZPageAllocator::alloc_page_common_inner(uint8_t type, size_t size, ZAllocationFlags flags) {
-  const size_t max = max_available(flags.no_reserve());
-  if (max < size) {
+ZPage* ZPageAllocator::alloc_page_common_inner(uint8_t type, size_t size, bool no_reserve) {
+  if (!ensure_available(size, no_reserve)) {
     // Not enough free memory
     return NULL;
   }
 
-  // Try allocating from the page cache
-  ZPage* const cached_page = _cache.alloc_page(type, size);
-  if (cached_page != NULL) {
-    return cached_page;
-  }
-
-  // Try allocate from the pre-mapped memory
-  ZPage* const pre_mapped_page = _pre_mapped.alloc_page(type, size);
-  if (pre_mapped_page != NULL) {
-    return pre_mapped_page;
+  // Try allocate page from the cache
+  ZPage* const page = _cache.alloc_page(type, size);
+  if (page != NULL) {
+    return page;
   }
 
-  // Flush any remaining pre-mapped memory so that
-  // subsequent allocations can use the physical memory.
-  flush_pre_mapped();
+  // Try flush pages from the cache
+  ensure_uncached_available(size);
 
-  // Try ensure that physical memory is available
-  const size_t unused = try_ensure_unused(size, flags.no_reserve());
-  if (unused < size) {
-    // Try evict pages from the cache
-    const size_t needed = size - unused;
-    if (_cache.available() >= needed) {
-      evict_cache(needed);
-    }
-  }
-
-  // Create new page and allocate physical memory
+  // Create new page
   return create_page(type, size);
 }
 
 ZPage* ZPageAllocator::alloc_page_common(uint8_t type, size_t size, ZAllocationFlags flags) {
-  ZPage* const page = alloc_page_common_inner(type, size, flags);
+  ZPage* const page = alloc_page_common_inner(type, size, flags.no_reserve());
   if (page == NULL) {
     // Out of memory
     return NULL;
@@ -326,11 +389,17 @@
   increase_used(size, flags.relocation());
 
   // Send trace event
-  ZTracer::tracer()->report_page_alloc(size, used(), max_available(flags.no_reserve()), _cache.available(), flags);
+  ZTracer::tracer()->report_page_alloc(size, _used, max_available(flags.no_reserve()), _cache.available(), flags);
 
   return page;
 }
 
+void ZPageAllocator::check_out_of_memory_during_initialization() {
+  if (!is_init_completed()) {
+    vm_exit_during_initialization("java.lang.OutOfMemoryError", "Java heap too small");
+  }
+}
+
 ZPage* ZPageAllocator::alloc_page_blocking(uint8_t type, size_t size, ZAllocationFlags flags) {
   // Prepare to block
   ZPageAllocRequest request(type, size, flags, ZCollectedHeap::heap()->total_collections());
@@ -433,28 +502,15 @@
   }
 }
 
-void ZPageAllocator::detach_memory(const ZVirtualMemory& vmem, ZPhysicalMemory& pmem) {
-  const uintptr_t addr = vmem.start();
-
-  // Free virtual memory
-  _virtual.free(vmem);
-
-  // Unmap physical memory
-  _physical.unmap(pmem, addr);
-
-  // Free physical memory
-  _physical.free(pmem);
-
-  // Clear physical mapping
-  pmem.clear();
-}
-
 void ZPageAllocator::free_page(ZPage* page, bool reclaimed) {
   ZLocker<ZLock> locker(&_lock);
 
   // Update used statistics
   decrease_used(page->size(), reclaimed);
 
+  // Set time when last used
+  page->set_last_used();
+
   // Cache page
   _cache.free_page(page);
 
@@ -462,59 +518,157 @@
   satisfy_alloc_queue();
 }
 
-void ZPageAllocator::flush_cache(ZPageCacheFlushClosure* cl) {
+size_t ZPageAllocator::flush_cache(ZPageCacheFlushClosure* cl) {
   ZList<ZPage> list;
 
+  // Flush pages
   _cache.flush(cl, &list);
 
+  const size_t overflushed = cl->overflushed();
+  if (overflushed > 0) {
+    // Overflushed, keep part of last page
+    ZPage* const page = list.last()->split(overflushed);
+    _cache.free_page(page);
+  }
+
+  // Destroy pages
+  size_t flushed = 0;
   for (ZPage* page = list.remove_first(); page != NULL; page = list.remove_first()) {
+    flushed += page->size();
     destroy_page(page);
   }
+
+  return flushed;
 }
 
-class ZPageCacheEvictClosure : public ZPageCacheFlushClosure {
-private:
-  const size_t _requested;
-  size_t       _evicted;
-
+class ZPageCacheFlushForAllocationClosure : public ZPageCacheFlushClosure {
 public:
-  ZPageCacheEvictClosure(size_t requested) :
-      _requested(requested),
-      _evicted(0) {}
+  ZPageCacheFlushForAllocationClosure(size_t requested) :
+      ZPageCacheFlushClosure(requested) {}
 
   virtual bool do_page(const ZPage* page) {
-    if (_evicted < _requested) {
-      // Evict page
-      _evicted += page->size();
+    if (_flushed < _requested) {
+      // Flush page
+      _flushed += page->size();
       return true;
     }
 
-    // Don't evict page
+    // Don't flush page
     return false;
   }
-
-  size_t evicted() const {
-    return _evicted;
-  }
 };
 
-void ZPageAllocator::evict_cache(size_t requested) {
-  // Evict pages
-  ZPageCacheEvictClosure cl(requested);
-  flush_cache(&cl);
+void ZPageAllocator::flush_cache_for_allocation(size_t requested) {
+  assert(requested <= _cache.available(), "Invalid request");
 
-  const size_t evicted = cl.evicted();
+  // Flush pages
+  ZPageCacheFlushForAllocationClosure cl(requested);
+  const size_t flushed = flush_cache(&cl);
+
+  assert(requested == flushed, "Failed to flush");
+
   const size_t cached_after = _cache.available();
-  const size_t cached_before = cached_after + evicted;
+  const size_t cached_before = cached_after + flushed;
 
   log_info(gc, heap)("Page Cache: " SIZE_FORMAT "M(%.0lf%%)->" SIZE_FORMAT "M(%.0lf%%), "
-                     "Evicted: " SIZE_FORMAT "M, Requested: " SIZE_FORMAT "M",
+                     "Flushed: " SIZE_FORMAT "M",
                      cached_before / M, percent_of(cached_before, max_capacity()),
                      cached_after / M, percent_of(cached_after, max_capacity()),
-                     evicted / M, requested / M);
+                     flushed / M);
 
   // Update statistics
-  ZStatInc(ZCounterPageCacheEvict, evicted);
+  ZStatInc(ZCounterPageCacheFlush, flushed);
+}
+
+class ZPageCacheFlushForUncommitClosure : public ZPageCacheFlushClosure {
+private:
+  const uint64_t _now;
+  const uint64_t _delay;
+  uint64_t       _timeout;
+
+public:
+  ZPageCacheFlushForUncommitClosure(size_t requested, uint64_t delay) :
+      ZPageCacheFlushClosure(requested),
+      _now(os::elapsedTime()),
+      _delay(delay),
+      _timeout(_delay) {}
+
+  virtual bool do_page(const ZPage* page) {
+    const uint64_t expires = page->last_used() + _delay;
+    const uint64_t timeout = expires - MIN2(expires, _now);
+
+    if (_flushed < _requested && timeout == 0) {
+      // Flush page
+      _flushed += page->size();
+      return true;
+    }
+
+    // Record shortest non-expired timeout
+    _timeout = MIN2(_timeout, timeout);
+
+    // Don't flush page
+    return false;
+  }
+
+  uint64_t timeout() const {
+    return _timeout;
+  }
+};
+
+uint64_t ZPageAllocator::uncommit(uint64_t delay) {
+  // Set the default timeout, when no pages are found in the
+  // cache or when uncommit is disabled, equal to the delay.
+  uint64_t timeout = delay;
+
+  if (!_uncommit) {
+    // Disabled
+    return timeout;
+  }
+
+  size_t capacity_before;
+  size_t capacity_after;
+  size_t uncommitted;
+
+  {
+    SuspendibleThreadSetJoiner joiner;
+    ZLocker<ZLock> locker(&_lock);
+
+    // Don't flush more than we will uncommit. Never uncommit
+    // the reserve, and never uncommit below min capacity.
+    const size_t needed = MIN2(_used + _max_reserve, _current_max_capacity);
+    const size_t guarded = MAX2(needed, _min_capacity);
+    const size_t uncommittable = _capacity - guarded;
+    const size_t uncached_available = _capacity - _used - _cache.available();
+    size_t uncommit = MIN2(uncommittable, uncached_available);
+    const size_t flush = uncommittable - uncommit;
+
+    if (flush > 0) {
+      // Flush pages to uncommit
+      ZPageCacheFlushForUncommitClosure cl(flush, delay);
+      uncommit += flush_cache(&cl);
+      timeout = cl.timeout();
+    }
+
+    // Uncommit
+    uncommitted = _physical.uncommit(uncommit);
+    _capacity -= uncommitted;
+
+    capacity_after = _capacity;
+    capacity_before = capacity_after + uncommitted;
+  }
+
+  if (uncommitted > 0) {
+    log_info(gc, heap)("Capacity: " SIZE_FORMAT "M(%.0lf%%)->" SIZE_FORMAT "M(%.0lf%%), "
+                       "Uncommitted: " SIZE_FORMAT "M",
+                       capacity_before / M, percent_of(capacity_before, max_capacity()),
+                       capacity_after / M, percent_of(capacity_after, max_capacity()),
+                       uncommitted / M);
+
+    // Update statistics
+    ZStatInc(ZCounterUncommit, uncommitted);
+  }
+
+  return timeout;
 }
 
 void ZPageAllocator::enable_deferred_delete() const {
@@ -525,6 +679,35 @@
   _safe_delete.disable_deferred_delete();
 }
 
+void ZPageAllocator::debug_map_page(const ZPage* page) const {
+  assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+  _physical.debug_map(page->physical_memory(), page->start());
+}
+
+class ZPageCacheDebugMapClosure : public StackObj {
+private:
+  const ZPageAllocator* const _allocator;
+
+public:
+  ZPageCacheDebugMapClosure(const ZPageAllocator* allocator) :
+      _allocator(allocator) {}
+
+  virtual void do_page(const ZPage* page) {
+    _allocator->debug_map_page(page);
+  }
+};
+
+void ZPageAllocator::debug_map_cached_pages() const {
+  assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+  ZPageCacheDebugMapClosure cl(this);
+  _cache.pages_do(&cl);
+}
+
+void ZPageAllocator::debug_unmap_all_pages() const {
+  assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
+  _physical.debug_unmap(ZPhysicalMemorySegment(0 /* start */, ZAddressOffsetMax), 0 /* offset */);
+}
+
 bool ZPageAllocator::is_alloc_stalled() const {
   assert(SafepointSynchronize::is_at_safepoint(), "Should be at safepoint");
   return !_queue.is_empty();
--- a/src/hotspot/share/gc/z/zPageAllocator.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPageAllocator.hpp	Wed May 15 13:54:43 2019 +0530
@@ -29,7 +29,6 @@
 #include "gc/z/zLock.hpp"
 #include "gc/z/zPageCache.hpp"
 #include "gc/z/zPhysicalMemory.hpp"
-#include "gc/z/zPreMappedMemory.hpp"
 #include "gc/z/zSafeDelete.hpp"
 #include "gc/z/zVirtualMemory.hpp"
 #include "memory/allocation.hpp"
@@ -44,8 +43,11 @@
   ZVirtualMemoryManager      _virtual;
   ZPhysicalMemoryManager     _physical;
   ZPageCache                 _cache;
+  const size_t               _min_capacity;
+  const size_t               _max_capacity;
   const size_t               _max_reserve;
-  ZPreMappedMemory           _pre_mapped;
+  size_t                     _current_max_capacity;
+  size_t                     _capacity;
   size_t                     _used_high;
   size_t                     _used_low;
   size_t                     _used;
@@ -53,39 +55,44 @@
   ssize_t                    _reclaimed;
   ZList<ZPageAllocRequest>   _queue;
   mutable ZSafeDelete<ZPage> _safe_delete;
+  bool                       _uncommit;
+  bool                       _initialized;
 
   static ZPage* const      gc_marker;
 
+  void prime_cache(size_t size);
+
   void increase_used(size_t size, bool relocation);
   void decrease_used(size_t size, bool reclaimed);
 
-  size_t max_available(bool no_reserve) const;
-  size_t try_ensure_unused(size_t size, bool no_reserve);
-  size_t try_ensure_unused_for_pre_mapped(size_t size);
-
   ZPage* create_page(uint8_t type, size_t size);
   void destroy_page(ZPage* page);
 
-  void flush_pre_mapped();
-  void flush_cache(ZPageCacheFlushClosure* cl);
-  void evict_cache(size_t requested);
+  size_t max_available(bool no_reserve) const;
+  bool ensure_available(size_t size, bool no_reserve);
+  void ensure_uncached_available(size_t size);
 
   void check_out_of_memory_during_initialization();
 
-  ZPage* alloc_page_common_inner(uint8_t type, size_t size, ZAllocationFlags flags);
+  ZPage* alloc_page_common_inner(uint8_t type, size_t size, bool no_reserve);
   ZPage* alloc_page_common(uint8_t type, size_t size, ZAllocationFlags flags);
   ZPage* alloc_page_blocking(uint8_t type, size_t size, ZAllocationFlags flags);
   ZPage* alloc_page_nonblocking(uint8_t type, size_t size, ZAllocationFlags flags);
 
+  size_t flush_cache(ZPageCacheFlushClosure* cl);
+  void flush_cache_for_allocation(size_t requested);
+
   void satisfy_alloc_queue();
 
-  void detach_memory(const ZVirtualMemory& vmem, ZPhysicalMemory& pmem);
-
 public:
-  ZPageAllocator(size_t min_capacity, size_t max_capacity, size_t max_reserve);
+  ZPageAllocator(size_t min_capacity,
+                 size_t initial_capacity,
+                 size_t max_capacity,
+                 size_t max_reserve);
 
   bool is_initialized() const;
 
+  size_t min_capacity() const;
   size_t max_capacity() const;
   size_t current_max_capacity() const;
   size_t capacity() const;
@@ -102,11 +109,16 @@
   ZPage* alloc_page(uint8_t type, size_t size, ZAllocationFlags flags);
   void free_page(ZPage* page, bool reclaimed);
 
+  uint64_t uncommit(uint64_t delay);
+
   void enable_deferred_delete() const;
   void disable_deferred_delete() const;
 
-  void map_page(ZPage* page);
-  void unmap_all_pages();
+  void map_page(const ZPage* page) const;
+
+  void debug_map_page(const ZPage* page) const;
+  void debug_map_cached_pages() const;
+  void debug_unmap_all_pages() const;
 
   bool is_alloc_stalled() const;
   void check_out_of_memory();
--- a/src/hotspot/share/gc/z/zPageCache.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPageCache.cpp	Wed May 15 13:54:43 2019 +0530
@@ -31,8 +31,17 @@
 
 static const ZStatCounter ZCounterPageCacheHitL1("Memory", "Page Cache Hit L1", ZStatUnitOpsPerSecond);
 static const ZStatCounter ZCounterPageCacheHitL2("Memory", "Page Cache Hit L2", ZStatUnitOpsPerSecond);
+static const ZStatCounter ZCounterPageCacheHitL3("Memory", "Page Cache Hit L3", ZStatUnitOpsPerSecond);
 static const ZStatCounter ZCounterPageCacheMiss("Memory", "Page Cache Miss", ZStatUnitOpsPerSecond);
 
+ZPageCacheFlushClosure::ZPageCacheFlushClosure(size_t requested) :
+    _requested(requested),
+    _flushed(0) {}
+
+size_t ZPageCacheFlushClosure::overflushed() const {
+  return _flushed > _requested ? _flushed - _requested : 0;
+}
+
 ZPageCache::ZPageCache() :
     _available(0),
     _small(),
@@ -67,40 +76,73 @@
     remote_numa_id++;
   }
 
-  ZStatInc(ZCounterPageCacheMiss);
   return NULL;
 }
 
 ZPage* ZPageCache::alloc_medium_page() {
-  ZPage* const l1_page = _medium.remove_first();
-  if (l1_page != NULL) {
+  ZPage* const page = _medium.remove_first();
+  if (page != NULL) {
     ZStatInc(ZCounterPageCacheHitL1);
-    return l1_page;
+    return page;
   }
 
-  ZStatInc(ZCounterPageCacheMiss);
   return NULL;
 }
 
 ZPage* ZPageCache::alloc_large_page(size_t size) {
   // Find a page with the right size
   ZListIterator<ZPage> iter(&_large);
-  for (ZPage* l1_page; iter.next(&l1_page);) {
-    if (l1_page->size() == size) {
+  for (ZPage* page; iter.next(&page);) {
+    if (size == page->size()) {
       // Page found
-      _large.remove(l1_page);
+      _large.remove(page);
       ZStatInc(ZCounterPageCacheHitL1);
-      return l1_page;
+      return page;
     }
   }
 
-  ZStatInc(ZCounterPageCacheMiss);
+  return NULL;
+}
+
+ZPage* ZPageCache::alloc_oversized_medium_page(size_t size) {
+  if (size <= ZPageSizeMedium) {
+    return _medium.remove_first();
+  }
+
   return NULL;
 }
 
+ZPage* ZPageCache::alloc_oversized_large_page(size_t size) {
+  // Find a page that is large enough
+  ZListIterator<ZPage> iter(&_large);
+  for (ZPage* page; iter.next(&page);) {
+    if (size <= page->size()) {
+      // Page found
+      _large.remove(page);
+      return page;
+    }
+  }
+
+  return NULL;
+}
+
+ZPage* ZPageCache::alloc_oversized_page(size_t size) {
+  ZPage* page = alloc_oversized_large_page(size);
+  if (page == NULL) {
+    page = alloc_oversized_medium_page(size);
+  }
+
+  if (page != NULL) {
+    ZStatInc(ZCounterPageCacheHitL3);
+  }
+
+  return page;
+}
+
 ZPage* ZPageCache::alloc_page(uint8_t type, size_t size) {
   ZPage* page;
 
+  // Try allocate exact page
   if (type == ZPageTypeSmall) {
     page = alloc_small_page();
   } else if (type == ZPageTypeMedium) {
@@ -109,14 +151,33 @@
     page = alloc_large_page(size);
   }
 
+  if (page == NULL) {
+    // Try allocate potentially oversized page
+    ZPage* const oversized = alloc_oversized_page(size);
+    if (oversized != NULL) {
+      if (size < oversized->size()) {
+        // Split oversized page
+        page = oversized->split(type, size);
+
+        // Cache remainder
+        free_page_inner(oversized);
+      } else {
+        // Re-type correctly sized page
+        page = oversized->retype(type);
+      }
+    }
+  }
+
   if (page != NULL) {
     _available -= page->size();
+  } else {
+    ZStatInc(ZCounterPageCacheMiss);
   }
 
   return page;
 }
 
-void ZPageCache::free_page(ZPage* page) {
+void ZPageCache::free_page_inner(ZPage* page) {
   const uint8_t type = page->type();
   if (type == ZPageTypeSmall) {
     _small.get(page->numa_id()).insert_first(page);
@@ -125,7 +186,10 @@
   } else {
     _large.insert_first(page);
   }
+}
 
+void ZPageCache::free_page(ZPage* page) {
+  free_page_inner(page);
   _available += page->size();
 }
 
--- a/src/hotspot/share/gc/z/zPageCache.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPageCache.hpp	Wed May 15 13:54:43 2019 +0530
@@ -30,7 +30,13 @@
 #include "memory/allocation.hpp"
 
 class ZPageCacheFlushClosure : public StackObj {
+protected:
+  const size_t _requested;
+  size_t       _flushed;
+
 public:
+  ZPageCacheFlushClosure(size_t requested);
+  size_t overflushed() const;
   virtual bool do_page(const ZPage* page) = 0;
 };
 
@@ -45,6 +51,12 @@
   ZPage* alloc_medium_page();
   ZPage* alloc_large_page(size_t size);
 
+  ZPage* alloc_oversized_medium_page(size_t size);
+  ZPage* alloc_oversized_large_page(size_t size);
+  ZPage* alloc_oversized_page(size_t size);
+
+  void free_page_inner(ZPage* page);
+
   bool flush_list_inner(ZPageCacheFlushClosure* cl, ZList<ZPage>* from, ZList<ZPage>* to);
   void flush_list(ZPageCacheFlushClosure* cl, ZList<ZPage>* from, ZList<ZPage>* to);
   void flush_per_numa_lists(ZPageCacheFlushClosure* cl, ZPerNUMA<ZList<ZPage> >* from, ZList<ZPage>* to);
@@ -58,6 +70,8 @@
   void free_page(ZPage* page);
 
   void flush(ZPageCacheFlushClosure* cl, ZList<ZPage>* to);
+
+  template <typename Closure> void pages_do(Closure* cl) const;
 };
 
 #endif // SHARE_GC_Z_ZPAGECACHE_HPP
--- a/src/hotspot/share/gc/z/zPageCache.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPageCache.inline.hpp	Wed May 15 13:54:43 2019 +0530
@@ -24,10 +24,35 @@
 #ifndef SHARE_GC_Z_ZPAGECACHE_INLINE_HPP
 #define SHARE_GC_Z_ZPAGECACHE_INLINE_HPP
 
+#include "gc/z/zList.inline.hpp"
 #include "gc/z/zPageCache.hpp"
 
 inline size_t ZPageCache::available() const {
   return _available;
 }
 
+template <typename Closure>
+inline void ZPageCache::pages_do(Closure* cl) const {
+  // Small
+  ZPerNUMAConstIterator<ZList<ZPage> > iter_numa(&_small);
+  for (const ZList<ZPage>* list; iter_numa.next(&list);) {
+    ZListIterator<ZPage> iter_small(list);
+    for (ZPage* page; iter_small.next(&page);) {
+      cl->do_page(page);
+    }
+  }
+
+  // Medium
+  ZListIterator<ZPage> iter_medium(&_medium);
+  for (ZPage* page; iter_medium.next(&page);) {
+    cl->do_page(page);
+  }
+
+  // Large
+  ZListIterator<ZPage> iter_large(&_large);
+  for (ZPage* page; iter_large.next(&page);) {
+    cl->do_page(page);
+  }
+}
+
 #endif // SHARE_GC_Z_ZPAGECACHE_INLINE_HPP
--- a/src/hotspot/share/gc/z/zPhysicalMemory.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPhysicalMemory.cpp	Wed May 15 13:54:43 2019 +0530
@@ -33,18 +33,42 @@
     _nsegments(0),
     _segments(NULL) {}
 
-ZPhysicalMemory::ZPhysicalMemory(size_t size) :
-    _nsegments(0),
-    _segments(NULL) {
-  add_segment(ZPhysicalMemorySegment(0, size));
-}
-
 ZPhysicalMemory::ZPhysicalMemory(const ZPhysicalMemorySegment& segment) :
     _nsegments(0),
     _segments(NULL) {
   add_segment(segment);
 }
 
+ZPhysicalMemory::ZPhysicalMemory(const ZPhysicalMemory& pmem) :
+    _nsegments(0),
+    _segments(NULL) {
+
+  // Copy segments
+  for (size_t i = 0; i < pmem.nsegments(); i++) {
+    add_segment(pmem.segment(i));
+  }
+}
+
+const ZPhysicalMemory& ZPhysicalMemory::operator=(const ZPhysicalMemory& pmem) {
+  // Free segments
+  delete [] _segments;
+  _segments = NULL;
+  _nsegments = 0;
+
+  // Copy segments
+  for (size_t i = 0; i < pmem.nsegments(); i++) {
+    add_segment(pmem.segment(i));
+  }
+
+  return *this;
+}
+
+ZPhysicalMemory::~ZPhysicalMemory() {
+  delete [] _segments;
+  _segments = NULL;
+  _nsegments = 0;
+}
+
 size_t ZPhysicalMemory::size() const {
   size_t size = 0;
 
@@ -55,134 +79,114 @@
   return size;
 }
 
-void ZPhysicalMemory::add_segment(ZPhysicalMemorySegment segment) {
+void ZPhysicalMemory::add_segment(const ZPhysicalMemorySegment& segment) {
   // Try merge with last segment
   if (_nsegments > 0) {
     ZPhysicalMemorySegment& last = _segments[_nsegments - 1];
     assert(last.end() <= segment.start(), "Segments added out of order");
     if (last.end() == segment.start()) {
-      // Merge
-      last.expand(segment.size());
+      last = ZPhysicalMemorySegment(last.start(), last.size() + segment.size());
       return;
     }
   }
 
-  // Make room for a new segment
-  const size_t size = sizeof(ZPhysicalMemorySegment) * (_nsegments + 1);
-  _segments = (ZPhysicalMemorySegment*)ReallocateHeap((char*)_segments, size, mtGC);
+  // Resize array
+  ZPhysicalMemorySegment* const old_segments = _segments;
+  _segments = new ZPhysicalMemorySegment[_nsegments + 1];
+  for (size_t i = 0; i < _nsegments; i++) {
+    _segments[i] = old_segments[i];
+  }
+  delete [] old_segments;
 
   // Add new segment
   _segments[_nsegments] = segment;
   _nsegments++;
 }
 
-ZPhysicalMemory ZPhysicalMemory::split(size_t split_size) {
-  // Only splitting of single-segment instances have been implemented.
-  assert(nsegments() == 1, "Can only have one segment");
-  assert(split_size <= size(), "Invalid size");
-  return ZPhysicalMemory(_segments[0].split(split_size));
-}
+ZPhysicalMemory ZPhysicalMemory::split(size_t size) {
+  ZPhysicalMemory pmem;
+  size_t nsegments = 0;
 
-void ZPhysicalMemory::clear() {
-  if (_segments != NULL) {
-    FreeHeap(_segments);
-    _segments = NULL;
-    _nsegments = 0;
+  for (size_t i = 0; i < _nsegments; i++) {
+    const ZPhysicalMemorySegment& segment = _segments[i];
+    if (pmem.size() < size) {
+      if (pmem.size() + segment.size() <= size) {
+        // Transfer segment
+        pmem.add_segment(segment);
+      } else {
+        // Split segment
+        const size_t split_size = size - pmem.size();
+        pmem.add_segment(ZPhysicalMemorySegment(segment.start(), split_size));
+        _segments[nsegments++] = ZPhysicalMemorySegment(segment.start() + split_size, segment.size() - split_size);
+      }
+    } else {
+      // Keep segment
+      _segments[nsegments++] = segment;
+    }
   }
+
+  _nsegments = nsegments;
+
+  return pmem;
 }
 
-ZPhysicalMemoryManager::ZPhysicalMemoryManager(size_t max_capacity) :
-    _backing(max_capacity),
-    _max_capacity(max_capacity),
-    _current_max_capacity(max_capacity),
-    _capacity(0),
-    _used(0) {}
-
 bool ZPhysicalMemoryManager::is_initialized() const {
   return _backing.is_initialized();
 }
 
-void ZPhysicalMemoryManager::try_ensure_unused_capacity(size_t size) {
-  const size_t unused = unused_capacity();
-  if (unused >= size) {
-    // Don't try to expand, enough unused capacity available
-    return;
-  }
-
-  const size_t current_max = current_max_capacity();
-  if (_capacity == current_max) {
-    // Don't try to expand, current max capacity reached
-    return;
-  }
-
-  // Try to expand
-  const size_t old_capacity = capacity();
-  const size_t new_capacity = MIN2(old_capacity + size - unused, current_max);
-  _capacity = _backing.try_expand(old_capacity, new_capacity);
-
-  if (_capacity != new_capacity) {
-    // Failed, or partly failed, to expand
-    log_error(gc, init)("Not enough space available on the backing filesystem to hold the current max");
-    log_error(gc, init)("Java heap size (" SIZE_FORMAT "M). Forcefully lowering max Java heap size to "
-                        SIZE_FORMAT "M (%.0lf%%).", current_max / M, _capacity / M,
-                        percent_of(_capacity, current_max));
-
-    // Adjust current max capacity to avoid further expand attempts
-    _current_max_capacity = _capacity;
-  }
+void ZPhysicalMemoryManager::warn_commit_limits(size_t max) const {
+  _backing.warn_commit_limits(max);
 }
 
-void ZPhysicalMemoryManager::nmt_commit(ZPhysicalMemory pmem, uintptr_t offset) {
+bool ZPhysicalMemoryManager::supports_uncommit() {
+  return _backing.supports_uncommit();
+}
+
+void ZPhysicalMemoryManager::nmt_commit(const ZPhysicalMemory& pmem, uintptr_t offset) const {
   const uintptr_t addr = _backing.nmt_address(offset);
   const size_t size = pmem.size();
   MemTracker::record_virtual_memory_commit((void*)addr, size, CALLER_PC);
 }
 
-void ZPhysicalMemoryManager::nmt_uncommit(ZPhysicalMemory pmem, uintptr_t offset) {
+void ZPhysicalMemoryManager::nmt_uncommit(const ZPhysicalMemory& pmem, uintptr_t offset) const {
   if (MemTracker::tracking_level() > NMT_minimal) {
     const uintptr_t addr = _backing.nmt_address(offset);
     const size_t size = pmem.size();
-
     Tracker tracker(Tracker::uncommit);
     tracker.record((address)addr, size);
   }
 }
 
+size_t ZPhysicalMemoryManager::commit(size_t size) {
+  return _backing.commit(size);
+}
+
+size_t ZPhysicalMemoryManager::uncommit(size_t size) {
+  return _backing.uncommit(size);
+}
+
 ZPhysicalMemory ZPhysicalMemoryManager::alloc(size_t size) {
-  if (unused_capacity() < size) {
-    // Not enough memory available
-    return ZPhysicalMemory();
-  }
-
-  _used += size;
   return _backing.alloc(size);
 }
 
-void ZPhysicalMemoryManager::free(ZPhysicalMemory pmem) {
+void ZPhysicalMemoryManager::free(const ZPhysicalMemory& pmem) {
   _backing.free(pmem);
-  _used -= pmem.size();
 }
 
-void ZPhysicalMemoryManager::map(ZPhysicalMemory pmem, uintptr_t offset) {
-  // Map page
+void ZPhysicalMemoryManager::map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
   _backing.map(pmem, offset);
-
-  // Update native memory tracker
   nmt_commit(pmem, offset);
 }
 
-void ZPhysicalMemoryManager::unmap(ZPhysicalMemory pmem, uintptr_t offset) {
-  // Update native memory tracker
+void ZPhysicalMemoryManager::unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
   nmt_uncommit(pmem, offset);
-
-  // Unmap page
   _backing.unmap(pmem, offset);
 }
 
-void ZPhysicalMemoryManager::debug_map(ZPhysicalMemory pmem, uintptr_t offset) {
+void ZPhysicalMemoryManager::debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const {
   _backing.debug_map(pmem, offset);
 }
 
-void ZPhysicalMemoryManager::debug_unmap(ZPhysicalMemory pmem, uintptr_t offset) {
+void ZPhysicalMemoryManager::debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const {
   _backing.debug_unmap(pmem, offset);
 }
--- a/src/hotspot/share/gc/z/zPhysicalMemory.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPhysicalMemory.hpp	Wed May 15 13:54:43 2019 +0530
@@ -27,20 +27,18 @@
 #include "memory/allocation.hpp"
 #include OS_CPU_HEADER(gc/z/zPhysicalMemoryBacking)
 
-class ZPhysicalMemorySegment {
+class ZPhysicalMemorySegment : public CHeapObj<mtGC> {
 private:
   uintptr_t _start;
   uintptr_t _end;
 
 public:
+  ZPhysicalMemorySegment();
   ZPhysicalMemorySegment(uintptr_t start, size_t size);
 
   uintptr_t start() const;
   uintptr_t end() const;
   size_t size() const;
-
-  void expand(size_t size);
-  ZPhysicalMemorySegment split(size_t size);
 };
 
 class ZPhysicalMemory {
@@ -50,53 +48,45 @@
 
 public:
   ZPhysicalMemory();
-  ZPhysicalMemory(size_t size);
   ZPhysicalMemory(const ZPhysicalMemorySegment& segment);
+  ZPhysicalMemory(const ZPhysicalMemory& pmem);
+  const ZPhysicalMemory& operator=(const ZPhysicalMemory& pmem);
+  ~ZPhysicalMemory();
 
   bool is_null() const;
   size_t size() const;
 
   size_t nsegments() const;
-  ZPhysicalMemorySegment segment(size_t index) const;
-  void add_segment(ZPhysicalMemorySegment segment);
+  const ZPhysicalMemorySegment& segment(size_t index) const;
+  void add_segment(const ZPhysicalMemorySegment& segment);
 
   ZPhysicalMemory split(size_t size);
-  void clear();
 };
 
 class ZPhysicalMemoryManager {
-  friend class VMStructs;
-
 private:
   ZPhysicalMemoryBacking _backing;
-  const size_t           _max_capacity;
-  size_t                 _current_max_capacity;
-  size_t                 _capacity;
-  size_t                 _used;
 
-  void nmt_commit(ZPhysicalMemory pmem, uintptr_t offset);
-  void nmt_uncommit(ZPhysicalMemory pmem, uintptr_t offset);
+  void nmt_commit(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+  void nmt_uncommit(const ZPhysicalMemory& pmem, uintptr_t offset) const;
 
 public:
-  ZPhysicalMemoryManager(size_t max_capacity);
-
   bool is_initialized() const;
 
-  size_t max_capacity() const;
-  size_t current_max_capacity() const;
-  size_t capacity() const;
-  size_t unused_capacity() const;
+  void warn_commit_limits(size_t max) const;
+  bool supports_uncommit();
 
-  void try_ensure_unused_capacity(size_t size);
+  size_t commit(size_t size);
+  size_t uncommit(size_t size);
 
   ZPhysicalMemory alloc(size_t size);
-  void free(ZPhysicalMemory pmem);
+  void free(const ZPhysicalMemory& pmem);
 
-  void map(ZPhysicalMemory pmem, uintptr_t offset);
-  void unmap(ZPhysicalMemory pmem, uintptr_t offset);
+  void map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+  void unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
 
-  void debug_map(ZPhysicalMemory pmem, uintptr_t offset);
-  void debug_unmap(ZPhysicalMemory pmem, uintptr_t offset);
+  void debug_map(const ZPhysicalMemory& pmem, uintptr_t offset) const;
+  void debug_unmap(const ZPhysicalMemory& pmem, uintptr_t offset) const;
 };
 
 #endif // SHARE_GC_Z_ZPHYSICALMEMORY_HPP
--- a/src/hotspot/share/gc/z/zPhysicalMemory.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zPhysicalMemory.inline.hpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,10 @@
 #include "gc/z/zPhysicalMemory.hpp"
 #include "utilities/debug.hpp"
 
+inline ZPhysicalMemorySegment::ZPhysicalMemorySegment() :
+    _start(UINTPTR_MAX),
+    _end(UINTPTR_MAX) {}
+
 inline ZPhysicalMemorySegment::ZPhysicalMemorySegment(uintptr_t start, size_t size) :
     _start(start),
     _end(start + size) {}
@@ -40,18 +44,7 @@
 }
 
 inline size_t ZPhysicalMemorySegment::size() const {
-  return end() - start();
-}
-
-inline void ZPhysicalMemorySegment::expand(size_t size) {
-  _end += size;
-}
-
-inline ZPhysicalMemorySegment ZPhysicalMemorySegment::split(size_t split_size) {
-  assert(split_size <= size(), "Invalid size");
-  ZPhysicalMemorySegment segment(_start, split_size);
-  _start += split_size;
-  return segment;
+  return _end - _start;
 }
 
 inline bool ZPhysicalMemory::is_null() const {
@@ -62,25 +55,9 @@
   return _nsegments;
 }
 
-inline ZPhysicalMemorySegment ZPhysicalMemory::segment(size_t index) const {
+inline const ZPhysicalMemorySegment& ZPhysicalMemory::segment(size_t index) const {
   assert(index < _nsegments, "Invalid segment index");
   return _segments[index];
 }
 
-inline size_t ZPhysicalMemoryManager::max_capacity() const {
-  return _max_capacity;
-}
-
-inline size_t ZPhysicalMemoryManager::current_max_capacity() const {
-  return _current_max_capacity;
-}
-
-inline size_t ZPhysicalMemoryManager::capacity() const {
-  return _capacity;
-}
-
-inline size_t ZPhysicalMemoryManager::unused_capacity() const {
-  return _capacity - _used;
-}
-
 #endif // SHARE_GC_Z_ZPHYSICALMEMORY_INLINE_HPP
--- a/src/hotspot/share/gc/z/zPreMappedMemory.cpp	Tue May 14 11:23:08 2019 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include "precompiled.hpp"
-#include "gc/z/zPage.inline.hpp"
-#include "gc/z/zPhysicalMemory.inline.hpp"
-#include "gc/z/zPreMappedMemory.inline.hpp"
-#include "gc/z/zVirtualMemory.inline.hpp"
-#include "logging/log.hpp"
-
-ZPreMappedMemory::ZPreMappedMemory(ZVirtualMemoryManager &vmm, ZPhysicalMemoryManager &pmm, size_t size) :
-    _vmem(),
-    _pmem(),
-    _initialized(false) {
-  if (!vmm.is_initialized() || !pmm.is_initialized()) {
-    // Not initialized
-    return;
-  }
-
-  // Pre-mapping and pre-touching memory can take a long time. Log a message
-  // to help the user understand why the JVM might seem slow to start.
-  log_info(gc, init)("Pre-touching: %s", AlwaysPreTouch ? "Enabled" : "Disabled");
-  log_info(gc, init)("Pre-mapping: " SIZE_FORMAT "M", size / M);
-
-  if (size > 0) {
-    _pmem = pmm.alloc(size);
-    if (_pmem.is_null()) {
-      // Out of memory
-      log_error(gc, init)("Failed to pre-map Java heap (Cannot allocate physical memory)");
-      return;
-    }
-
-    _vmem = vmm.alloc(size, true /* alloc_from_front */);
-    if (_vmem.is_null()) {
-      // Out of address space
-      log_error(gc, init)("Failed to pre-map Java heap (Cannot allocate virtual memory)");
-      pmm.free(_pmem);
-      return;
-    }
-
-    // Map physical memory
-    pmm.map(_pmem, _vmem.start());
-  }
-
-  _initialized = true;
-}
-
-ZPage* ZPreMappedMemory::alloc_page(uint8_t type, size_t size) {
-  if (size > available()) {
-    // Not enough pre-mapped memory
-    return NULL;
-  }
-
-  // Take a chunk of the pre-mapped memory
-  const ZPhysicalMemory pmem = _pmem.split(size);
-  const ZVirtualMemory  vmem = _vmem.split(size);
-
-  ZPage* const page = new ZPage(type, vmem, pmem);
-  page->set_pre_mapped();
-
-  return page;
-}
-
-void ZPreMappedMemory::clear() {
-  assert(_pmem.is_null(), "Should be detached");
-  _vmem.clear();
-}
--- a/src/hotspot/share/gc/z/zPreMappedMemory.hpp	Tue May 14 11:23:08 2019 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2016, 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.
- */
-
-#ifndef SHARE_GC_Z_ZPREMAPPEDMEMORY_HPP
-#define SHARE_GC_Z_ZPREMAPPEDMEMORY_HPP
-
-#include "gc/z/zPhysicalMemory.hpp"
-#include "gc/z/zVirtualMemory.hpp"
-#include "memory/allocation.hpp"
-
-class ZPage;
-
-class ZPreMappedMemory {
-private:
-  ZVirtualMemory  _vmem;
-  ZPhysicalMemory _pmem;
-  bool            _initialized;
-
-public:
-  ZPreMappedMemory(ZVirtualMemoryManager &vmm, ZPhysicalMemoryManager &pmm, size_t size);
-
-  bool is_initialized() const;
-
-  ZPhysicalMemory& physical_memory();
-  const ZVirtualMemory& virtual_memory() const;
-
-  size_t available() const;
-
-  ZPage* alloc_page(uint8_t type, size_t size);
-
-  void clear();
-};
-
-#endif // SHARE_GC_Z_ZPREMAPPEDMEMORY_HPP
--- a/src/hotspot/share/gc/z/zPreMappedMemory.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 2016, 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.
- */
-
-#ifndef SHARE_GC_Z_ZPREMAPPEDMEMORY_INLINE_HPP
-#define SHARE_GC_Z_ZPREMAPPEDMEMORY_INLINE_HPP
-
-#include "gc/z/zPreMappedMemory.hpp"
-
-inline bool ZPreMappedMemory::is_initialized() const {
-  return _initialized;
-}
-
-inline ZPhysicalMemory& ZPreMappedMemory::physical_memory() {
-  return _pmem;
-}
-
-inline const ZVirtualMemory& ZPreMappedMemory::virtual_memory() const {
-  return _vmem;
-}
-
-inline size_t ZPreMappedMemory::available() const {
-  return _vmem.size();
-}
-
-#endif // SHARE_GC_Z_ZPREMAPPEDMEMORY_INLINE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zUncommitter.cpp	Wed May 15 13:54:43 2019 +0530
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "precompiled.hpp"
+#include "gc/z/zHeap.inline.hpp"
+#include "gc/z/zUncommitter.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "runtime/os.hpp"
+
+ZUncommitter::ZUncommitter() :
+    _monitor(Monitor::leaf, "ZUncommitter", false, Monitor::_safepoint_check_never),
+    _stop(false) {
+  set_name("ZUncommitter");
+  create_and_start();
+}
+
+bool ZUncommitter::idle(uint64_t timeout) {
+  // Idle for at least one second
+  const uint64_t expires = os::elapsedTime() + MAX2(timeout, 1ul);
+
+  for (;;) {
+    // We might wake up spuriously from wait, so always recalculate
+    // the timeout after a wakeup to see if we need to wait again.
+    const uint64_t now = os::elapsedTime();
+    const uint64_t remaining = expires - MIN2(expires, now);
+
+    MonitorLocker ml(&_monitor, Monitor::_no_safepoint_check_flag);
+    if (remaining > 0 && !_stop) {
+      ml.wait(remaining * MILLIUNITS);
+    } else {
+      return !_stop;
+    }
+  }
+}
+
+void ZUncommitter::run_service() {
+  for (;;) {
+    // Try uncommit unused memory
+    const uint64_t timeout = ZHeap::heap()->uncommit(ZUncommitDelay);
+
+    log_trace(gc, heap)("Uncommit Timeout: " UINT64_FORMAT "s", timeout);
+
+    // Idle until next attempt
+    if (!idle(timeout)) {
+      return;
+    }
+  }
+}
+
+void ZUncommitter::stop_service() {
+  MonitorLocker ml(&_monitor, Monitor::_no_safepoint_check_flag);
+  _stop = true;
+  ml.notify();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/gc/z/zUncommitter.hpp	Wed May 15 13:54:43 2019 +0530
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#ifndef SHARE_GC_Z_ZUNCOMMITTER_HPP
+#define SHARE_GC_Z_ZUNCOMMITTER_HPP
+
+#include "gc/shared/concurrentGCThread.hpp"
+#include "runtime/mutex.hpp"
+
+class ZUncommitter : public ConcurrentGCThread {
+private:
+  Monitor _monitor;
+  bool    _stop;
+
+  bool idle(uint64_t timeout);
+
+protected:
+  virtual void run_service();
+  virtual void stop_service();
+
+public:
+  ZUncommitter();
+};
+
+#endif // SHARE_GC_Z_ZUNCOMMITTER_HPP
--- a/src/hotspot/share/gc/z/zVirtualMemory.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zVirtualMemory.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -72,6 +72,6 @@
   return ZVirtualMemory(start, size);
 }
 
-void ZVirtualMemoryManager::free(ZVirtualMemory vmem) {
+void ZVirtualMemoryManager::free(const ZVirtualMemory& vmem) {
   _manager.free(vmem.start(), vmem.size());
 }
--- a/src/hotspot/share/gc/z/zVirtualMemory.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zVirtualMemory.hpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 #define SHARE_GC_Z_ZVIRTUALMEMORY_HPP
 
 #include "gc/z/zMemory.hpp"
-#include "memory/allocation.hpp"
 
 class ZVirtualMemory {
   friend class VMStructs;
@@ -42,8 +41,8 @@
   uintptr_t start() const;
   uintptr_t end() const;
   size_t size() const;
+
   ZVirtualMemory split(size_t size);
-  void clear();
 };
 
 class ZVirtualMemoryManager {
@@ -60,7 +59,7 @@
   bool is_initialized() const;
 
   ZVirtualMemory alloc(size_t size, bool alloc_from_front = false);
-  void free(ZVirtualMemory vmem);
+  void free(const ZVirtualMemory& vmem);
 };
 
 #endif // SHARE_GC_Z_ZVIRTUALMEMORY_HPP
--- a/src/hotspot/share/gc/z/zVirtualMemory.inline.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/zVirtualMemory.inline.hpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,16 +51,9 @@
   return _end - _start;
 }
 
-inline ZVirtualMemory ZVirtualMemory::split(size_t split_size) {
-  assert(split_size <= size(), "precondition");
-  ZVirtualMemory mem(_start, split_size);
-  _start += split_size;
-  return mem;
-}
-
-inline void ZVirtualMemory::clear() {
-  _start = UINTPTR_MAX;
-  _end = UINTPTR_MAX;
+inline ZVirtualMemory ZVirtualMemory::split(size_t size) {
+  _start += size;
+  return ZVirtualMemory(_start - size, size);
 }
 
 #endif // SHARE_GC_Z_ZVIRTUALMEMORY_INLINE_HPP
--- a/src/hotspot/share/gc/z/z_globals.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/gc/z/z_globals.hpp	Wed May 15 13:54:43 2019 +0530
@@ -56,6 +56,13 @@
   experimental(uint, ZCollectionInterval, 0,                                \
           "Force GC at a fixed time interval (in seconds)")                 \
                                                                             \
+  experimental(bool, ZUncommit, true,                                       \
+          "Uncommit unused memory")                                         \
+                                                                            \
+  experimental(uintx, ZUncommitDelay, 5 * 60,                               \
+          "Uncommit memory if it has been unused for the specified "        \
+          "amount of time (in seconds)")                                    \
+                                                                            \
   diagnostic(uint, ZStatisticsInterval, 10,                                 \
           "Time between statistics print outs (in seconds)")                \
           range(1, (uint)-1)                                                \
--- a/src/hotspot/share/interpreter/interpreterRuntime.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp	Wed May 15 13:54:43 2019 +0530
@@ -417,7 +417,7 @@
 
 JRT_ENTRY(void, InterpreterRuntime::create_exception(JavaThread* thread, char* name, char* message))
   // lookup exception klass
-  TempNewSymbol s = SymbolTable::new_symbol(name, CHECK);
+  TempNewSymbol s = SymbolTable::new_symbol(name);
   if (ProfileTraps) {
     if (s == vmSymbols::java_lang_ArithmeticException()) {
       note_trap(thread, Deoptimization::Reason_div0_check, CHECK);
@@ -436,7 +436,7 @@
   ResourceMark rm(thread);
   const char* klass_name = obj->klass()->external_name();
   // lookup exception klass
-  TempNewSymbol s = SymbolTable::new_symbol(name, CHECK);
+  TempNewSymbol s = SymbolTable::new_symbol(name);
   if (ProfileTraps) {
     note_trap(thread, Deoptimization::Reason_class_check, CHECK);
   }
--- a/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -171,8 +171,8 @@
   assert(args != NULL, "invariant");
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   assert(args->klass() != NULL, "invariant");
-  args->set_name("<init>", CHECK_NULL);
-  args->set_signature("()V", CHECK_NULL);
+  args->set_name("<init>");
+  args->set_signature("()V");
   JfrJavaSupport::new_object(args, CHECK_NULL);
   return (oop)args->result()->get_jobject();
 }
--- a/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/instrumentation/jfrEventClassTransformer.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -357,7 +357,6 @@
   }
 };
 
-static unsigned int unused_hash = 0;
 static const char value_name[] = "value";
 static bool has_annotation(const InstanceKlass* ik, const Symbol* annotation_type, bool& value) {
   assert(annotation_type != NULL, "invariant");
@@ -372,7 +371,7 @@
     if (annotation_iterator.type() == annotation_type) {
       // target annotation found
       static const Symbol* value_symbol =
-        SymbolTable::lookup_only(value_name, sizeof value_name - 1, unused_hash);
+        SymbolTable::probe(value_name, sizeof value_name - 1);
       assert(value_symbol != NULL, "invariant");
       const AnnotationElementIterator element_iterator = annotation_iterator.elements();
       while (element_iterator.has_next()) {
@@ -412,7 +411,7 @@
   }
   static Symbol* jdk_jfr_module_symbol = NULL;
   if (jdk_jfr_module_symbol == NULL) {
-    jdk_jfr_module_symbol = SymbolTable::lookup_only(jdk_jfr_module_name, sizeof jdk_jfr_module_name - 1, unused_hash);
+    jdk_jfr_module_symbol = SymbolTable::probe(jdk_jfr_module_name, sizeof jdk_jfr_module_name - 1);
     if (jdk_jfr_module_symbol == NULL) {
       return false;
     }
@@ -447,7 +446,7 @@
   assert(!untypedEventHandler, "invariant");
   static const Symbol* registered_symbol = NULL;
   if (registered_symbol == NULL) {
-    registered_symbol = SymbolTable::lookup_only(registered_constant, sizeof registered_constant - 1, unused_hash);
+    registered_symbol = SymbolTable::probe(registered_constant, sizeof registered_constant - 1);
     if (registered_symbol == NULL) {
       untypedEventHandler = true;
       return false;
@@ -1167,7 +1166,7 @@
                                 u2& added_cp_entries,
                                 TRAPS) {
   assert(utf8_constant != NULL, "invariant");
-  TempNewSymbol utf8_sym = SymbolTable::new_symbol(utf8_constant, THREAD);
+  TempNewSymbol utf8_sym = SymbolTable::new_symbol(utf8_constant);
   // lookup existing
   const int utf8_orig_idx = utf8_info_index(ik, utf8_sym, THREAD);
   if (utf8_orig_idx != invalid_cp_index) {
--- a/src/hotspot/share/jfr/jni/jfrGetAllEventClasses.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/jni/jfrGetAllEventClasses.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -134,8 +134,7 @@
   initialize(THREAD);
   assert(empty_java_util_arraylist != NULL, "should have been setup already!");
   static const char jdk_jfr_event_name[] = "jdk/internal/event/Event";
-  unsigned int unused_hash = 0;
-  Symbol* const event_klass_name = SymbolTable::lookup_only(jdk_jfr_event_name, sizeof jdk_jfr_event_name - 1, unused_hash);
+  Symbol* const event_klass_name = SymbolTable::probe(jdk_jfr_event_name, sizeof jdk_jfr_event_name - 1);
 
   if (NULL == event_klass_name) {
     // not loaded yet
@@ -168,10 +167,10 @@
   const Klass* const array_list_klass = JfrJavaSupport::klass(empty_java_util_arraylist);
   assert(array_list_klass != NULL, "invariant");
 
-  const Symbol* const add_method_sym = SymbolTable::lookup(add_method_name, sizeof add_method_name - 1, THREAD);
+  const Symbol* const add_method_sym = SymbolTable::new_symbol(add_method_name);
   assert(add_method_sym != NULL, "invariant");
 
-  const Symbol* const add_method_sig_sym = SymbolTable::lookup(add_method_signature, sizeof add_method_signature - 1, THREAD);
+  const Symbol* const add_method_sig_sym = SymbolTable::new_symbol(add_method_signature);
   assert(add_method_signature != NULL, "invariant");
 
   JavaValue result(T_BOOLEAN);
--- a/src/hotspot/share/jfr/jni/jfrJavaCall.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/jni/jfrJavaCall.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,9 +38,9 @@
 }
 #endif // ASSERT
 
-static Symbol* resolve(const char* str, TRAPS) {
+static Symbol* resolve(const char* str) {
   assert(str != NULL, "invariant");
-  return SymbolTable::lookup(str, (int)strlen(str), THREAD);
+  return SymbolTable::new_symbol(str);
 }
 
 static Klass* resolve(Symbol* k_sym, TRAPS) {
@@ -199,10 +199,10 @@
     set_klass(klass_name, CHECK);
   }
   if (name != NULL) {
-    set_name(name, CHECK);
+    set_name(name);
   }
   if (signature != NULL) {
-    set_signature(signature, THREAD);
+    set_signature(signature);
   }
 }
 
@@ -230,7 +230,7 @@
 
 void JfrJavaArguments::set_klass(const char* klass_name, TRAPS) {
   assert(klass_name != NULL, "invariant");
-  Symbol* const k_sym = resolve(klass_name, CHECK);
+  Symbol* const k_sym = resolve(klass_name);
   assert(k_sym != NULL, "invariant");
   const Klass* const klass = resolve(k_sym, CHECK);
   set_klass(klass);
@@ -246,9 +246,9 @@
   return const_cast<Symbol*>(_name);
 }
 
-void JfrJavaArguments::set_name(const char* name, TRAPS) {
+void JfrJavaArguments::set_name(const char* name) {
   assert(name != NULL, "invariant");
-  const Symbol* const sym = resolve(name, CHECK);
+  const Symbol* const sym = resolve(name);
   set_name(sym);
 }
 
@@ -262,9 +262,9 @@
   return const_cast<Symbol*>(_signature);
 }
 
-void JfrJavaArguments::set_signature(const char* signature, TRAPS) {
+void JfrJavaArguments::set_signature(const char* signature) {
   assert(signature != NULL, "invariant");
-  const Symbol* const sym = resolve(signature, CHECK);
+  const Symbol* const sym = resolve(signature);
   set_signature(sym);
 }
 
--- a/src/hotspot/share/jfr/jni/jfrJavaCall.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/jni/jfrJavaCall.hpp	Wed May 15 13:54:43 2019 +0530
@@ -47,11 +47,11 @@
   void set_klass(const Klass* klass);
 
   Symbol* name() const;
-  void set_name(const char* name, TRAPS);
+  void set_name(const char* name);
   void set_name(const Symbol* name);
 
   Symbol* signature() const;
-  void set_signature(const char* signature, TRAPS);
+  void set_signature(const char* signature);
   void set_signature(const Symbol* signature);
 
   int array_length() const;
--- a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp	Wed May 15 13:54:43 2019 +0530
@@ -579,7 +579,7 @@
 static bool is_jdk_jfr_module_in_readability_graph() {
   Thread* const t = Thread::current();
   // take one of the packages in the module to be located and query for its definition.
-  TempNewSymbol pkg_sym = SymbolTable::new_symbol(JDK_JFR_PACKAGE_NAME, t);
+  TempNewSymbol pkg_sym = SymbolTable::new_symbol(JDK_JFR_PACKAGE_NAME);
   return Modules::is_package_defined(pkg_sym, Handle(), t);
 }
 
--- a/src/hotspot/share/jfr/jni/jfrUpcalls.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/jni/jfrUpcalls.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -49,11 +49,11 @@
   static bool initialized = false;
   if (!initialized) {
     DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
-    jvm_upcalls_class_sym = SymbolTable::new_permanent_symbol("jdk/jfr/internal/JVMUpcalls", CHECK_false);
-    on_retransform_method_sym = SymbolTable::new_permanent_symbol("onRetransform", CHECK_false);
-    on_retransform_signature_sym = SymbolTable::new_permanent_symbol("(JZLjava/lang/Class;[B)[B", CHECK_false);
-    bytes_for_eager_instrumentation_sym = SymbolTable::new_permanent_symbol("bytesForEagerInstrumentation", CHECK_false);
-    bytes_for_eager_instrumentation_sig_sym = SymbolTable::new_permanent_symbol("(JZLjava/lang/Class;[B)[B", THREAD);
+    jvm_upcalls_class_sym = SymbolTable::new_permanent_symbol("jdk/jfr/internal/JVMUpcalls");
+    on_retransform_method_sym = SymbolTable::new_permanent_symbol("onRetransform");
+    on_retransform_signature_sym = SymbolTable::new_permanent_symbol("(JZLjava/lang/Class;[B)[B");
+    bytes_for_eager_instrumentation_sym = SymbolTable::new_permanent_symbol("bytesForEagerInstrumentation");
+    bytes_for_eager_instrumentation_sig_sym = SymbolTable::new_permanent_symbol("(JZLjava/lang/Class;[B)[B");
     initialized = bytes_for_eager_instrumentation_sig_sym != NULL;
   }
   return initialized;
--- a/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/leakprofiler/checkpoint/objectSampleDescription.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -91,7 +91,7 @@
 
 void ObjectSampleDescription::ensure_initialized() {
   if (symbol_size == NULL) {
-    symbol_size = SymbolTable::new_permanent_symbol("size", Thread::current());
+    symbol_size = SymbolTable::new_permanent_symbol("size");
   }
 }
 
--- a/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/recorder/checkpoint/types/traceid/jfrTraceId.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -87,14 +87,14 @@
   static const Symbol* jdk_internal_event_sym = NULL;
   if (jdk_internal_event_sym == NULL) {
     // setup when loading the first TypeArrayKlass (Universe::genesis) hence single threaded invariant
-    jdk_internal_event_sym = SymbolTable::new_permanent_symbol("jdk/internal/event/Event", Thread::current());
+    jdk_internal_event_sym = SymbolTable::new_permanent_symbol("jdk/internal/event/Event");
   }
   assert(jdk_internal_event_sym != NULL, "invariant");
 
   static const Symbol* jdk_jfr_event_sym = NULL;
   if (jdk_jfr_event_sym == NULL) {
     // setup when loading the first TypeArrayKlass (Universe::genesis) hence single threaded invariant
-    jdk_jfr_event_sym = SymbolTable::new_permanent_symbol("jdk/jfr/Event", Thread::current());
+    jdk_jfr_event_sym = SymbolTable::new_permanent_symbol("jdk/jfr/Event");
   }
   assert(jdk_jfr_event_sym != NULL, "invariant");
   const Symbol* const klass_name = klass->name();
--- a/src/hotspot/share/jfr/utilities/jfrJavaLog.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/utilities/jfrJavaLog.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,8 +62,8 @@
   JavaValue result(T_VOID);
   JfrJavaArguments args(&result);
   args.set_klass(JfrJavaSupport::klass(lt));
-  args.set_name("tagSetLevel", CHECK);
-  args.set_signature("I", CHECK);
+  args.set_name("tagSetLevel");
+  args.set_signature("I");
   args.set_receiver(JfrJavaSupport::resolve_non_null(lt));
   args.push_int(llt);
   JfrJavaSupport::set_field(&args, THREAD);
--- a/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp	Wed May 15 13:54:43 2019 +0530
@@ -76,55 +76,55 @@
 
 static bool setup_event_writer_offsets(TRAPS) {
   const char class_name[] = "jdk/jfr/internal/EventWriter";
-  Symbol* const k_sym = SymbolTable::lookup(class_name, sizeof class_name - 1, CHECK_false);
+  Symbol* const k_sym = SymbolTable::new_symbol(class_name);
   assert(k_sym != NULL, "invariant");
   Klass* klass = SystemDictionary::resolve_or_fail(k_sym, true, CHECK_false);
   assert(klass != NULL, "invariant");
 
   const char start_pos_name[] = "startPosition";
-  Symbol* const start_pos_sym = SymbolTable::lookup(start_pos_name, sizeof start_pos_name - 1, CHECK_false);
+  Symbol* const start_pos_sym = SymbolTable::new_symbol(start_pos_name);
   assert(start_pos_sym != NULL, "invariant");
   assert(invalid_offset == start_pos_offset, "invariant");
   compute_offset(start_pos_offset, klass, start_pos_sym, vmSymbols::long_signature());
   assert(start_pos_offset != invalid_offset, "invariant");
 
   const char start_pos_address_name[] = "startPositionAddress";
-  Symbol* const start_pos_address_sym = SymbolTable::lookup(start_pos_address_name, sizeof start_pos_address_name - 1, CHECK_false);
+  Symbol* const start_pos_address_sym = SymbolTable::new_symbol(start_pos_address_name);
   assert(start_pos_address_sym != NULL, "invariant");
   assert(invalid_offset == start_pos_address_offset, "invariant");
   compute_offset(start_pos_address_offset, klass, start_pos_address_sym, vmSymbols::long_signature());
   assert(start_pos_address_offset != invalid_offset, "invariant");
 
   const char event_pos_name[] = "currentPosition";
-  Symbol* const event_pos_sym = SymbolTable::lookup(event_pos_name, sizeof event_pos_name - 1, CHECK_false);
+  Symbol* const event_pos_sym = SymbolTable::new_symbol(event_pos_name);
   assert(event_pos_sym != NULL, "invariant");
   assert(invalid_offset == current_pos_offset, "invariant");
   compute_offset(current_pos_offset, klass, event_pos_sym,vmSymbols::long_signature());
   assert(current_pos_offset != invalid_offset, "invariant");
 
   const char max_pos_name[] = "maxPosition";
-  Symbol* const max_pos_sym = SymbolTable::lookup(max_pos_name, sizeof max_pos_name - 1, CHECK_false);
+  Symbol* const max_pos_sym = SymbolTable::new_symbol(max_pos_name);
   assert(max_pos_sym != NULL, "invariant");
   assert(invalid_offset == max_pos_offset, "invariant");
   compute_offset(max_pos_offset, klass, max_pos_sym, vmSymbols::long_signature());
   assert(max_pos_offset != invalid_offset, "invariant");
 
   const char max_event_size_name[] = "maxEventSize";
-  Symbol* const max_event_size_sym = SymbolTable::lookup(max_event_size_name, sizeof max_event_size_name - 1, CHECK_false);
+  Symbol* const max_event_size_sym = SymbolTable::new_symbol(max_event_size_name);
   assert (max_event_size_sym != NULL, "invariant");
   assert(invalid_offset == max_event_size_offset, "invariant");
   compute_offset(max_event_size_offset, klass, max_event_size_sym, vmSymbols::int_signature());
   assert(max_event_size_offset != invalid_offset, "invariant");
 
   const char notified_name[] = "notified";
-  Symbol* const notified_sym = SymbolTable::lookup(notified_name, sizeof notified_name - 1, CHECK_false);
+  Symbol* const notified_sym = SymbolTable::new_symbol(notified_name);
   assert (notified_sym != NULL, "invariant");
   assert(invalid_offset == notified_offset, "invariant");
   compute_offset(notified_offset, klass, notified_sym, vmSymbols::bool_signature());
   assert(notified_offset != invalid_offset, "invariant");
 
   const char valid_name[] = "valid";
-  Symbol* const valid_sym = SymbolTable::lookup(valid_name, sizeof valid_name - 1, CHECK_false);
+  Symbol* const valid_sym = SymbolTable::new_symbol(valid_name);
   assert (valid_sym != NULL, "invariant");
   assert(invalid_offset == valid_offset, "invariant");
   compute_offset(valid_offset, klass, valid_sym, vmSymbols::bool_signature());
--- a/src/hotspot/share/jvmci/compilerRuntime.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jvmci/compilerRuntime.cpp	Wed May 15 13:54:43 2019 +0530
@@ -45,8 +45,7 @@
       // First 2 bytes of name contains length (number of bytes).
       int len = Bytes::get_Java_u2((address)name);
       name += 2;
-      TempNewSymbol sym = SymbolTable::new_symbol(name, len, CHECK);
-      str = StringTable::intern(sym, CHECK);
+      str = StringTable::intern(name, CHECK);
       assert(java_lang_String::is_instance(str), "must be string");
       *(oop*)string_result = str; // Store result
     }
@@ -78,7 +77,7 @@
     name++;
     len -= 2;
   }
-  TempNewSymbol sym = SymbolTable::new_symbol(name, len, CHECK_NULL);
+  TempNewSymbol sym = SymbolTable::new_symbol(name, len);
   if (sym == NULL) {
     return NULL;
   }
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp	Wed May 15 13:54:43 2019 +0530
@@ -506,7 +506,7 @@
 C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, jclass accessing_class, jboolean resolve))
   JVMCIObject name = JVMCIENV->wrap(jname);
   const char* str = JVMCIENV->as_utf8_string(name);
-  TempNewSymbol class_name = SymbolTable::new_symbol(str, CHECK_NULL);
+  TempNewSymbol class_name = SymbolTable::new_symbol(str);
 
   if (class_name->utf8_length() <= 1) {
     JVMCI_THROW_MSG_0(InternalError, err_msg("Primitive type %s should be handled in Java code", class_name->as_C_string()));
@@ -537,8 +537,7 @@
       // This is a name from a signature.  Strip off the trimmings.
       // Call recursive to keep scope of strippedsym.
       TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1,
-                                                          class_name->utf8_length()-2,
-                                                          CHECK_0);
+                                                          class_name->utf8_length()-2);
       resolved_klass = SystemDictionary::find(strippedsym, class_loader, protection_domain, CHECK_0);
     } else if (FieldType::is_array(class_name)) {
       FieldArrayInfo fd;
@@ -547,8 +546,7 @@
       BasicType t = FieldType::get_array_info(class_name, fd, CHECK_0);
       if (t == T_OBJECT) {
         TempNewSymbol strippedsym = SymbolTable::new_symbol(class_name->as_utf8()+1+fd.dimension(),
-                                                            class_name->utf8_length()-2-fd.dimension(),
-                                                            CHECK_0);
+                                                            class_name->utf8_length()-2-fd.dimension());
         resolved_klass = SystemDictionary::find(strippedsym,
                                                              class_loader,
                                                              protection_domain,
@@ -1762,7 +1760,7 @@
 C2V_VMENTRY(void, compileToBytecode, (JNIEnv* env, jobject, jobject lambda_form_handle))
   Handle lambda_form = JVMCIENV->asConstant(JVMCIENV->wrap(lambda_form_handle), JVMCI_CHECK);
   if (lambda_form->is_a(SystemDictionary::LambdaForm_klass())) {
-    TempNewSymbol compileToBytecode = SymbolTable::new_symbol("compileToBytecode", CHECK);
+    TempNewSymbol compileToBytecode = SymbolTable::new_symbol("compileToBytecode");
     JavaValue result(T_VOID);
     JavaCalls::call_special(&result, lambda_form, SystemDictionary::LambdaForm_klass(), compileToBytecode, vmSymbols::void_method_signature(), CHECK);
   } else {
--- a/src/hotspot/share/jvmci/jvmciEnv.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jvmci/jvmciEnv.cpp	Wed May 15 13:54:43 2019 +0530
@@ -92,7 +92,7 @@
   }
 
   // Get the serialized saved properties from HotSpot
-  TempNewSymbol serializeSavedProperties = SymbolTable::new_symbol("serializeSavedProperties", CHECK_EXIT);
+  TempNewSymbol serializeSavedProperties = SymbolTable::new_symbol("serializeSavedProperties");
   JavaValue result(T_OBJECT);
   JavaCallArguments args;
   JavaCalls::call_static(&result, ik, serializeSavedProperties, vmSymbols::serializePropertiesToByteArray_signature(), &args, THREAD);
--- a/src/hotspot/share/jvmci/jvmciJavaClasses.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jvmci/jvmciJavaClasses.cpp	Wed May 15 13:54:43 2019 +0530
@@ -139,7 +139,7 @@
 #define METHOD(jniCallType, jniGetMethod, hsCallType, returnType, className, methodName, signatureSymbolName, args) \
   check_resolve_method(#hsCallType, k, vmSymbols::methodName##_name(), vmSymbols::signatureSymbolName(), CHECK);
 #define CONSTRUCTOR(className, signature) { \
-  TempNewSymbol sig = SymbolTable::new_symbol(signature, CHECK); \
+  TempNewSymbol sig = SymbolTable::new_symbol(signature); \
   check_resolve_method("call_special", k, vmSymbols::object_initializer_name(), sig, CHECK); \
   }
 #endif
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Wed May 15 13:54:43 2019 +0530
@@ -469,20 +469,20 @@
 JRT_END
 
 JRT_ENTRY(void, JVMCIRuntime::throw_and_post_jvmti_exception(JavaThread* thread, const char* exception, const char* message))
-  TempNewSymbol symbol = SymbolTable::new_symbol(exception, CHECK);
+  TempNewSymbol symbol = SymbolTable::new_symbol(exception);
   SharedRuntime::throw_and_post_jvmti_exception(thread, symbol, message);
 JRT_END
 
 JRT_ENTRY(void, JVMCIRuntime::throw_klass_external_name_exception(JavaThread* thread, const char* exception, Klass* klass))
   ResourceMark rm(thread);
-  TempNewSymbol symbol = SymbolTable::new_symbol(exception, CHECK);
+  TempNewSymbol symbol = SymbolTable::new_symbol(exception);
   SharedRuntime::throw_and_post_jvmti_exception(thread, symbol, klass->external_name());
 JRT_END
 
 JRT_ENTRY(void, JVMCIRuntime::throw_class_cast_exception(JavaThread* thread, const char* exception, Klass* caster_klass, Klass* target_klass))
   ResourceMark rm(thread);
   const char* message = SharedRuntime::generate_class_cast_message(caster_klass, target_klass);
-  TempNewSymbol symbol = SymbolTable::new_symbol(exception, CHECK);
+  TempNewSymbol symbol = SymbolTable::new_symbol(exception);
   SharedRuntime::throw_and_post_jvmti_exception(thread, symbol, message);
 JRT_END
 
@@ -1011,8 +1011,7 @@
     // This is a name from a signature.  Strip off the trimmings.
     // Call recursive to keep scope of strippedsym.
     TempNewSymbol strippedsym = SymbolTable::new_symbol(sym->as_utf8()+1,
-                    sym->utf8_length()-2,
-                    CHECK_NULL);
+                                                        sym->utf8_length()-2);
     return get_klass_by_name_impl(accessing_klass, cpool, strippedsym, require_local);
   }
 
@@ -1045,8 +1044,7 @@
     // We have an unloaded array.
     // Build it on the fly if the element class exists.
     TempNewSymbol elem_sym = SymbolTable::new_symbol(sym->as_utf8()+1,
-                                                 sym->utf8_length()-1,
-                                                 CHECK_NULL);
+                                                     sym->utf8_length()-1);
 
     // Get element Klass recursively.
     Klass* elem_klass =
--- a/src/hotspot/share/logging/logPrefix.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/logging/logPrefix.hpp	Wed May 15 13:54:43 2019 +0530
@@ -71,6 +71,8 @@
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, ref)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, start)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, task)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, verify)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, phases, verify, start)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, plab)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, promotion)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, region)) \
@@ -88,6 +90,8 @@
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, task, time)) \
   DEBUG_ONLY(LOG_PREFIX(Test_log_prefix_prefixer, LOG_TAGS(logging, test))) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, tlab)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, verify)) \
+  LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, verify, start)) \
   LOG_PREFIX(GCId::print_prefix, LOG_TAGS(gc, workgang))
 
 
--- a/src/hotspot/share/memory/filemap.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/memory/filemap.cpp	Wed May 15 13:54:43 2019 +0530
@@ -877,7 +877,7 @@
   MemTracker::record_virtual_memory_type((address)base, mtClassShared);
 #endif
 
-  if (!verify_region_checksum(i)) {
+  if (VerifySharedSpaces && !verify_region_checksum(i)) {
     return NULL;
   }
 
@@ -1143,9 +1143,11 @@
 
 bool FileMapInfo::verify_mapped_heap_regions(int first, int num) {
   assert(num > 0, "sanity");
-  for (int i = first; i < first + num; i++) {
-    if (!verify_region_checksum(i)) {
-      return false;
+  if (VerifySharedSpaces) {
+    for (int i = first; i < first + num; i++) {
+      if (!verify_region_checksum(i)) {
+        return false;
+      }
     }
   }
   return true;
@@ -1204,9 +1206,7 @@
 #endif // INCLUDE_CDS_JAVA_HEAP
 
 bool FileMapInfo::verify_region_checksum(int i) {
-  if (!VerifySharedSpaces) {
-    return true;
-  }
+  assert(VerifySharedSpaces, "sanity");
 
   size_t sz = space_at(i)->_used;
 
--- a/src/hotspot/share/memory/heapShared.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/memory/heapShared.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -884,8 +884,8 @@
                                             int num, Thread* THREAD) {
   for (int i = 0; i < num; i++) {
     ArchivableStaticFieldInfo* info = &fields[i];
-    TempNewSymbol klass_name =  SymbolTable::new_symbol(info->klass_name, THREAD);
-    TempNewSymbol field_name =  SymbolTable::new_symbol(info->field_name, THREAD);
+    TempNewSymbol klass_name =  SymbolTable::new_symbol(info->klass_name);
+    TempNewSymbol field_name =  SymbolTable::new_symbol(info->field_name);
 
     Klass* k = SystemDictionary::resolve_or_null(klass_name, THREAD);
     assert(k != NULL && !HAS_PENDING_EXCEPTION, "class must exist");
--- a/src/hotspot/share/memory/metaspace.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/memory/metaspace.cpp	Wed May 15 13:54:43 2019 +0530
@@ -47,6 +47,7 @@
 #include "utilities/debug.hpp"
 #include "utilities/formatBuffer.hpp"
 #include "utilities/globalDefinitions.hpp"
+#include "utilities/vmError.hpp"
 
 
 using namespace metaspace;
@@ -917,31 +918,6 @@
 #endif
 }
 
-// Utils to check if a pointer or range is part of a committed metaspace region.
-metaspace::VirtualSpaceNode* MetaspaceUtils::find_enclosing_virtual_space(const void* p) {
-  MutexLocker cl(MetaspaceExpand_lock, Mutex::_no_safepoint_check_flag);
-  VirtualSpaceNode* vsn = Metaspace::space_list()->find_enclosing_space(p);
-  if (Metaspace::using_class_space() && vsn == NULL) {
-    vsn = Metaspace::class_space_list()->find_enclosing_space(p);
-  }
-  return vsn;
-}
-
-bool MetaspaceUtils::is_range_in_committed(const void* from, const void* to) {
-#if INCLUDE_CDS
-  if (UseSharedSpaces) {
-    for (int idx = MetaspaceShared::ro; idx <= MetaspaceShared::mc; idx++) {
-      if (FileMapInfo::current_info()->is_in_shared_region(from, idx)) {
-        return FileMapInfo::current_info()->is_in_shared_region(to, idx);
-      }
-    }
-  }
-#endif
-  VirtualSpaceNode* vsn = find_enclosing_virtual_space(from);
-  return (vsn != NULL) && vsn->contains(to);
-}
-
-
 // Metaspace methods
 
 size_t Metaspace::_first_chunk_word_size = 0;
--- a/src/hotspot/share/memory/metaspace.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/memory/metaspace.hpp	Wed May 15 13:54:43 2019 +0530
@@ -329,11 +329,6 @@
   // Helper for print_xx_report.
   static void print_vs(outputStream* out, size_t scale);
 
-  // Utils to check if a pointer or range is part of a committed metaspace region
-  // without acquiring any locks.
-  static metaspace::VirtualSpaceNode* find_enclosing_virtual_space(const void* p);
-  static bool is_range_in_committed(const void* from, const void* to);
-
 public:
 
   // Collect used metaspace statistics. This involves walking the CLDG. The resulting
--- a/src/hotspot/share/memory/metaspaceShared.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/memory/metaspaceShared.cpp	Wed May 15 13:54:43 2019 +0530
@@ -371,7 +371,7 @@
     utf8_buffer[utf8_length] = '\0';
 
     if (prefix_type == HashtableTextDump::SymbolPrefix) {
-      SymbolTable::new_permanent_symbol(utf8_buffer, THREAD);
+      SymbolTable::new_permanent_symbol(utf8_buffer);
     } else{
       assert(prefix_type == HashtableTextDump::StringPrefix, "Sanity");
       oop s = StringTable::intern(utf8_buffer, THREAD);
--- a/src/hotspot/share/memory/universe.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/memory/universe.cpp	Wed May 15 13:54:43 2019 +0530
@@ -807,7 +807,7 @@
                              Symbol* signature,
                              bool is_static, TRAPS)
 {
-  TempNewSymbol name = SymbolTable::new_symbol(method, CHECK);
+  TempNewSymbol name = SymbolTable::new_symbol(method);
   Method* m = NULL;
   // The klass must be linked before looking up the method.
   if (!ik->link_class_or_fail(THREAD) ||
--- a/src/hotspot/share/oops/instanceKlass.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/oops/instanceKlass.cpp	Wed May 15 13:54:43 2019 +0530
@@ -2611,7 +2611,7 @@
     if (package_name == NULL) {
       return NULL;
     }
-    Symbol* pkg_name = SymbolTable::new_symbol(package_name, THREAD);
+    Symbol* pkg_name = SymbolTable::new_symbol(package_name);
     return pkg_name;
   }
 }
--- a/src/hotspot/share/oops/klass.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/oops/klass.cpp	Wed May 15 13:54:43 2019 +0530
@@ -813,7 +813,7 @@
   if ((size_t)k < os::min_page_size()) return false;
 
   if (!os::is_readable_range(k, k + 1)) return false;
-  if (!MetaspaceUtils::is_range_in_committed(k, k + 1)) return false;
+  if (!Metaspace::contains(k)) return false;
 
   if (!Symbol::is_valid(k->name())) return false;
   return ClassLoaderDataGraph::is_valid(k->class_loader_data());
--- a/src/hotspot/share/oops/klass.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/oops/klass.hpp	Wed May 15 13:54:43 2019 +0530
@@ -333,6 +333,7 @@
   static ByteSize secondary_super_cache_offset() { return in_ByteSize(offset_of(Klass, _secondary_super_cache)); }
   static ByteSize secondary_supers_offset()      { return in_ByteSize(offset_of(Klass, _secondary_supers)); }
   static ByteSize java_mirror_offset()           { return in_ByteSize(offset_of(Klass, _java_mirror)); }
+  static ByteSize class_loader_data_offset()     { return in_ByteSize(offset_of(Klass, _class_loader_data)); }
   static ByteSize modifier_flags_offset()        { return in_ByteSize(offset_of(Klass, _modifier_flags)); }
   static ByteSize layout_helper_offset()         { return in_ByteSize(offset_of(Klass, _layout_helper)); }
   static ByteSize access_flags_offset()          { return in_ByteSize(offset_of(Klass, _access_flags)); }
--- a/src/hotspot/share/oops/method.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/oops/method.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1579,7 +1579,7 @@
   Symbol*  signature = m->signature();
   for(SignatureStream ss(signature); !ss.is_done(); ss.next()) {
     if (ss.is_object()) {
-      Symbol* sym = ss.as_symbol(CHECK_(false));
+      Symbol* sym = ss.as_symbol();
       Symbol*  name  = sym;
       Klass* klass = SystemDictionary::resolve_or_null(name, class_loader,
                                              protection_domain, THREAD);
--- a/src/hotspot/share/oops/objArrayKlass.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/oops/objArrayKlass.cpp	Wed May 15 13:54:43 2019 +0530
@@ -116,7 +116,7 @@
       new_str[idx++] = ';';
     }
     new_str[idx++] = '\0';
-    name = SymbolTable::new_permanent_symbol(new_str, CHECK_0);
+    name = SymbolTable::new_permanent_symbol(new_str);
     if (element_klass->is_instance_klass()) {
       InstanceKlass* ik = InstanceKlass::cast(element_klass);
       ik->set_array_name(name);
--- a/src/hotspot/share/oops/oop.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/oops/oop.cpp	Wed May 15 13:54:43 2019 +0530
@@ -182,9 +182,7 @@
   if (!Universe::heap()->is_in(obj)) return false;
 
   Klass* k = (Klass*)load_klass_raw(obj);
-
-  if (!os::is_readable_range(k, k + 1)) return false;
-  return MetaspaceUtils::is_range_in_committed(k, k + 1);
+  return Klass::is_valid(k);
 }
 
 oop oopDesc::oop_or_null(address addr) {
--- a/src/hotspot/share/oops/symbol.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/oops/symbol.cpp	Wed May 15 13:54:43 2019 +0530
@@ -57,13 +57,13 @@
   }
 }
 
-void* Symbol::operator new(size_t sz, int len, TRAPS) throw() {
+void* Symbol::operator new(size_t sz, int len) throw() {
   int alloc_size = size(len)*wordSize;
   address res = (address) AllocateHeap(alloc_size, mtSymbol);
   return res;
 }
 
-void* Symbol::operator new(size_t sz, int len, Arena* arena, TRAPS) throw() {
+void* Symbol::operator new(size_t sz, int len, Arena* arena) throw() {
   int alloc_size = size(len)*wordSize;
   address res = (address)arena->Amalloc_4(alloc_size);
   return res;
--- a/src/hotspot/share/oops/symbol.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/oops/symbol.hpp	Wed May 15 13:54:43 2019 +0530
@@ -132,8 +132,8 @@
   }
 
   Symbol(const u1* name, int length, int refcount);
-  void* operator new(size_t size, int len, TRAPS) throw();
-  void* operator new(size_t size, int len, Arena* arena, TRAPS) throw();
+  void* operator new(size_t size, int len) throw();
+  void* operator new(size_t size, int len, Arena* arena) throw();
 
   void  operator delete(void* p);
 
--- a/src/hotspot/share/oops/typeArrayKlass.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/oops/typeArrayKlass.cpp	Wed May 15 13:54:43 2019 +0530
@@ -47,7 +47,7 @@
                                       const char* name_str, TRAPS) {
   Symbol* sym = NULL;
   if (name_str != NULL) {
-    sym = SymbolTable::new_permanent_symbol(name_str, CHECK_NULL);
+    sym = SymbolTable::new_permanent_symbol(name_str);
   }
 
   ClassLoaderData* null_loader_data = ClassLoaderData::the_null_class_loader_data();
--- a/src/hotspot/share/prims/jni.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/jni.cpp	Wed May 15 13:54:43 2019 +0530
@@ -329,7 +329,7 @@
                          name);
       return 0;
     }
-    class_name = SymbolTable::new_symbol(name, CHECK_NULL);
+    class_name = SymbolTable::new_symbol(name);
   }
   ResourceMark rm(THREAD);
   ClassFileStream st((u1*)buf, bufLen, NULL, ClassFileStream::verify);
@@ -416,7 +416,7 @@
     }
   }
 
-  TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);
+  TempNewSymbol sym = SymbolTable::new_symbol(name);
   result = find_class_from_class_loader(env, sym, true, loader,
                                         protection_domain, true, thread);
 
@@ -3288,7 +3288,7 @@
   Handle loader;            // null (bootstrap) loader
   Handle protection_domain; // null protection domain
 
-  TempNewSymbol sym = SymbolTable::new_symbol(name, CHECK_NULL);
+  TempNewSymbol sym = SymbolTable::new_symbol(name);
   jclass result =  find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL);
 
   if (log_is_enabled(Debug, class, resolve) && result != NULL) {
--- a/src/hotspot/share/prims/jvm.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/jvm.cpp	Wed May 15 13:54:43 2019 +0530
@@ -138,9 +138,9 @@
     vframeStream vfst(jthread);
 
     // scan up the stack skipping ClassLoader, AccessController and PrivilegedAction frames
-    TempNewSymbol access_controller = SymbolTable::new_symbol("java/security/AccessController", CHECK);
+    TempNewSymbol access_controller = SymbolTable::new_symbol("java/security/AccessController");
     Klass* access_controller_klass = SystemDictionary::resolve_or_fail(access_controller, false, CHECK);
-    TempNewSymbol privileged_action = SymbolTable::new_symbol("java/security/PrivilegedAction", CHECK);
+    TempNewSymbol privileged_action = SymbolTable::new_symbol("java/security/PrivilegedAction");
     Klass* privileged_action_klass = SystemDictionary::resolve_or_fail(privileged_action, false, CHECK);
 
     Method* last_caller = NULL;
@@ -786,7 +786,7 @@
     return NULL;
   }
 
-  TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);
+  TempNewSymbol h_name = SymbolTable::new_symbol(name);
   Klass* k = SystemDictionary::resolve_or_null(h_name, CHECK_NULL);
   if (k == NULL) {
     return NULL;
@@ -810,7 +810,7 @@
     THROW_MSG_0(vmSymbols::java_lang_ClassNotFoundException(), name);
   }
 
-  TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);
+  TempNewSymbol h_name = SymbolTable::new_symbol(name);
 
   oop loader_oop = JNIHandles::resolve(loader);
   oop from_class = JNIHandles::resolve(caller);
@@ -852,7 +852,7 @@
                        name);
     return 0;
   }
-  TempNewSymbol h_name = SymbolTable::new_symbol(name, CHECK_NULL);
+  TempNewSymbol h_name = SymbolTable::new_symbol(name);
   oop from_class_oop = JNIHandles::resolve(from);
   Klass* from_class = (from_class_oop == NULL)
                            ? (Klass*)NULL
@@ -933,7 +933,7 @@
                          name);
       return 0;
     }
-    class_name = SymbolTable::new_symbol(name, str_len, CHECK_NULL);
+    class_name = SymbolTable::new_symbol(name, str_len);
   }
 
   ResourceMark rm(THREAD);
@@ -989,7 +989,7 @@
     // into the constant pool.
     return NULL;
   }
-  TempNewSymbol klass_name = SymbolTable::new_symbol(str, str_len, CHECK_NULL);
+  TempNewSymbol klass_name = SymbolTable::new_symbol(str, str_len);
 
   // Security Note:
   //   The Java level wrapper will perform the necessary security check allowing
--- a/src/hotspot/share/prims/jvmti.xml	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/jvmti.xml	Wed May 15 13:54:43 2019 +0530
@@ -26,10 +26,7 @@
 <!DOCTYPE specification [
    <!ELEMENT specification (title, intro*, functionsection, errorsection,
                             eventsection, datasection, issuessection, changehistory)>
-   <!ATTLIST specification label CDATA #REQUIRED
-                           majorversion CDATA #REQUIRED
-                           minorversion CDATA #REQUIRED
-                           microversion CDATA #REQUIRED>
+   <!ATTLIST specification label CDATA #REQUIRED>
 
    <!ELEMENT title (#PCDATA|jvmti|tm)*>
    <!ATTLIST title subtitle CDATA #REQUIRED>
@@ -357,10 +354,7 @@
    <!ELEMENT li  ANY>
  ]>
 
-<specification label="JVM(TM) Tool Interface"
-        majorversion="11"
-        minorversion="0"
-        microversion="0">
+<specification label="JVM(TM) Tool Interface">
   <title subtitle="Version">
     <tm>JVM</tm> Tool Interface
   </title>
--- a/src/hotspot/share/prims/jvmti.xsl	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/jvmti.xsl	Wed May 15 13:54:43 2019 +0530
@@ -1899,12 +1899,20 @@
   </dd>
 </xsl:template>
 
+<xsl:template name="lastchangeversion">
+  <xsl:for-each select="//change">
+     <xsl:if test="position() = last()">
+       <xsl:value-of select="@version"/>
+     </xsl:if>
+  </xsl:for-each>
+</xsl:template>
+
 <xsl:template match="changehistory">
     <div class="sep"/>
     <hr class="thick"/>
     <h2>Change History</h2>
     Last update: <xsl:value-of select="@update"/><br/>
-    Version: <xsl:call-template name="showversion"/>
+    Version: <xsl:call-template name="lastchangeversion"/>
     <div class="sep"/>
     <xsl:apply-templates select="intro"/>
     <div class="sep"/>
--- a/src/hotspot/share/prims/jvmtiExport.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/jvmtiExport.cpp	Wed May 15 13:54:43 2019 +0530
@@ -383,7 +383,10 @@
       }
       break;
     default:
-      return JNI_EVERSION;  // unsupported major version number
+      // Starting from 13 we do not care about minor version anymore
+      if (major < 13 || major > Abstract_VM_Version::vm_major_version()) {
+        return JNI_EVERSION;  // unsupported major version number
+      }
   }
 
   if (JvmtiEnv::get_phase() == JVMTI_PHASE_LIVE) {
--- a/src/hotspot/share/prims/jvmtiH.xsl	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/jvmtiH.xsl	Wed May 15 13:54:43 2019 +0530
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
- Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
  This code is free software; you can redistribute it and/or modify it
@@ -117,10 +117,10 @@
     JVMTI_VERSION_11  = 0x300B0000,
 
     JVMTI_VERSION = 0x30000000 + (</xsl:text>
-  <xsl:value-of select="//specification/@majorversion"/>
+  <xsl:value-of select="$majorversion"/>
   <xsl:text> * 0x10000) + (</xsl:text>
-  <xsl:value-of select="//specification/@minorversion"/>
-  <xsl:text> * 0x100)</xsl:text>
+  <!-- Now minorversion is always 0 -->
+  <xsl:text> 0 * 0x100)</xsl:text>
   <xsl:variable name="micro">
     <xsl:call-template name="microversion"/>
   </xsl:variable>
--- a/src/hotspot/share/prims/jvmtiImpl.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/jvmtiImpl.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -609,7 +609,7 @@
     ty_sign++;
     len -= 2;
   }
-  TempNewSymbol ty_sym = SymbolTable::new_symbol(ty_sign, len, thread);
+  TempNewSymbol ty_sym = SymbolTable::new_symbol(ty_sign, len);
   if (klass->name() == ty_sym) {
     return true;
   }
--- a/src/hotspot/share/prims/jvmtiLib.xsl	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/jvmtiLib.xsl	Wed May 15 13:54:43 2019 +0530
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
 
- Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved.
  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
  This code is free software; you can redistribute it and/or modify it
@@ -27,14 +27,17 @@
 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                 version="1.0">
 
+  <xsl:param name="majorversion"></xsl:param>
+
   <xsl:template name="microversion">
-    <xsl:value-of select="//specification/@microversion"/>
+    <!-- Now microversion is always 0 -->
+    <xsl:text>0</xsl:text>
   </xsl:template>
 
   <xsl:template name="showbasicversion">
-    <xsl:value-of select="//specification/@majorversion"/>
-    <xsl:text>.</xsl:text>
-    <xsl:value-of select="//specification/@minorversion"/>
+    <xsl:value-of select="$majorversion"/>
+    <!-- Now minorversion is always 0 -->
+    <xsl:text>.0</xsl:text>
   </xsl:template>
 
   <xsl:template name="showversion">
--- a/src/hotspot/share/prims/methodHandles.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/methodHandles.cpp	Wed May 15 13:54:43 2019 +0530
@@ -519,12 +519,12 @@
 // convert the external string or reflective type to an internal signature
 Symbol* MethodHandles::lookup_signature(oop type_str, bool intern_if_not_found, TRAPS) {
   if (java_lang_invoke_MethodType::is_instance(type_str)) {
-    return java_lang_invoke_MethodType::as_signature(type_str, intern_if_not_found, THREAD);
+    return java_lang_invoke_MethodType::as_signature(type_str, intern_if_not_found);
   } else if (java_lang_Class::is_instance(type_str)) {
-    return java_lang_Class::as_signature(type_str, false, THREAD);
+    return java_lang_Class::as_signature(type_str, false);
   } else if (java_lang_String::is_instance_inlined(type_str)) {
     if (intern_if_not_found) {
-      return java_lang_String::as_symbol(type_str, THREAD);
+      return java_lang_String::as_symbol(type_str);
     } else {
       return java_lang_String::as_symbol_or_null(type_str);
     }
@@ -602,7 +602,7 @@
     }
     const char* sigstr =       buffer.base();
     int         siglen = (int) buffer.size();
-    bsig = SymbolTable::new_symbol(sigstr, siglen, THREAD);
+    bsig = SymbolTable::new_symbol(sigstr, siglen);
   }
   assert(is_basic_type_signature(bsig) ||
          // detune assert in case the injected argument is not a basic type:
--- a/src/hotspot/share/prims/nativeLookup.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/nativeLookup.cpp	Wed May 15 13:54:43 2019 +0530
@@ -407,9 +407,9 @@
 address NativeLookup::base_library_lookup(const char* class_name, const char* method_name, const char* signature) {
   EXCEPTION_MARK;
   bool in_base_library = true;  // SharedRuntime inits some math methods.
-  TempNewSymbol c_name = SymbolTable::new_symbol(class_name,  CATCH);
-  TempNewSymbol m_name = SymbolTable::new_symbol(method_name, CATCH);
-  TempNewSymbol s_name = SymbolTable::new_symbol(signature,   CATCH);
+  TempNewSymbol c_name = SymbolTable::new_symbol(class_name);
+  TempNewSymbol m_name = SymbolTable::new_symbol(method_name);
+  TempNewSymbol s_name = SymbolTable::new_symbol(signature);
 
   // Find the class
   Klass* k = SystemDictionary::resolve_or_fail(c_name, true, CATCH);
--- a/src/hotspot/share/prims/wbtestmethods/parserTests.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/wbtestmethods/parserTests.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -51,7 +51,7 @@
 static const char* lookup_diagnosticArgumentEnum(const char* field_name, oop object) {
   Thread* THREAD = Thread::current();
   const char* enum_sig = "Lsun/hotspot/parser/DiagnosticCommand$DiagnosticArgumentType;";
-  TempNewSymbol enumSigSymbol = SymbolTable::lookup(enum_sig, (int) strlen(enum_sig), THREAD);
+  TempNewSymbol enumSigSymbol = SymbolTable::new_symbol(enum_sig);
   int offset = WhiteBox::offset_for_field(field_name, object, enumSigSymbol);
   oop enumOop = object->obj_field(offset);
 
--- a/src/hotspot/share/prims/whitebox.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/prims/whitebox.cpp	Wed May 15 13:54:43 2019 +0530
@@ -179,7 +179,7 @@
 WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name))
   oop h_name = JNIHandles::resolve(name);
   if (h_name == NULL) return false;
-  Symbol* sym = java_lang_String::as_symbol(h_name, CHECK_false);
+  Symbol* sym = java_lang_String::as_symbol(h_name);
   TempNewSymbol tsym(sym); // Make sure to decrement reference count on sym on return
 
   WBIsKlassAliveClosure closure(sym);
@@ -191,7 +191,7 @@
 WB_ENTRY(jint, WB_GetSymbolRefcount(JNIEnv* env, jobject unused, jstring name))
   oop h_name = JNIHandles::resolve(name);
   if (h_name == NULL) return false;
-  Symbol* sym = java_lang_String::as_symbol(h_name, CHECK_0);
+  Symbol* sym = java_lang_String::as_symbol(h_name);
   TempNewSymbol tsym(sym); // Make sure to decrement reference count on sym on return
   return (jint)sym->refcount();
 WB_END
@@ -1996,8 +1996,7 @@
   InstanceKlass* ik = InstanceKlass::cast(arg_klass);
 
   //Create symbols to look for in the class
-  TempNewSymbol name_symbol = SymbolTable::lookup(field_name, (int) strlen(field_name),
-      THREAD);
+  TempNewSymbol name_symbol = SymbolTable::new_symbol(field_name);
 
   //To be filled in with an offset of the field we're looking for
   fieldDescriptor fd;
--- a/src/hotspot/share/runtime/arguments.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/runtime/arguments.cpp	Wed May 15 13:54:43 2019 +0530
@@ -3792,11 +3792,6 @@
     return JNI_ENOMEM;
   }
 
-  // Set up VerifySharedSpaces
-  if (FLAG_IS_DEFAULT(VerifySharedSpaces) && SharedArchiveFile != NULL) {
-    VerifySharedSpaces = true;
-  }
-
   // Delay warning until here so that we've had a chance to process
   // the -XX:-PrintWarnings flag
   if (needs_hotspotrc_warning) {
--- a/src/hotspot/share/runtime/deoptimization.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/runtime/deoptimization.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1430,7 +1430,7 @@
   ResourceMark rm(THREAD);
   for (SignatureStream ss(symbol); !ss.is_done(); ss.next()) {
     if (ss.is_object()) {
-      Symbol* class_name = ss.as_symbol(CHECK);
+      Symbol* class_name = ss.as_symbol();
       Handle protection_domain (THREAD, constant_pool->pool_holder()->protection_domain());
       SystemDictionary::resolve_or_null(class_name, class_loader, protection_domain, CHECK);
     }
--- a/src/hotspot/share/runtime/fieldType.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/runtime/fieldType.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -82,7 +82,7 @@
     int len = (int)strlen(element);
     assert(element[len-1] == ';', "last char should be a semicolon");
     element[len-1] = '\0';        // chop off semicolon
-    fd._object_key = SymbolTable::new_symbol(element + 1, CHECK_(T_BYTE));
+    fd._object_key = SymbolTable::new_symbol(element + 1);
   }
   // Pass dimension back to caller
   fd._dimension = dim;
--- a/src/hotspot/share/runtime/globals.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/runtime/globals.hpp	Wed May 15 13:54:43 2019 +0530
@@ -2349,8 +2349,7 @@
           "Use shared spaces for metadata")                                 \
                                                                             \
   product(bool, VerifySharedSpaces, false,                                  \
-          "Verify shared spaces (false for default archive, true for "      \
-          "archive specified by -XX:SharedArchiveFile)")                    \
+          "Verify integrity of shared spaces")                              \
                                                                             \
   product(bool, RequireSharedSpaces, false,                                 \
           "Require shared spaces for metadata")                             \
--- a/src/hotspot/share/runtime/os.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/runtime/os.hpp	Wed May 15 13:54:43 2019 +0530
@@ -591,6 +591,7 @@
   // Loads .dll/.so and
   // in case of error it checks if .dll/.so was built for the
   // same architecture as HotSpot is running on
+  // in case of an error NULL is returned and an error message is stored in ebuf
   static void* dll_load(const char *name, char *ebuf, int ebuflen);
 
   // lookup symbol in a shared library
--- a/src/hotspot/share/runtime/reflection.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/runtime/reflection.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -757,7 +757,7 @@
 
 
   if (T_OBJECT == ss->type() || T_ARRAY == ss->type()) {
-    Symbol* name = ss->as_symbol(CHECK_NULL);
+    Symbol* name = ss->as_symbol();
     oop loader = method->method_holder()->class_loader();
     oop protection_domain = method->method_holder()->protection_domain();
     const Klass* k = SystemDictionary::resolve_or_fail(name,
--- a/src/hotspot/share/runtime/signature.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/runtime/signature.cpp	Wed May 15 13:54:43 2019 +0530
@@ -336,7 +336,7 @@
   return _type == T_ARRAY;
 }
 
-Symbol* SignatureStream::as_symbol(TRAPS) {
+Symbol* SignatureStream::as_symbol() {
   // Create a symbol from for string _begin _end
   int begin = _begin;
   int end   = _end;
@@ -368,7 +368,7 @@
 
   // Save names for cleaning up reference count at the end of
   // SignatureStream scope.
-  name = SymbolTable::new_symbol(symbol_chars, len, CHECK_NULL);
+  name = SymbolTable::new_symbol(symbol_chars, len);
   if (!name->is_permanent()) {
     if (_names == NULL) {
       _names = new GrowableArray<Symbol*>(10);
@@ -380,9 +380,9 @@
 }
 
 Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain,
-                                   FailureMode failure_mode, TRAPS) {
+                                 FailureMode failure_mode, TRAPS) {
   if (!is_object())  return NULL;
-  Symbol* name = as_symbol(CHECK_NULL);
+  Symbol* name = as_symbol();
   if (failure_mode == ReturnNull) {
     return SystemDictionary::resolve_or_null(name, class_loader, protection_domain, THREAD);
   } else {
--- a/src/hotspot/share/runtime/signature.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/runtime/signature.hpp	Wed May 15 13:54:43 2019 +0530
@@ -400,7 +400,7 @@
   bool is_object() const;                        // True if this argument is an object
   bool is_array() const;                         // True if this argument is an array
   BasicType type() const                         { return _type; }
-  Symbol* as_symbol(TRAPS);
+  Symbol* as_symbol();
   enum FailureMode { ReturnNull, NCDFError };
   Klass* as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS);
   oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS);
--- a/src/hotspot/share/services/attachListener.hpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/services/attachListener.hpp	Wed May 15 13:54:43 2019 +0530
@@ -121,7 +121,7 @@
   const char* name() const                      { return _name; }
 
   // set the operation name
-  void set_name(char* name) {
+  void set_name(const char* name) {
     assert(strlen(name) <= name_length_max, "exceeds maximum name length");
     size_t len = MIN2(strlen(name), (size_t)name_length_max);
     memcpy(_name, name, len);
@@ -148,7 +148,7 @@
   }
 
   // create an operation of a given name
-  AttachOperation(char* name) {
+  AttachOperation(const char* name) {
     set_name(name);
     for (int i=0; i<arg_count_max; i++) {
       set_arg(i, NULL);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/utilities/virtualizationSupport.cpp	Wed May 15 13:54:43 2019 +0530
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019 SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/os.hpp"
+#include "utilities/virtualizationSupport.hpp"
+
+static void *dlHandle = NULL;
+
+static GuestLib_StatGet_t GuestLib_StatGet = NULL;
+static GuestLib_StatFree_t GuestLib_StatFree = NULL;
+
+static bool has_host_information = false;
+static bool has_resource_information = false;
+
+// host + resource information; avoid the session and other special info vectors
+static char host_information[300];
+static char extended_resource_info_at_startup[600];
+
+void VirtualizationSupport::initialize() {
+  // open vmguestlib and bind SDK functions
+  char ebuf[1024];
+  dlHandle = os::dll_load("vmGuestLib", ebuf, sizeof ebuf);
+
+#ifdef LINUX
+  if (dlHandle == NULL) {
+    // the open-vm-tools have a different guest lib name
+    // on some distros e.g. SLES12 the open-vm-tools are the default,
+    // so use the different libname as a fallback
+    dlHandle = os::dll_load("/usr/lib64/libguestlib.so.0", ebuf, sizeof ebuf);
+  }
+#endif
+  if (dlHandle == NULL) {
+    return;
+  }
+
+  GuestLib_StatGet = CAST_TO_FN_PTR(GuestLib_StatGet_t, os::dll_lookup(dlHandle, "VMGuestLib_StatGet"));
+  GuestLib_StatFree = CAST_TO_FN_PTR(GuestLib_StatFree_t, os::dll_lookup(dlHandle, "VMGuestLib_StatFree"));
+
+  if (GuestLib_StatGet != NULL && GuestLib_StatFree != NULL) {
+    char* result_info = NULL;
+    size_t result_size = 0;
+    VMGuestLibError sg_error = GuestLib_StatGet("text", "resources", &result_info, &result_size);
+    if (sg_error == VMGUESTLIB_ERROR_SUCCESS) {
+      has_resource_information = true;
+      snprintf(extended_resource_info_at_startup, sizeof(extended_resource_info_at_startup), "%s", result_info);
+      GuestLib_StatFree(result_info, result_size);
+    }
+    sg_error = GuestLib_StatGet("text", "host", &result_info, &result_size);
+    if (sg_error == VMGUESTLIB_ERROR_SUCCESS) {
+      has_host_information = true;
+      snprintf(host_information, sizeof(host_information), "%s", result_info);
+      GuestLib_StatFree(result_info, result_size);
+    }
+  }
+}
+
+void VirtualizationSupport::print_virtualization_info(outputStream* st) {
+  if (has_host_information) {
+    st->print_cr("vSphere host information:");
+    st->print_cr("%s", host_information);
+  }
+  // resource info at startup
+  if (has_resource_information) {
+    st->print_cr("vSphere resource information collected at VM startup:");
+    st->print_cr("%s", extended_resource_info_at_startup);
+  }
+  // current resource info
+  if (GuestLib_StatGet != NULL && GuestLib_StatFree != NULL) {
+    char* result_info = NULL;
+    size_t result_size = 0;
+    VMGuestLibError sg_error = GuestLib_StatGet("text", "resources", &result_info, &result_size);
+    if (sg_error == VMGUESTLIB_ERROR_SUCCESS) {
+      st->print_cr("vSphere resource information available now:");
+      st->print_cr("%s", result_info);
+      GuestLib_StatFree(result_info, result_size);
+    }
+  }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hotspot/share/utilities/virtualizationSupport.hpp	Wed May 15 13:54:43 2019 +0530
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019 SAP SE. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef SHARE_UTILITIES_VIRTUALIZATIONSUPPORT_HPP
+#define SHARE_UTILITIES_VIRTUALIZATIONSUPPORT_HPP
+
+#include "utilities/ostream.hpp"
+
+typedef enum {
+  VMGUESTLIB_ERROR_SUCCESS = 0, // no error occured
+  VMGUESTLIB_ERROR_OTHER,
+  VMGUESTLIB_ERROR_NOT_RUNNING_IN_VM,
+  VMGUESTLIB_ERROR_NOT_ENABLED,
+  VMGUESTLIB_ERROR_NOT_AVAILABLE,
+  VMGUESTLIB_ERROR_NO_INFO,
+  VMGUESTLIB_ERROR_MEMORY,
+  VMGUESTLIB_ERROR_BUFFER_TOO_SMALL,
+  VMGUESTLIB_ERROR_INVALID_HANDLE,
+  VMGUESTLIB_ERROR_INVALID_ARG,
+  VMGUESTLIB_ERROR_UNSUPPORTED_VERSION
+} VMGuestLibError;
+
+// new SDK functions from VMWare SDK 6.0; need VMware Tools version 9.10 installed
+typedef VMGuestLibError (*GuestLib_StatGet_t)(const char*, const char*, char**, size_t*);
+typedef VMGuestLibError (*GuestLib_StatFree_t)(char*, size_t);
+
+class VirtualizationSupport {
+ public:
+  static void initialize();
+  static void print_virtualization_info(outputStream* st);
+};
+
+#endif
+
--- a/src/hotspot/share/utilities/vmError.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/src/hotspot/share/utilities/vmError.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1198,8 +1198,7 @@
 static int expand_and_open(const char* pattern, char* buf, size_t buflen, size_t pos) {
   int fd = -1;
   if (Arguments::copy_expand_pid(pattern, strlen(pattern), &buf[pos], buflen - pos)) {
-    // the O_EXCL flag will cause the open to fail if the file exists
-    fd = open(buf, O_RDWR | O_CREAT | O_EXCL, 0666);
+    fd = open(buf, O_RDWR | O_CREAT, 0666);
   }
   return fd;
 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Tue May 14 11:23:08 2019 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Wed May 15 13:54:43 2019 +0530
@@ -1963,6 +1963,13 @@
             return (flags() & LAMBDA_METHOD) == LAMBDA_METHOD;
         }
 
+        /** override this method to point to the original enclosing method if this method symbol represents a synthetic
+         *  lambda method
+         */
+        public MethodSymbol originalEnclosingMethod() {
+            return this;
+        }
+
         /** The implementation of this (abstract) symbol in class origin;
          *  null if none exists. Synthetic methods are not considered
          *  as possible implementations.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue May 14 11:23:08 2019 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Wed May 15 13:54:43 2019 +0530
@@ -603,21 +603,6 @@
             tree.init = translate(tree.init);
             tree.sym = (VarSymbol) lambdaContext.getSymbolMap(LOCAL_VAR).get(tree.sym);
             result = tree;
-        } else if (context != null && lambdaContext.getSymbolMap(TYPE_VAR).containsKey(tree.sym)) {
-            JCExpression init = translate(tree.init);
-            VarSymbol xsym = (VarSymbol)lambdaContext.getSymbolMap(TYPE_VAR).get(tree.sym);
-            int prevPos = make.pos;
-            try {
-                result = make.at(tree).VarDef(xsym, init);
-            } finally {
-                make.at(prevPos);
-            }
-            // Replace the entered symbol for this variable
-            WriteableScope sc = tree.sym.owner.members();
-            if (sc != null) {
-                sc.remove(tree.sym);
-                sc.enter(xsym);
-            }
         } else {
             super.visitVarDef(tree);
         }
@@ -1572,9 +1557,6 @@
                 // Check for type variables (including as type arguments).
                 // If they occur within class nested in a lambda, mark for erasure
                 Type type = tree.sym.asType();
-                if (inClassWithinLambda() && !types.isSameType(types.erasure(type), type)) {
-                    ltc.addSymbol(tree.sym, TYPE_VAR);
-                }
             }
 
             List<Frame> prevStack = frameStack;
@@ -1944,8 +1926,17 @@
                  }
 
                 // This symbol will be filled-in in complete
-                this.translatedSym = makePrivateSyntheticMethod(0, null, null, owner.enclClass());
-
+                if (owner.kind == MTH) {
+                    final MethodSymbol originalOwner = (MethodSymbol)owner.clone(owner.owner);
+                    this.translatedSym = new MethodSymbol(SYNTHETIC | PRIVATE, null, null, owner.enclClass()) {
+                        @Override
+                        public MethodSymbol originalEnclosingMethod() {
+                            return originalOwner;
+                        }
+                    };
+                } else {
+                    this.translatedSym = makePrivateSyntheticMethod(0, null, null, owner.enclClass());
+                }
                 translatedSymbols = new EnumMap<>(LambdaSymbolKind.class);
 
                 translatedSymbols.put(PARAM, new LinkedHashMap<Symbol, Symbol>());
@@ -1953,7 +1944,6 @@
                 translatedSymbols.put(CAPTURED_VAR, new LinkedHashMap<Symbol, Symbol>());
                 translatedSymbols.put(CAPTURED_THIS, new LinkedHashMap<Symbol, Symbol>());
                 translatedSymbols.put(CAPTURED_OUTER_THIS, new LinkedHashMap<Symbol, Symbol>());
-                translatedSymbols.put(TYPE_VAR, new LinkedHashMap<Symbol, Symbol>());
 
                 freeVarProcessedLocalClasses = new HashSet<>();
             }
@@ -2046,16 +2036,6 @@
                     case CAPTURED_THIS:
                         ret = sym;  // self represented
                         break;
-                    case TYPE_VAR:
-                        // Just erase the type var
-                        ret = new VarSymbol(sym.flags(), sym.name,
-                                types.erasure(sym.type), sym.owner);
-
-                        /* this information should also be kept for LVT generation at Gen
-                         * a Symbol with pos < startPos won't be tracked.
-                         */
-                        ((VarSymbol)ret).pos = ((VarSymbol)sym).pos;
-                        break;
                     case CAPTURED_VAR:
                         ret = new VarSymbol(SYNTHETIC | FINAL | PARAMETER, sym.name, types.erasure(sym.type), translatedSym) {
                             @Override
@@ -2352,8 +2332,7 @@
         LOCAL_VAR,      // original to translated lambda locals
         CAPTURED_VAR,   // variables in enclosing scope to translated synthetic parameters
         CAPTURED_THIS,  // class symbols to translated synthetic parameters (for captured member access)
-        CAPTURED_OUTER_THIS, // used when `this' capture is illegal, but outer this capture is legit (JDK-8129740)
-        TYPE_VAR;      // original to translated lambda type variables
+        CAPTURED_OUTER_THIS; // used when `this' capture is illegal, but outer this capture is legit (JDK-8129740)
 
         boolean propagateAnnotations() {
             switch (this) {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue May 14 11:23:08 2019 +0530
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -323,9 +323,9 @@
             (c.owner.type == null // local to init block
              || c.owner.kind != MTH) // or member init
             ? null
-            : (MethodSymbol)c.owner;
+            : ((MethodSymbol)c.owner).originalEnclosingMethod();
         databuf.appendChar(poolWriter.putClass(enclClass));
-        databuf.appendChar(enclMethod == null ? 0 : poolWriter.putNameAndType(c.owner));
+        databuf.appendChar(enclMethod == null ? 0 : poolWriter.putNameAndType(enclMethod));
         endAttr(alenIdx);
         return 1;
     }
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPageAllocator.java	Tue May 14 11:23:08 2019 +0530
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPageAllocator.java	Wed May 15 13:54:43 2019 +0530
@@ -27,8 +27,6 @@
 import sun.jvm.hotspot.debugger.Address;
 import sun.jvm.hotspot.runtime.VM;
 import sun.jvm.hotspot.runtime.VMObject;
-import sun.jvm.hotspot.runtime.VMObjectFactory;
-import sun.jvm.hotspot.types.AddressField;
 import sun.jvm.hotspot.types.CIntegerField;
 import sun.jvm.hotspot.types.Type;
 import sun.jvm.hotspot.types.TypeDataBase;
@@ -37,7 +35,8 @@
 
 public class ZPageAllocator extends VMObject {
 
-    private static long physicalFieldOffset;
+    private static CIntegerField maxCapacityField;
+    private static CIntegerField capacityField;
     private static CIntegerField usedField;
 
     static {
@@ -47,21 +46,17 @@
     static private synchronized void initialize(TypeDataBase db) {
         Type type = db.lookupType("ZPageAllocator");
 
-        physicalFieldOffset = type.getAddressField("_physical").getOffset();
+        maxCapacityField = type.getCIntegerField("_max_capacity");
+        capacityField = type.getCIntegerField("_capacity");
         usedField = type.getCIntegerField("_used");
     }
 
-    private ZPhysicalMemoryManager physical() {
-      Address physicalAddr = addr.addOffsetTo(physicalFieldOffset);
-      return (ZPhysicalMemoryManager)VMObjectFactory.newObject(ZPhysicalMemoryManager.class, physicalAddr);
-    }
-
     public long maxCapacity() {
-        return physical().maxCapacity();
+        return maxCapacityField.getValue(addr);
     }
 
     public long capacity() {
-        return physical().capacity();
+        return capacityField.getValue(addr);
     }
 
     public long used() {
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/gc/z/ZPhysicalMemoryManager.java	Tue May 14 11:23:08 2019 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.gc.z;
-
-import sun.jvm.hotspot.debugger.Address;
-import sun.jvm.hotspot.runtime.VM;
-import sun.jvm.hotspot.runtime.VMObject;
-import sun.jvm.hotspot.types.CIntegerField;
-import sun.jvm.hotspot.types.Type;
-import sun.jvm.hotspot.types.TypeDataBase;
-
-// Mirror class for ZPhysicalMemoryManager
-
-public class ZPhysicalMemoryManager extends VMObject {
-
-    private static CIntegerField capacityField;
-
-    private static CIntegerField maxCapacityField;
-
-    static {
-        VM.registerVMInitializedObserver((o, d) -> initialize(VM.getVM().getTypeDataBase()));
-    }
-
-    private static synchronized void initialize(TypeDataBase db) {
-        Type type = db.lookupType("ZPhysicalMemoryManager");
-
-        capacityField = type.getCIntegerField("_capacity");
-        maxCapacityField = type.getCIntegerField("_max_capacity");
-    }
-
-    public long capacity() {
-        return capacityField.getValue(addr);
-    }
-
-    public long maxCapacity() {
-        return maxCapacityField.getValue(addr);
-    }
-
-    public ZPhysicalMemoryManager(Address addr) {
-        super(addr);
-    }
-}
--- a/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java	Tue May 14 11:23:08 2019 +0530
+++ b/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@
     private final ThreadGroup mainGroupForJDI;
     private ResourceBundle messages = null;
     private int vmSequenceNumber = 0;
-    private static final int majorVersion = 11;
+    private static final int majorVersion = Runtime.version().feature();
     private static final int minorVersion = 0;
 
     private static final Object lock = new Object();
--- a/src/jdk.jdwp.agent/share/native/libjdwp/VirtualMachineImpl.c	Tue May 14 11:23:08 2019 +0530
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/VirtualMachineImpl.c	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,8 +35,6 @@
 #include "FrameID.h"
 
 static char *versionName = "Java Debug Wire Protocol (Reference Implementation)";
-static int majorVersion = 11;  /* JDWP major version */
-static int minorVersion = 0;  /* JDWP minor version */
 
 static jboolean
 version(PacketInputStream *in, PacketOutputStream *out)
@@ -46,6 +44,10 @@
     char *vmVersion;
     char *vmInfo;
 
+    /* Now the JDWP versions are the same as JVMTI versions */
+    int majorVersion = jvmtiMajorVersion();
+    int minorVersion = 0;
+
     if (gdata->vmDead) {
         outStream_setError(out, JDWP_ERROR(VM_DEAD));
         return JNI_TRUE;
--- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Tue May 14 11:23:08 2019 +0530
+++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java	Wed May 15 13:54:43 2019 +0530
@@ -1211,7 +1211,7 @@
             return 0;
 
         long written = 0;
-        if (e.crc != 0 && e.csize > 0) {
+        if (e.csize > 0 && (e.crc != 0 || e.size == 0)) {
             // pre-compressed entry, write directly to output stream
             writeTo(e, os);
         } else {
--- a/test/hotspot/gtest/classfile/test_symbolTable.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/gtest/classfile/test_symbolTable.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,14 +34,14 @@
   // the thread should be in vm to use locks
   ThreadInVMfromNative ThreadInVMfromNative(THREAD);
 
-  Symbol* abc = SymbolTable::new_symbol("abc", CATCH);
+  Symbol* abc = SymbolTable::new_symbol("abc");
   int abccount = abc->refcount();
   TempNewSymbol ss = abc;
   ASSERT_EQ(ss->refcount(), abccount) << "only one abc";
   ASSERT_EQ(ss->refcount(), abc->refcount()) << "should match TempNewSymbol";
 
-  Symbol* efg = SymbolTable::new_symbol("efg", CATCH);
-  Symbol* hij = SymbolTable::new_symbol("hij", CATCH);
+  Symbol* efg = SymbolTable::new_symbol("efg");
+  Symbol* hij = SymbolTable::new_symbol("hij");
   int efgcount = efg->refcount();
   int hijcount = hij->refcount();
 
@@ -63,12 +63,12 @@
   ASSERT_EQ(s1->refcount(), abccount + 1) << "should still be two abc (s1 and ss)";
 
   TempNewSymbol s3;
-  Symbol* klm = SymbolTable::new_symbol("klm", CATCH);
+  Symbol* klm = SymbolTable::new_symbol("klm");
   int klmcount = klm->refcount();
   s3 = klm; // assignment
   ASSERT_EQ(s3->refcount(), klmcount) << "only one klm now";
 
-  Symbol* xyz = SymbolTable::new_symbol("xyz", CATCH);
+  Symbol* xyz = SymbolTable::new_symbol("xyz");
   int xyzcount = xyz->refcount();
   { // inner scope
     TempNewSymbol s_inner = xyz;
@@ -77,7 +77,7 @@
           << "Should have been decremented by dtor in inner scope";
 
   // Test overflowing refcount making symbol permanent
-  Symbol* bigsym = SymbolTable::new_symbol("bigsym", CATCH);
+  Symbol* bigsym = SymbolTable::new_symbol("bigsym");
   for (int i = 0; i < PERM_REFCOUNT + 100; i++) {
     bigsym->increment_refcount();
   }
@@ -101,9 +101,8 @@
   SymbolThread(Semaphore* post) : JavaTestThread(post) {}
   virtual ~SymbolThread() {}
   void main_run() {
-    Thread* THREAD = Thread::current();
     for (int i = 0; i < 1000; i++) {
-      TempNewSymbol sym = SymbolTable::new_symbol(symbol_name, CATCH);
+      TempNewSymbol sym = SymbolTable::new_symbol(symbol_name);
       // Create and destroy new symbol
       EXPECT_TRUE(sym->refcount() != 0) << "Symbol refcount unexpectedly zeroed";
     }
@@ -121,12 +120,10 @@
   void main_run() {
     Semaphore done(0);
 
-    Thread* THREAD = Thread::current();
-
     // Find a symbol where there will probably be only one instance.
     for (int i = 0; i < 100; i++) {
        os::snprintf(symbol_name, SYM_NAME_LENGTH, "some_symbol%d", i);
-       TempNewSymbol ts = SymbolTable::new_symbol(symbol_name, CATCH);
+       TempNewSymbol ts = SymbolTable::new_symbol(symbol_name);
        if (ts->refcount() == 1) {
          EXPECT_TRUE(ts->refcount() == 1) << "Symbol is just created";
          break;  // found a unique symbol
--- a/test/hotspot/gtest/gc/z/test_zForwarding.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/gtest/gc/z/test_zForwarding.cpp	Wed May 15 13:54:43 2019 +0530
@@ -169,9 +169,6 @@
 
     // Teardown forwarding
     ZForwarding::destroy(forwarding);
-
-    // Teardown page
-    page.physical_memory().clear();
   }
 
   // Run the given function with a few different input values.
--- a/test/hotspot/gtest/gc/z/test_zPhysicalMemory.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/gtest/gc/z/test_zPhysicalMemory.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,59 +22,121 @@
  */
 
 #include "precompiled.hpp"
-#include "gc/z/zGlobals.hpp"
 #include "gc/z/zPhysicalMemory.inline.hpp"
-#include "utilities/debug.hpp"
 #include "unittest.hpp"
 
-#if defined(AMD64)
+TEST(ZPhysicalMemoryTest, copy) {
+  const ZPhysicalMemorySegment seg0(0, 100);
+  const ZPhysicalMemorySegment seg1(200, 100);
+
+  ZPhysicalMemory pmem0;
+  pmem0.add_segment(seg0);
+  EXPECT_EQ(pmem0.nsegments(), 1u);
+  EXPECT_EQ(pmem0.segment(0).size(), 100u);
+
+  ZPhysicalMemory pmem1;
+  pmem1.add_segment(seg0);
+  pmem1.add_segment(seg1);
+  EXPECT_EQ(pmem1.nsegments(), 2u);
+  EXPECT_EQ(pmem1.segment(0).size(), 100u);
+  EXPECT_EQ(pmem1.segment(1).size(), 100u);
 
-TEST(ZPhysicalMemorySegmentTest, split) {
-  ZPhysicalMemorySegment seg(0, 10 * ZGranuleSize);
+  ZPhysicalMemory pmem2(pmem0);
+  EXPECT_EQ(pmem2.nsegments(), 1u);
+  EXPECT_EQ(pmem2.segment(0).size(), 100u);
+
+  pmem2 = pmem1;
+  EXPECT_EQ(pmem2.nsegments(), 2u);
+  EXPECT_EQ(pmem2.segment(0).size(), 100u);
+  EXPECT_EQ(pmem2.segment(1).size(), 100u);
+}
 
-  ZPhysicalMemorySegment seg_split0 = seg.split(0 * ZGranuleSize);
-  EXPECT_EQ(seg_split0.size(),  0 * ZGranuleSize);
-  EXPECT_EQ(       seg.size(), 10 * ZGranuleSize);
+TEST(ZPhysicalMemoryTest, segments) {
+  const ZPhysicalMemorySegment seg0(0, 1);
+  const ZPhysicalMemorySegment seg1(1, 1);
+  const ZPhysicalMemorySegment seg2(2, 1);
+  const ZPhysicalMemorySegment seg3(3, 1);
+  const ZPhysicalMemorySegment seg4(4, 1);
+  const ZPhysicalMemorySegment seg5(5, 1);
+  const ZPhysicalMemorySegment seg6(6, 1);
+
+  ZPhysicalMemory pmem0;
+  EXPECT_EQ(pmem0.nsegments(), 0u);
+  EXPECT_EQ(pmem0.is_null(), true);
 
-  ZPhysicalMemorySegment seg_split1 = seg.split(5 * ZGranuleSize);
-  EXPECT_EQ(seg_split1.size(),  5 * ZGranuleSize);
-  EXPECT_EQ(       seg.size(),  5 * ZGranuleSize);
+  ZPhysicalMemory pmem1;
+  pmem1.add_segment(seg0);
+  pmem1.add_segment(seg1);
+  pmem1.add_segment(seg2);
+  pmem1.add_segment(seg3);
+  pmem1.add_segment(seg4);
+  pmem1.add_segment(seg5);
+  pmem1.add_segment(seg6);
+  EXPECT_EQ(pmem1.nsegments(), 1u);
+  EXPECT_EQ(pmem1.segment(0).size(), 7u);
+  EXPECT_EQ(pmem1.is_null(), false);
+
+  ZPhysicalMemory pmem2;
+  pmem2.add_segment(seg0);
+  pmem2.add_segment(seg1);
+  pmem2.add_segment(seg2);
+  pmem2.add_segment(seg4);
+  pmem2.add_segment(seg5);
+  pmem2.add_segment(seg6);
+  EXPECT_EQ(pmem2.nsegments(), 2u);
+  EXPECT_EQ(pmem2.segment(0).size(), 3u);
+  EXPECT_EQ(pmem2.segment(1).size(), 3u);
+  EXPECT_EQ(pmem2.is_null(), false);
 
-  ZPhysicalMemorySegment seg_split2 = seg.split(5 * ZGranuleSize);
-  EXPECT_EQ(seg_split2.size(),  5 * ZGranuleSize);
-  EXPECT_EQ(       seg.size(),  0 * ZGranuleSize);
+  ZPhysicalMemory pmem3;
+  pmem3.add_segment(seg0);
+  pmem3.add_segment(seg2);
+  pmem3.add_segment(seg3);
+  pmem3.add_segment(seg4);
+  pmem3.add_segment(seg6);
+  EXPECT_EQ(pmem3.nsegments(), 3u);
+  EXPECT_EQ(pmem3.segment(0).size(), 1u);
+  EXPECT_EQ(pmem3.segment(1).size(), 3u);
+  EXPECT_EQ(pmem3.segment(2).size(), 1u);
+  EXPECT_EQ(pmem3.is_null(), false);
 
-  ZPhysicalMemorySegment seg_split3 = seg.split(0 * ZGranuleSize);
-  EXPECT_EQ(seg_split3.size(),  0 * ZGranuleSize);
-  EXPECT_EQ(       seg.size(),  0 * ZGranuleSize);
+  ZPhysicalMemory pmem4;
+  pmem4.add_segment(seg0);
+  pmem4.add_segment(seg2);
+  pmem4.add_segment(seg4);
+  pmem4.add_segment(seg6);
+  EXPECT_EQ(pmem4.nsegments(), 4u);
+  EXPECT_EQ(pmem4.segment(0).size(), 1u);
+  EXPECT_EQ(pmem4.segment(1).size(), 1u);
+  EXPECT_EQ(pmem4.segment(2).size(), 1u);
+  EXPECT_EQ(pmem4.segment(3).size(), 1u);
+  EXPECT_EQ(pmem4.is_null(), false);
 }
 
 TEST(ZPhysicalMemoryTest, split) {
-  ZPhysicalMemoryManager pmem_manager(10 * ZGranuleSize);
-
-  pmem_manager.try_ensure_unused_capacity(10 * ZGranuleSize);
-  EXPECT_EQ(pmem_manager.unused_capacity(), 10 * ZGranuleSize);
+  ZPhysicalMemory pmem;
 
-  ZPhysicalMemory pmem = pmem_manager.alloc(8 * ZGranuleSize);
-  EXPECT_EQ(pmem.nsegments(), 1u) << "wrong number of segments";
-
-  ZPhysicalMemory split0_pmem = pmem.split(ZGranuleSize);
-  EXPECT_EQ(split0_pmem.nsegments(), 1u);
-  EXPECT_EQ(       pmem.nsegments(), 1u);
-  EXPECT_EQ(split0_pmem.size(), 1 * ZGranuleSize);
-  EXPECT_EQ(       pmem.size(), 7 * ZGranuleSize);
+  pmem.add_segment(ZPhysicalMemorySegment(0, 10));
+  pmem.add_segment(ZPhysicalMemorySegment(10, 10));
+  pmem.add_segment(ZPhysicalMemorySegment(30, 10));
+  EXPECT_EQ(pmem.nsegments(), 2u);
+  EXPECT_EQ(pmem.size(), 30u);
 
-  ZPhysicalMemory split1_pmem = pmem.split(2 * ZGranuleSize);
-  EXPECT_EQ(split1_pmem.nsegments(), 1u);
-  EXPECT_EQ(       pmem.nsegments(), 1u);
-  EXPECT_EQ(split1_pmem.size(), 2 * ZGranuleSize);
-  EXPECT_EQ(       pmem.size(), 5 * ZGranuleSize);
+  ZPhysicalMemory pmem0 = pmem.split(1);
+  EXPECT_EQ(pmem0.nsegments(), 1u);
+  EXPECT_EQ(pmem0.size(), 1u);
+  EXPECT_EQ(pmem.nsegments(), 2u);
+  EXPECT_EQ(pmem.size(), 29u);
 
-  ZPhysicalMemory split2_pmem = pmem.split(5 * ZGranuleSize);
-  EXPECT_EQ(split2_pmem.nsegments(), 1u);
-  EXPECT_EQ(       pmem.nsegments(), 1u);
-  EXPECT_EQ(split2_pmem.size(), 5 * ZGranuleSize);
-  EXPECT_EQ(       pmem.size(), 0 * ZGranuleSize);
+  ZPhysicalMemory pmem1 = pmem.split(25);
+  EXPECT_EQ(pmem1.nsegments(), 2u);
+  EXPECT_EQ(pmem1.size(), 25u);
+  EXPECT_EQ(pmem.nsegments(), 1u);
+  EXPECT_EQ(pmem.size(), 4u);
+
+  ZPhysicalMemory pmem2 = pmem.split(4);
+  EXPECT_EQ(pmem2.nsegments(), 1u);
+  EXPECT_EQ(pmem2.size(), 4u);
+  EXPECT_EQ(pmem.nsegments(), 0u);
+  EXPECT_EQ(pmem.size(), 0u);
 }
-
-#endif
--- a/test/hotspot/gtest/gc/z/test_zVirtualMemory.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/gtest/gc/z/test_zVirtualMemory.cpp	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,26 +23,23 @@
 
 #include "precompiled.hpp"
 #include "gc/z/zVirtualMemory.inline.hpp"
-#include "utilities/debug.hpp"
 #include "unittest.hpp"
 
 TEST(ZVirtualMemory, split) {
-  const size_t PageSize = 2 * M;
-
-  ZVirtualMemory mem(0, 10 * PageSize);
+  ZVirtualMemory vmem(0, 10);
 
-  ZVirtualMemory mem_split0 = mem.split(0 * PageSize);
-  EXPECT_EQ(mem_split0.size(),  0 * PageSize);
-  EXPECT_EQ(       mem.size(), 10 * PageSize);
+  ZVirtualMemory vmem0 = vmem.split(0);
+  EXPECT_EQ(vmem0.size(), 0u);
+  EXPECT_EQ(vmem.size(), 10u);
 
-  ZVirtualMemory mem_split1 = mem.split(5u * PageSize);
-  EXPECT_EQ(mem_split1.size(),  5 * PageSize);
-  EXPECT_EQ(       mem.size(),  5 * PageSize);
+  ZVirtualMemory vmem1 = vmem.split(5);
+  EXPECT_EQ(vmem1.size(), 5u);
+  EXPECT_EQ(vmem.size(), 5u);
 
-  ZVirtualMemory mem_split2 = mem.split(5u * PageSize);
-  EXPECT_EQ(mem_split2.size(),  5 * PageSize);
-  EXPECT_EQ(       mem.size(),  0 * PageSize);
+  ZVirtualMemory vmem2 = vmem.split(5);
+  EXPECT_EQ(vmem2.size(), 5u);
+  EXPECT_EQ(vmem.size(), 0u);
 
-  ZVirtualMemory mem_split3 = mem.split(0 * PageSize);
-  EXPECT_EQ(mem_split3.size(),  0 * PageSize);
+  ZVirtualMemory vmem3 = vmem.split(0);
+  EXPECT_EQ(vmem3.size(), 0u);
 }
--- a/test/hotspot/gtest/gtestMain.cpp	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/gtest/gtestMain.cpp	Wed May 15 13:54:43 2019 +0530
@@ -231,7 +231,7 @@
 #endif // __APPLE__
 
 #else  // _WIN32
-  char* java_home_var = "_ALT_JAVA_HOME_DIR";
+  const char* java_home_var = "_ALT_JAVA_HOME_DIR";
   size_t len = strlen(java_home) + strlen(java_home_var) + 2;
   char * envString = new char[len];
   sprintf_s(envString, len, "%s=%s", java_home_var, java_home);
--- a/test/hotspot/jtreg/ProblemList-zgc.txt	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/jtreg/ProblemList-zgc.txt	Wed May 15 13:54:43 2019 +0530
@@ -37,6 +37,5 @@
 serviceability/sa/TestClhsdbJstackLock.java                   8220624   generic-all
 serviceability/sa/TestHeapDumpForInvokeDynamic.java           8220624   generic-all
 serviceability/sa/TestHeapDumpForLargeArray.java              8220624   generic-all
-serviceability/sa/TestUniverse.java                           8220624   generic-all
 serviceability/sa/TestJmapCore.java                           8220624   generic-all
 serviceability/sa/TestJmapCoreMetaspace.java                  8219443   generic-all
--- a/test/hotspot/jtreg/ProblemList.txt	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/jtreg/ProblemList.txt	Wed May 15 13:54:43 2019 +0530
@@ -41,6 +41,7 @@
 # :hotspot_compiler
 
 compiler/ciReplay/TestSAServer.java 8029528 generic-all
+compiler/ciReplay/TestServerVM.java 8223885 generic-all
 compiler/codecache/stress/OverloadCompileQueueTest.java 8166554 generic-all
 compiler/codegen/Test6896617.java 8193479 generic-all
 compiler/compilercontrol/jcmd/ClearDirectivesFileStackTest.java 8140405 generic-all
--- a/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsLog.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/jtreg/gc/g1/TestEagerReclaimHumongousRegionsLog.java	Wed May 15 13:54:43 2019 +0530
@@ -71,7 +71,7 @@
 
         // This gives an array of lines containing eager reclaim of humongous regions
         // log messages contents after the ":" in the following order for every GC:
-        //   Humongous Register: a.ams
+        //   Region Register: a.ams
         //   Humongous Total: b
         //   Humongous Candidate: c
         //   Humongous Reclaim: d.dms
@@ -79,7 +79,7 @@
         //   Humongous Regions: f->g
 
         String[] lines = Arrays.stream(output.getStdout().split("\\R"))
-                         .filter(s -> s.contains("Humongous")).map(s -> s.substring(s.indexOf(LogSeparator) + LogSeparator.length()))
+                         .filter(s -> (s.contains("Humongous") || s.contains("Region Register"))).map(s -> s.substring(s.indexOf(LogSeparator) + LogSeparator.length()))
                          .toArray(String[]::new);
 
         Asserts.assertTrue(lines.length % 6 == 0, "There seems to be an unexpected amount of log messages (total: " + lines.length + ") per GC");
--- a/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/jtreg/gc/g1/TestGCLogMessages.java	Wed May 15 13:54:43 2019 +0530
@@ -132,6 +132,7 @@
         new LogMessageWithLevel("Queue Fixup", Level.DEBUG),
         new LogMessageWithLevel("Table Fixup", Level.DEBUG),
         new LogMessageWithLevel("Expand Heap After Collection", Level.DEBUG),
+        new LogMessageWithLevel("Region Register", Level.DEBUG),
         // Free CSet
         new LogMessageWithLevel("Free Collection Set", Level.DEBUG),
         new LogMessageWithLevel("Free Collection Set Serial", Level.TRACE),
@@ -139,7 +140,6 @@
         new LogMessageWithLevel("Non-Young Free Collection Set", Level.TRACE),
         // Humongous Eager Reclaim
         new LogMessageWithLevel("Humongous Reclaim", Level.DEBUG),
-        new LogMessageWithLevel("Humongous Register", Level.DEBUG),
         // Merge PSS
         new LogMessageWithLevel("Merge Per-Thread State", Level.DEBUG),
         // TLAB handling
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestRegionSizeArgs.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestRegionSizeArgs.java	Wed May 15 13:54:43 2019 +0530
@@ -47,17 +47,6 @@
         {
             ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions",
                     "-XX:+UseShenandoahGC",
-                    "-Xms2m",
-                    "-Xmx1g",
-                    "-version");
-            OutputAnalyzer output = new OutputAnalyzer(pb.start());
-            output.shouldMatch("Initial heap size");
-            output.shouldHaveExitValue(1);
-        }
-
-        {
-            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions",
-                    "-XX:+UseShenandoahGC",
                     "-Xms4m",
                     "-Xmx1g",
                     "-version");
@@ -92,18 +81,6 @@
                     "-XX:+UseShenandoahGC",
                     "-Xms100m",
                     "-Xmx1g",
-                    "-XX:ShenandoahHeapRegionSize=11m",
-                    "-version");
-            OutputAnalyzer output = new OutputAnalyzer(pb.start());
-            output.shouldMatch("Invalid -XX:ShenandoahHeapRegionSize option");
-            output.shouldHaveExitValue(1);
-        }
-
-        {
-            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions",
-                    "-XX:+UseShenandoahGC",
-                    "-Xms100m",
-                    "-Xmx1g",
                     "-XX:ShenandoahHeapRegionSize=9m",
                     "-version");
             OutputAnalyzer output = new OutputAnalyzer(pb.start());
@@ -223,18 +200,6 @@
                     "-XX:+UseShenandoahGC",
                     "-Xms100m",
                     "-Xmx1g",
-                    "-XX:ShenandoahMinRegionSize=11m",
-                    "-version");
-            OutputAnalyzer output = new OutputAnalyzer(pb.start());
-            output.shouldMatch("Invalid -XX:ShenandoahMinRegionSize option");
-            output.shouldHaveExitValue(1);
-        }
-
-        {
-            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:+UnlockExperimentalVMOptions",
-                    "-XX:+UseShenandoahGC",
-                    "-Xms100m",
-                    "-Xmx1g",
                     "-XX:ShenandoahMinRegionSize=9m",
                     "-version");
             OutputAnalyzer output = new OutputAnalyzer(pb.start());
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/z/TestUncommit.java	Wed May 15 13:54:43 2019 +0530
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package gc.z;
+
+/*
+ * @test TestUncommit
+ * @requires vm.gc.Z
+ * @summary Test ZGC uncommit unused memory
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xms128M -Xmx512M -XX:ZUncommitDelay=10 gc.z.TestUncommit true 3
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xms512M -Xmx512M -XX:ZUncommitDelay=10 gc.z.TestUncommit false 1
+ * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xms128M -Xmx512M -XX:ZUncommitDelay=10 -XX:-ZUncommit gc.z.TestUncommit false 1
+ */
+
+import java.util.ArrayList;
+
+public class TestUncommit {
+    private static final int delay = 10; // seconds
+    private static final int allocSize = 200 * 1024 * 1024; // 200M
+    private static final int smallObjectSize = 4 * 1024; // 4K
+    private static final int mediumObjectSize = 2 * 1024 * 1024; // 2M
+    private static final int largeObjectSize = allocSize;
+
+    private static volatile ArrayList<byte[]> keepAlive;
+
+    private static long capacity() {
+        return Runtime.getRuntime().totalMemory();
+    }
+
+    private static void allocate(int objectSize) {
+        keepAlive = new ArrayList<>();
+        for (int i = 0; i < allocSize; i+= objectSize) {
+            keepAlive.add(new byte[objectSize]);
+        }
+    }
+
+    private static void reclaim() {
+        keepAlive = null;
+        System.gc();
+    }
+
+    private static void test(boolean enabled, int objectSize) throws Exception {
+        final var beforeAlloc = capacity();
+
+        // Allocate memory
+        allocate(objectSize);
+
+        final var afterAlloc = capacity();
+
+        // Reclaim memory
+        reclaim();
+
+        // Wait shorter than the uncommit delay
+        Thread.sleep(delay * 1000 / 2);
+
+        final var beforeUncommit = capacity();
+
+        // Wait longer than the uncommit delay
+        Thread.sleep(delay * 1000);
+
+        final var afterUncommit = capacity();
+
+        System.out.println("  Uncommit Enabled: " + enabled);
+        System.out.println("    Uncommit Delay: " + delay);
+        System.out.println("       Object Size: " + objectSize);
+        System.out.println("        Alloc Size: " + allocSize);
+        System.out.println("      Before Alloc: " + beforeAlloc);
+        System.out.println("       After Alloc: " + afterAlloc);
+        System.out.println("   Before Uncommit: " + beforeUncommit);
+        System.out.println("    After Uncommit: " + afterUncommit);
+        System.out.println();
+
+        // Verify
+        if (enabled) {
+            if (beforeUncommit == beforeAlloc) {
+                throw new Exception("Uncommitted too fast");
+            }
+
+            if (afterUncommit >= afterAlloc) {
+                throw new Exception("Uncommitted too slow");
+            }
+
+            if (afterUncommit < beforeAlloc) {
+                throw new Exception("Uncommitted too much");
+            }
+
+            if (afterUncommit > beforeAlloc) {
+                throw new Exception("Uncommitted too little");
+            }
+        } else {
+            if (afterAlloc > beforeUncommit ||
+                afterAlloc > afterUncommit) {
+                throw new Exception("Should not uncommit");
+            }
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        final boolean enabled = Boolean.parseBoolean(args[0]);
+        final int iterations = Integer.parseInt(args[1]);
+
+        for (int i = 0; i < iterations; i++) {
+            System.out.println("Iteration " + i);
+            test(enabled, smallObjectSize);
+            test(enabled, mediumObjectSize);
+            test(enabled, largeObjectSize);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/ErrorHandling/ErrorFileOverwriteTest.java	Wed May 15 13:54:43 2019 +0530
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, SAP. All rights reserved.
+ * 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 8221738
+ * @summary Test that subsequent crashes will overwrite the file given to -XX:ErrorFile (unless %a is specified
+ *           in the error file name)
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @requires (vm.debug == true)
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+import java.io.*;
+import java.util.regex.Pattern;
+
+public class ErrorFileOverwriteTest {
+
+  private static File findHsErrorFileInOutput(OutputAnalyzer output) {
+
+    String hs_err_file = output.firstMatch("# *(\\S*hs_err_pid.*\\.log)", 1);
+    if(hs_err_file ==null) {
+      throw new RuntimeException("Did not find hs-err file in output.\n");
+    }
+
+    File f = new File(hs_err_file);
+    if (!f.exists()) {
+      throw new RuntimeException("hs-err file missing at "
+              + f.getAbsolutePath() + ".\n");
+    }
+
+    return f;
+
+  }
+
+  private static void scanHsErrorFileForContent(File f, Pattern[] pattern) throws IOException {
+    FileInputStream fis = new FileInputStream(f);
+    BufferedReader br = new BufferedReader(new InputStreamReader(fis));
+    String line = null;
+
+    int currentPattern = 0;
+
+    String lastLine = null;
+    while ((line = br.readLine()) != null && currentPattern < pattern.length) {
+      if (pattern[currentPattern].matcher(line).matches()) {
+        System.out.println("Found: " + line + ".");
+        currentPattern++;
+      }
+      lastLine = line;
+    }
+    br.close();
+
+    if (currentPattern < pattern.length) {
+      throw new RuntimeException("hs-err file incomplete (first missing pattern: " +  pattern[currentPattern] + ")");
+    }
+
+  }
+
+  public static void do_test(boolean with_percent_p) throws Exception {
+
+    // Crash twice.
+    //
+    // Second crash should, given an error file Without %p,
+    // overwrite the first file. With %p it should not.
+
+    String errorFileStem = "hs_err_pid_test";
+    String errorFileName = errorFileStem + (with_percent_p ? "%p" : "") + ".log";
+
+    System.out.println("Testing with error file name " + errorFileName + "...");
+
+    System.out.println("First crash...");
+
+    ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+            "-Xmx64M",
+            "-XX:-CreateCoredumpOnCrash",
+            "-XX:ErrorHandlerTest=1",
+            "-XX:ErrorFile=" + errorFileName,
+            "-version");
+
+    OutputAnalyzer output_detail = new OutputAnalyzer(pb.start());
+
+    output_detail.shouldMatch("# A fatal error has been detected by the Java Runtime Environment:.*");
+    output_detail.shouldMatch("# An error report file with more information is saved as:.*");
+    output_detail.shouldMatch("# " + errorFileStem + ".*");
+    System.out.println("First crash: Found expected output on tty. Ok.");
+
+    File f = findHsErrorFileInOutput(output_detail);
+    System.out.println("First crash: Found hs error file at " + f.getAbsolutePath());
+
+    scanHsErrorFileForContent(f, new Pattern[] {
+            Pattern.compile("# *Internal Error.*"),
+            Pattern.compile("Command Line:.*-XX:ErrorHandlerTest=1.*-XX:ErrorFile=" + errorFileStem + ".*")
+    });
+    System.out.println("First crash: hs error content as expected. Ok.");
+
+
+    System.out.println("Second crash...");
+
+    pb = ProcessTools.createJavaProcessBuilder(
+            "-Xmx64M",
+            "-XX:-CreateCoredumpOnCrash",
+            "-XX:ErrorHandlerTest=2", // << now 2
+            "-XX:ErrorFile=" + errorFileName,
+            "-version");
+
+    output_detail = new OutputAnalyzer(pb.start());
+
+    output_detail.shouldMatch("# A fatal error has been detected by the Java Runtime Environment:.*");
+    output_detail.shouldMatch("# An error report file with more information is saved as:.*");
+    output_detail.shouldMatch("# " + errorFileStem + ".*");
+    System.out.println("Second crash: Found expected output on tty. Ok.");
+
+    File f2 = findHsErrorFileInOutput(output_detail);
+    System.out.println("Second crash: Found hs error file at " + f2.getAbsolutePath());
+
+    if (with_percent_p) {
+      if (f2.getAbsolutePath() == f.getAbsolutePath()) {
+        throw new RuntimeException("Unexpected overwriting of error file");
+      }
+    }
+
+    scanHsErrorFileForContent(f2, new Pattern[] {
+            Pattern.compile("# *Internal Error.*"),
+            Pattern.compile("Command Line:.*-XX:ErrorHandlerTest=2.*-XX:ErrorFile=" + errorFileStem + ".*")
+    });
+    System.out.println("Second crash: hs error content as expected. Ok.");
+
+  }
+
+  public static void main(String[] args) throws Exception {
+    do_test(false);
+    do_test(true);
+  }
+
+}
+
+
--- a/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -318,7 +318,11 @@
 
         // test, should pass
         System.out.println("1. Normal, should pass but may fail\n");
+
         String[] execArgs = {"-cp", jarFile, "Hello"};
+        // tests that corrupt contents of the archive need to run with
+        // VerifySharedSpaces enabled to detect inconsistencies
+        String[] verifyExecArgs = {"-XX:+VerifySharedSpaces", "-cp", jarFile, "Hello"};
 
         OutputAnalyzer output = TestCommon.execCommon(execArgs);
 
@@ -350,9 +354,10 @@
 
         // modify content
         System.out.println("\n3. Corrupt Content, should fail\n");
+
         copyFile(orgJsaFile, jsa);
         modifyJsaContent();
-        testAndCheck(execArgs);
+        testAndCheck(verifyExecArgs);
 
         // modify both header and content, test should fail
         System.out.println("\n4. Corrupt Header and Content, should fail\n");
@@ -363,19 +368,19 @@
         output.shouldContain("The shared archive file has the wrong version");
         output.shouldNotContain("Checksum verification failed");
 
-        // delete bytes in data sectoin
-        System.out.println("\n5. Delete bytes at begining of data section, should fail\n");
+        // delete bytes in data section
+        System.out.println("\n5. Delete bytes at beginning of data section, should fail\n");
         copyFile(orgJsaFile, jsa, true);
-        testAndCheck(execArgs);
+        testAndCheck(verifyExecArgs);
 
-        // insert bytes in data sectoin forward
-        System.out.println("\n6. Insert bytes at begining of data section, should fail\n");
+        // insert bytes in data section forward
+        System.out.println("\n6. Insert bytes at beginning of data section, should fail\n");
         copyFile(orgJsaFile, jsa, false);
-        testAndCheck(execArgs);
+        testAndCheck(verifyExecArgs);
 
         System.out.println("\n7. modify Content in random areas, should fail\n");
         copyFile(orgJsaFile, jsa);
         modifyJsaContentRandomly();
-        testAndCheck(execArgs);
+        testAndCheck(verifyExecArgs);
     }
 }
--- a/test/jdk/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/jdk/java/net/ServerSocket/AcceptCauseFileDescriptorLeak.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,6 +41,7 @@
  */
 
 import java.io.IOException;
+import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.util.List;
@@ -80,7 +81,7 @@
             }
         }
 
-        final ServerSocket ss = new ServerSocket(0) {
+        final ServerSocket ss = new ServerSocket(0, 0, InetAddress.getLoopbackAddress()) {
             public Socket accept() throws IOException {
                 Socket s = new Socket() {
                 };
@@ -93,7 +94,7 @@
             public void run() {
                 try {
                     for (int i = 0; i < REPS; i++) {
-                        (new Socket("localhost", ss.getLocalPort())).close();
+                        (new Socket(InetAddress.getLoopbackAddress(), ss.getLocalPort())).close();
                     }
                 } catch (IOException e) {
                     e.printStackTrace();
--- a/test/jdk/java/net/ServerSocket/UnreferencedSockets.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/jdk/java/net/ServerSocket/UnreferencedSockets.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Field;
 import java.io.IOException;
+import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.SocketImpl;
@@ -71,8 +72,8 @@
 
         ServerSocket ss;
 
-        Server() throws IOException {
-            ss = new ServerSocket(0);
+        Server(InetAddress address) throws IOException {
+            ss = new ServerSocket(0, 0, address);
             pendingSockets.add(new NamedWeak(ss, pendingQueue, "serverSocket"));
             extractRefs(ss, "serverSocket");
         }
@@ -81,7 +82,6 @@
             return ss.getLocalPort();
         }
 
-
         public void run() {
             try {
                 Socket s = ss.accept();
@@ -111,9 +111,9 @@
 
     public static void main(String args[]) throws Exception {
         IPSupport.throwSkippedExceptionIfNonOperational();
-
+        InetAddress lba = InetAddress.getLoopbackAddress();
         // Create and close a ServerSocket to warm up the FD count for side effects.
-        try (ServerSocket s = new ServerSocket(0)) {
+        try (ServerSocket s = new ServerSocket(0, 0, lba)) {
             // no-op; close immediately
             s.getLocalPort();   // no-op
         }
@@ -122,11 +122,11 @@
         listProcFD();
 
         // start a server
-        Server svr = new Server();
+        Server svr = new Server(lba);
         Thread thr = new Thread(svr);
         thr.start();
 
-        Socket s = new Socket("localhost", svr.localPort());
+        Socket s = new Socket(lba, svr.localPort());
         pendingSockets.add(new NamedWeak(s, pendingQueue, "clientSocket"));
         extractRefs(s, "clientSocket");
 
--- a/test/jdk/java/net/URL/PerConnectionProxy.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/jdk/java/net/URL/PerConnectionProxy.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @bug 4920526
  * @summary Needs per connection proxy support for URLs
  * @modules java.base/sun.net.www
- * @library ../../../sun/net/www/httptest/
+ * @library ../../../sun/net/www/httptest/ /test/lib
  * @build ClosedChannelList TestHttpServer HttpTransaction HttpCallback
  * @compile PerConnectionProxy.java
  * @run main/othervm -Dhttp.proxyHost=inexistant -Dhttp.proxyPort=8080 PerConnectionProxy
@@ -33,7 +33,8 @@
 
 import java.net.*;
 import java.io.*;
-import sun.net.www.*;
+
+import jdk.test.lib.net.URIBuilder;
 
 public class PerConnectionProxy implements HttpCallback {
     static TestHttpServer server;
@@ -49,12 +50,17 @@
 
     public static void main(String[] args) {
         try {
-            server = new TestHttpServer (new PerConnectionProxy(), 1, 10, 0);
-            ProxyServer pserver = new ProxyServer(InetAddress.getByName("localhost"), server.getLocalPort());
+            InetAddress loopbackAddress = InetAddress.getLoopbackAddress();
+            server = new TestHttpServer(new PerConnectionProxy(), 1, 10, loopbackAddress, 0);
+            ProxyServer pserver = new ProxyServer(loopbackAddress, server.getLocalPort());
             // start proxy server
             new Thread(pserver).start();
 
-            URL url = new URL("http://localhost:"+server.getLocalPort());
+            URL url = URIBuilder.newBuilder()
+                    .scheme("http")
+                    .loopback()
+                    .port(server.getLocalPort())
+                    .toURLUnchecked();
 
             // for non existing proxy expect an IOException
             try {
@@ -80,7 +86,9 @@
             // for a normal proxy setting expect to see connection
             // goes through that proxy
             try {
-                InetSocketAddress isa = InetSocketAddress.createUnresolved("localhost", pserver.getPort());
+                InetSocketAddress isa = InetSocketAddress.createUnresolved(
+                        loopbackAddress.getHostAddress(),
+                        pserver.getPort());
                 Proxy p = new Proxy(Proxy.Type.HTTP, isa);
                 HttpURLConnection urlc = (HttpURLConnection)url.openConnection (p);
                 int respCode = urlc.getResponseCode();
@@ -115,7 +123,7 @@
         public ProxyServer(InetAddress server, int port) throws IOException {
             serverInetAddr = server;
             serverPort = port;
-            ss = new ServerSocket(0);
+            ss = new ServerSocket(0, 0, InetAddress.getLoopbackAddress());
         }
 
         public void run() {
--- a/test/jdk/java/net/URLConnection/Redirect307Test.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/jdk/java/net/URLConnection/Redirect307Test.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,11 +24,14 @@
 /**
  * @test
  * @bug 4380568 7095949
+ * @library /test/lib
  * @summary  HttpURLConnection does not support 307 redirects
  */
 import java.io.*;
 import java.net.*;
 
+import jdk.test.lib.net.URIBuilder;
+
 class RedirServer extends Thread {
 
     static final int TIMEOUT = 10 * 1000;
@@ -100,12 +103,16 @@
 
 public class Redirect307Test {
     public static void main(String[] args) throws Exception {
-        ServerSocket sock = new ServerSocket(0);
+        ServerSocket sock = new ServerSocket(0, 0, InetAddress.getLoopbackAddress());
         int port = sock.getLocalPort();
         RedirServer server = new RedirServer(sock);
         server.start();
 
-        URL url = new URL("http://localhost:" + port);
+        URL url = URIBuilder.newBuilder()
+                .scheme("http")
+                .loopback()
+                .port(port)
+                .toURL();
         URLConnection conURL =  url.openConnection();
         conURL.setDoInput(true);
         conURL.setAllowUserInteraction(false);
--- a/test/jdk/java/net/URLConnection/RedirectLimit.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/jdk/java/net/URLConnection/RedirectLimit.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,7 @@
 /**
  * @test
  * @bug 4458085 7095949
+ * @library /test/lib
  * @summary  Redirects Limited to 5
  */
 
@@ -35,6 +36,8 @@
 import java.io.*;
 import java.net.*;
 
+import jdk.test.lib.net.URIBuilder;
+
 class RedirLimitServer extends Thread {
     static final int TIMEOUT = 10 * 1000;
     static final int NUM_REDIRECTS = 9;
@@ -105,12 +108,16 @@
 
 public class RedirectLimit {
     public static void main(String[] args) throws Exception {
-        ServerSocket ss = new ServerSocket (0);
+        ServerSocket ss = new ServerSocket(0, 0, InetAddress.getLoopbackAddress());
         int port = ss.getLocalPort();
         RedirLimitServer server = new RedirLimitServer(ss);
         server.start();
 
-        URL url = new URL("http://localhost:" + port);
+        URL url = URIBuilder.newBuilder()
+                .scheme("http")
+                .loopback()
+                .port(port)
+                .toURL();
         URLConnection conURL =  url.openConnection();
 
         conURL.setDoInput(true);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/text/Collator/RuleBasedCollatorTest.java	Wed May 15 13:54:43 2019 +0530
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 4406815 8222969
+ * @summary RuleBasedCollatorTest uses very limited but selected test data
+ *  to test basic functionalities provided by RuleBasedCollator.
+ * @run testng/othervm RuleBasedCollatorTest
+ */
+
+import java.text.CollationElementIterator;
+import java.text.CollationKey;
+import java.text.RuleBasedCollator;
+import java.text.Collator;
+import java.text.ParseException;
+import java.util.Arrays;
+import java.util.Locale;
+
+import org.testng.annotations.BeforeGroups;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import org.testng.SkipException;
+import static org.testng.Assert.*;
+
+public class RuleBasedCollatorTest {
+
+    static RuleBasedCollator USC;
+    static String US_RULES;
+
+    @BeforeGroups("USC")
+    public void setup() {
+        Collator c = Collator.getInstance(Locale.US);
+        if (!(c instanceof RuleBasedCollator)) {
+            throw new SkipException("skip tests.");
+        }
+        USC = (RuleBasedCollator) c;
+        US_RULES = USC.getRules();
+    }
+
+
+    @DataProvider(name = "rulesData")
+    Object[][] rulesData() {
+        //Basic Tailor
+        String BASIC_TAILOR_RULES = "< b=c<\u00e6;A,a";
+        String[] BASIC_TAILOR_DATA = {"\u00e6", "b", "a", "c", "A"};
+        String[] BASIC_TAILOR_EXPECTED = {"b", "c", "\u00e6", "A", "a"};
+
+        //Contraction
+        String CONTRACTION_RULES = US_RULES + "& b < ch ,cH, Ch, CH < c ";
+        String[] CONTRACTION_DATA = {"b", "c", "ch", "CH", "Ch", "cH"};
+        String[] CONTRACTION_EXPECTED = {"b", "ch", "cH", "Ch", "CH", "c"};
+
+        //Expansion
+        String EXPANSION_RULES = US_RULES + "& ae = \u00e4 < b";
+        String[] EXPANSION_DATA = {"ad", "af", "\u00e4"};
+        String[] EXPANSION_EXPECTED = {"ad", "\u00e4", "af"};
+
+        //Punctuation
+        String PUNCTUATION_RULES = US_RULES + "< ' ' < '-'";
+        String[] PUNCTUATION_DATA = {"b-w", "b-W", "B-w", "B-W", "bW", "bw",
+                "Bw", "BW", "b w", "b W", "B w", "B W"};
+        String[] PUNCTUATION_EXPECTED = {"bw", "bW", "Bw", "BW", "b w", "b W",
+                "B w", "B W", "b-w", "b-W", "B-w", "B-W"};
+
+        return new Object[][] {
+                {BASIC_TAILOR_RULES, BASIC_TAILOR_DATA, BASIC_TAILOR_EXPECTED},
+                {CONTRACTION_RULES, CONTRACTION_DATA, CONTRACTION_EXPECTED},
+                {EXPANSION_RULES, EXPANSION_DATA, EXPANSION_EXPECTED},
+                {PUNCTUATION_RULES, PUNCTUATION_DATA, PUNCTUATION_EXPECTED}
+        };
+    }
+
+    @Test(dataProvider = "rulesData", groups = "USC")
+    public void testRules(String rules, String[] testData, String[] expected)
+            throws ParseException {
+        Arrays.sort(testData, new RuleBasedCollator(rules));
+        assertEquals(testData, expected);
+
+    }
+
+    @DataProvider(name = "FrenchSecondarySort")
+    Object[][] FrenchSecondarySort() {
+        return new Object[][] {
+                { "\u0061\u00e1\u0061", "\u00e1\u0061\u0061", 1 },
+                //{"\u0061\u00e1", "\u00e1\u0041", 1},  //JDK-4406815
+                //{"\u00e1\u0041", "\u0061\u00e1", -1}, //JDK-4406815
+                {"\u1ea0a", "\u1ea2A", -1}, //case ignore
+                { "\u1ea0b", "\u1ea2A", 1 },  //primary overwrite
+                { "\u1e15", "\u1e1d", -1 },   //ignore sec diacritic
+                { "a", "\u1ea1", -1 } };
+    }
+
+    @Test(dataProvider = "FrenchSecondarySort", groups = "USC")
+    public void testFrenchSecondarySort(String sData, String tData,
+            int expected) throws ParseException {
+        String french_rule = "@";
+        String rules = US_RULES + french_rule;
+        RuleBasedCollator rc = new RuleBasedCollator(rules);
+        int result = rc.compare(sData, tData);
+        assertEquals(expected, result);
+    }
+
+    @DataProvider(name = "ThaiLaoVowelConsonantSwapping")
+    Object[][] ThaiLaoVowelConsonantSwapping() {
+        return new Object[][] {{"\u0e44\u0e01", "\u0e40\u0e2e", -1},//swap
+                {"\u0e2e\u0e40", "\u0e01\u0e44", 1},//no swap
+                {"\u0e44\u0061", "\u0e40\u0081", 1}//no swap
+        };
+    }
+
+    @Test(dataProvider = "ThaiLaoVowelConsonantSwapping", groups = "USC")
+    public void testThaiLaoVowelConsonantSwapping(String sData, String tData,
+            int expected) throws ParseException {
+        String thai_rule = "& Z < \u0e01 < \u0e2e <\u0e40 < \u0e44!";
+        String rules = US_RULES + thai_rule;
+        RuleBasedCollator rc = new RuleBasedCollator(rules);
+        int result = rc.compare(sData, tData);
+        assertEquals(expected, result);
+    }
+
+    @Test
+    public void testIgnorableCharacter() throws ParseException {
+        String rule = "=f<a<c";
+        RuleBasedCollator rc = new RuleBasedCollator(rule);
+        CollationElementIterator iter = rc.getCollationElementIterator("f");
+        int element = iter.next();
+        int primary = iter.primaryOrder(element);
+        assertEquals(primary, 0);
+    }
+
+    @DataProvider(name = "Normalization")
+    Object[][] Normalization() {
+        return new Object[][] {
+                //micro sign has no canonical decomp mapping
+                // 0:NO_Decomposition;
+                // 1:CANONICAL_Decomposition;
+                // 2:FULL_Decomposition
+                {"\u00b5", "\u03BC", 0, -1},
+                {"\u00b5", "\u03BC", 1, -1},
+                {"\u00b5", "\u03BC", 2, 0}
+        };
+    }
+
+    @Test(dataProvider = "Normalization", groups = "USC")
+    public void testNormalization(String sData, String tData, int decomp,
+            int result) {
+        RuleBasedCollator rc = (RuleBasedCollator)USC.clone();
+        rc.setDecomposition(decomp);
+        assertEquals(rc.compare(sData, tData), result);
+    }
+
+    @Test
+    public void testEquality() throws ParseException {
+        String rule1 = "<a=b";
+        RuleBasedCollator rc1= new RuleBasedCollator(rule1);
+        //test equals()
+        assertTrue(rc1.equals(new RuleBasedCollator(rule1)));
+
+        //test semantic equality
+        String[] array1 = {"b", "c", "a"};
+        String[] array2 = Arrays.copyOf(array1, array1.length);
+        String[] expected = {"b", "a", "c"};
+        String rule2 = "<b=a";
+        RuleBasedCollator rc2= new RuleBasedCollator(rule2);
+
+        Arrays.sort(array1, rc1);
+        Arrays.sort(array2, rc2);
+        assertEquals(array1, array2);
+        assertEquals(array1, expected);
+    }
+
+    @Test
+    public void testBasicParsingOrder() throws ParseException {
+        String rule1 = "< a < b & a < c";
+        String rule2 = "< a < c & a < b";
+        String rule3 = "< a < b < c";
+        String s = "abc";
+        RuleBasedCollator c1 = new RuleBasedCollator(rule1);
+        RuleBasedCollator c2 = new RuleBasedCollator(rule2);
+        RuleBasedCollator c3 = new RuleBasedCollator(rule3);
+        CollationKey k1 = c1.getCollationKey(s);
+        CollationKey k2 = c2.getCollationKey(s);
+        CollationKey k3 = c3.getCollationKey(s);
+        //rule1 should not equals to rule2
+        assertEquals(k1.compareTo(k2) == 0, false);
+
+        //rule2 should equals to rule3
+        assertEquals(k2.compareTo(k3) == 0, true);
+    }
+
+    @DataProvider(name = "ParseData")
+    Object[][] ParseData() {
+        return new Object[][] {
+                {""},
+                {"a < b"},
+                {"< a-b < c"},
+                {"< ,a"},
+                {"< a < b & c < d"}
+        };
+    }
+
+    @Test(dataProvider = "ParseData",
+            expectedExceptions = ParseException.class)
+    public void testParseException(String rule) throws ParseException{
+        new RuleBasedCollator(rule);
+    }
+
+    @Test(expectedExceptions = NullPointerException.class)
+    public void testNullParseException() throws ParseException{
+        new RuleBasedCollator(null);
+    }
+}
--- a/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarHttpProperties.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/jdk/java/util/jar/JarFile/mrjar/MultiReleaseJarHttpProperties.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @test
  * @bug 8132734 8194070
  * @summary Test the System properties for JarFile that support multi-release jar files
- * @library /lib/testlibrary/java/util/jar
+ * @library /lib/testlibrary/java/util/jar /test/lib
  * @modules jdk.jartool
  *          jdk.compiler
  *          jdk.httpserver
@@ -44,9 +44,12 @@
  */
 
 import java.io.IOException;
+import java.net.InetAddress;
 import java.net.URL;
 import java.net.URLClassLoader;
 
+import jdk.test.lib.net.URIBuilder;
+
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -57,7 +60,7 @@
 
     @BeforeClass
     public void initialize() throws Exception {
-        server = new SimpleHttpServer();
+        server = new SimpleHttpServer(InetAddress.getLoopbackAddress());
         server.start();
         super.initialize();
     }
@@ -65,7 +68,8 @@
     @Override
     protected void initializeClassLoader() throws Exception {
         URL[] urls = new URL[]{
-                new URL("http://localhost:" + server.getPort() + "/multi-release.jar")
+                URIBuilder.newBuilder().scheme("http").port(server.getPort()).loopback()
+                        .path("/multi-release.jar").toURL(),
         };
         cldr = new URLClassLoader(urls);
         // load any class, Main is convenient and in the root entries
--- a/test/jdk/jdk/nio/zipfs/ZipFSTester.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/jdk/jdk/nio/zipfs/ZipFSTester.java	Wed May 15 13:54:43 2019 +0530
@@ -228,7 +228,7 @@
                 Files.newInputStream(parent);
                 throw new RuntimeException("Failed");
             } catch (FileSystemException e) {
-                e.printStackTrace();    // expected fse
+                // expected fse
             }
 
             // rmdirs
@@ -420,7 +420,15 @@
 
     static Object[][] getEntries() {
         Object[][] entries = new Object[10 + rdm.nextInt(20)][3];
-        for (int i = 0; i < entries.length; i++) {
+        // first entries shall test the corner case of 0 bytes of data
+        entries[0][0] = "entries" + 0;
+        entries[0][1] = METHOD_STORED;
+        entries[0][2] = new byte[0];
+        entries[1][0] = "entries" + 1;
+        entries[1][1] = METHOD_DEFLATED;
+        entries[1][2] = new byte[0];
+        // the rest is random data
+        for (int i = 2; i < entries.length; i++) {
             entries[i][0] = "entries" + i;
             entries[i][1] = rdm.nextInt(10) % 2 == 0 ?
                 METHOD_STORED : METHOD_DEFLATED;
--- a/test/jdk/lib/testlibrary/java/util/jar/SimpleHttpServer.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/jdk/lib/testlibrary/java/util/jar/SimpleHttpServer.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -42,13 +43,19 @@
     private static final Path multirelease = Paths.get(userdir, "multi-release.jar");
 
     private final HttpServer server;
+    private final InetAddress address;
 
     public SimpleHttpServer() throws IOException {
+        this(null);
+    }
+
+    public SimpleHttpServer(InetAddress addr) throws IOException {
+        address = addr;
         server = HttpServer.create();
     }
 
     public void start() throws IOException {
-        server.bind(new InetSocketAddress(0), 0);
+        server.bind(new InetSocketAddress(address, 0), 0);
         server.createContext("/multi-release.jar", t -> {
             try (InputStream is = t.getRequestBody()) {
                 is.readAllBytes();  // probably not necessary to consume request
--- a/test/jdk/sun/net/www/protocol/http/RetryUponTimeout.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/jdk/sun/net/www/protocol/http/RetryUponTimeout.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,7 @@
     static int count = 0;
     public static void main(String[] args) throws Exception {
         try {
-            server = new ServerSocket (0);
+            server = new ServerSocket(0, 0, InetAddress.getLoopbackAddress());
             int port = server.getLocalPort ();
             new Thread(new RetryUponTimeout()).start ();
 
--- a/test/jdk/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/jdk/sun/net/www/protocol/jar/MultiReleaseJarURLConnection.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
  * @test
  * @bug 8132734 8144062 8159785 8194070
  * @summary Test that URL connections to multi-release jars can be runtime versioned
- * @library /lib/testlibrary/java/util/jar
+ * @library /lib/testlibrary/java/util/jar /test/lib
  * @modules jdk.compiler
  *          jdk.httpserver
  *          jdk.jartool
@@ -38,7 +38,11 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.net.InetAddress;
 import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.net.URLConnection;
@@ -47,6 +51,8 @@
 import java.util.Enumeration;
 import java.util.jar.JarFile;
 
+import jdk.test.lib.net.URIBuilder;
+
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -68,7 +74,7 @@
         creator.buildMultiReleaseJar();
         creator.buildSignedMultiReleaseJar();
 
-        server = new SimpleHttpServer();
+        server = new SimpleHttpServer(InetAddress.getLoopbackAddress());
         server.start();
 
     }
@@ -167,9 +173,9 @@
                 {"unsigned", new URL("jar:file:" + unsigned + "!/")},
                 {"signed", new URL("jar:file:" + signed + "!/")},
                 // external jar received via http protocol
-                {"http", new URL("jar:http://localhost:" + server.getPort() + "/multi-release.jar!/")},
-                {"http", new URL("http://localhost:" + server.getPort() + "/multi-release.jar")},
-
+                {"http", toHttpJarURL(server.getPort(), "/multi-release.jar", "!/")},
+                {"http", URIBuilder.newBuilder().scheme("http").port(server.getPort())
+                        .loopback().path("/multi-release.jar").toURL()},
         };
     }
 
@@ -220,6 +226,18 @@
         cldr.close();
     }
 
+    private static URL toHttpJarURL(int port, String jar, String file)
+            throws MalformedURLException, URISyntaxException {
+        assert file.startsWith("!/");
+        URI httpURI = URIBuilder.newBuilder()
+                .scheme("http")
+                .loopback()
+                .port(port)
+                .path(jar)
+                .build();
+        return new URL("jar:" + httpURI + file);
+    }
+
     private boolean readAndCompare(URL url, String match) throws Exception {
         boolean result;
         // necessary to do it this way, instead of openStream(), so we can
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/T8215470/BadEnclosingMethodAttrTest.java	Wed May 15 13:54:43 2019 +0530
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8215470
+ * @summary Bad EnclosingMethod attribute on classes declared in lambdas
+ * @modules jdk.compiler/com.sun.tools.javac.util
+ */
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import com.sun.tools.javac.util.Assert;
+
+public class BadEnclosingMethodAttrTest<T> {
+    protected BadEnclosingMethodAttrTest() {
+        Assert.check(getClass().getEnclosingMethod().toString().equals("static void BadEnclosingMethodAttrTest.lambdaScope(java.lang.Object)"));
+        Type typeFromEnclosingMethod = getClass().getEnclosingMethod().getGenericParameterTypes()[0];
+        ParameterizedType paramType = (ParameterizedType) getClass().getGenericSuperclass();
+        Type typeFromGenericClass = paramType.getActualTypeArguments()[0];
+        Assert.check(typeFromEnclosingMethod.equals(typeFromGenericClass));
+    }
+
+    static <X> void lambdaScope(X x) {
+        Runnable r = () -> {
+            new BadEnclosingMethodAttrTest<X>() {};
+        };
+        r.run();
+    }
+
+    public static void main(final String[] args) {
+        lambdaScope("");
+    }
+}
--- a/test/langtools/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/langtools/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8042931
+ * @bug 8042931 8215470
  * @summary Checking EnclosingMethod attribute of anonymous/local class.
  * @library /tools/lib /tools/javac/lib ../lib
  * @modules jdk.compiler/com.sun.tools.javac.api
@@ -245,7 +245,7 @@
         // anonymous and local classes in lambda
         @ExpectedEnclosingMethod(
                 info = "EnclosingLambda in EnclosingMethodTest",
-                enclosingMethod = "lambda",
+                enclosingMethod = "<init>",
                 enclosingClazz = EnclosingMethodTest.class
         )
         class EnclosingLambda {
@@ -325,7 +325,7 @@
             // anonymous and local classes in lambda
             @ExpectedEnclosingMethod(
                     info = "EnclosingLambda in notEnclosing01",
-                    enclosingMethod = "lambda",
+                    enclosingMethod = "<init>",
                     enclosingClazz = notEnclosing01.class
             )
             class EnclosingLambda {
@@ -382,7 +382,7 @@
             // anonymous and local classes in lambda
             @ExpectedEnclosingMethod(
                     info = "EnclosingLambda in notEnclosing02",
-                    enclosingMethod = "lambda",
+                    enclosingMethod = "<clinit>",
                     enclosingClazz = notEnclosing02.class
             )
             class EnclosingLambda {
@@ -460,7 +460,7 @@
             // anonymous and local classes in lambda
             @ExpectedEnclosingMethod(
                     info = "EnclosingLambda in notEnclosing03",
-                    enclosingMethod = "lambda",
+                    enclosingMethod = "<init>",
                     enclosingClazz = notEnclosing03.class
             )
             class EnclosingLambda {
@@ -517,7 +517,7 @@
             // anonymous and local classes in lambda
             @ExpectedEnclosingMethod(
                     info = "EnclosingLambda in notEnclosing04",
-                    enclosingMethod = "lambda",
+                    enclosingMethod = "<clinit>",
                     enclosingClazz = notEnclosing04.class
             )
             class EnclosingLambda {
--- a/test/langtools/tools/javac/lambda/LambdaInnerTypeVarReflect.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/langtools/tools/javac/lambda/LambdaInnerTypeVarReflect.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -77,7 +77,7 @@
 
         String javapOut = sw.toString();
         assertTrue(javapOut.contains(innerName));
-        assertTrue(!javapOut.contains("RRRRR"));
+        assertTrue(javapOut.contains("RRRRR"));
     }
 
     public static void main(String[] args) throws IOException {
--- a/test/micro/org/openjdk/bench/java/net/SocketReadWrite.java	Tue May 14 11:23:08 2019 +0530
+++ b/test/micro/org/openjdk/bench/java/net/SocketReadWrite.java	Wed May 15 13:54:43 2019 +0530
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -22,86 +22,194 @@
  */
 package org.openjdk.bench.java.net;
 
+import org.openjdk.jmh.annotations.Benchmark;
+import org.openjdk.jmh.annotations.BenchmarkMode;
+import org.openjdk.jmh.annotations.Mode;
+import org.openjdk.jmh.annotations.OutputTimeUnit;
+import org.openjdk.jmh.annotations.Param;
+import org.openjdk.jmh.annotations.Scope;
+import org.openjdk.jmh.annotations.Setup;
+import org.openjdk.jmh.annotations.State;
+import org.openjdk.jmh.annotations.TearDown;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.Socket;
-import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.TimeUnit;
 
-import org.openjdk.jmh.annotations.BenchmarkMode;
-import org.openjdk.jmh.annotations.Benchmark;
-import org.openjdk.jmh.annotations.Mode;
-import org.openjdk.jmh.annotations.OutputTimeUnit;
-import org.openjdk.jmh.annotations.Scope;
-import org.openjdk.jmh.annotations.Setup;
-import org.openjdk.jmh.annotations.State;
-import org.openjdk.jmh.annotations.TearDown;
-
 /**
- * Tests the overheads of I/O API.
- * This test is known to depend heavily on network conditions and paltform.
+ * Benchmark socket read/write.
+ *
  */
 @BenchmarkMode(Mode.Throughput)
-@OutputTimeUnit(TimeUnit.MILLISECONDS)
+@OutputTimeUnit(TimeUnit.SECONDS)
 @State(Scope.Thread)
 public class SocketReadWrite {
 
-    private OutputStream os;
-    private InputStream is;
-    private ServerSocket ss;
-    private Socket s1, s2;
-    private ReadThread rt;
+    static final InetAddress address = InetAddress.getLoopbackAddress();
+    public static final int TIMEOUT = 10000;
+
+    static class EchoServer implements Runnable {
+        // EchoServer is implemented to execute the same amount echo threads as benchmarking threads are running
+
+        final ServerSocket ss;
+        final int port;
+        final CountDownLatch startedLatch;
+        final int size;
+        final boolean timeout;
+        List<ServerThread> threads = new ArrayList<>();
+        volatile boolean isDone = false;
+
+        public EchoServer(CountDownLatch await, int size, boolean timeout) throws IOException {
+            this.size = size;
+            this.timeout = timeout;
+            ss = new ServerSocket(0);
+            port = ss.getLocalPort();
+            this.startedLatch = await;
+        }
+
+        @Override
+        public void run() {
+            startedLatch.countDown();
+            while (!isDone) {
+                try {
+                    Socket s = ss.accept();
+                    s.setTcpNoDelay(true);
+                    if (timeout) {
+                        s.setSoTimeout(TIMEOUT);
+                    }
+                    ServerThread st = new ServerThread(s, size);
+                    threads.add(st);
+                    new Thread(st).start();
+                } catch (IOException e) {
+                    if (!isDone) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+
+        synchronized void close() throws IOException {
+            if (!isDone) {
+                isDone = true;
+                ss.close();
+                for (ServerThread st : threads) {
+                    st.close();
+                }
+            }
+        }
+
+        static EchoServer instance = null;
+
+        static synchronized EchoServer startServer(int size, boolean timeout) throws IOException {
+            if (instance == null) {
+                CountDownLatch started = new CountDownLatch(1);
+                EchoServer s = new EchoServer(started, size, timeout);
+                new Thread(s).start();
+                try {
+                    started.await(); // wait until server thread started
+                } catch (InterruptedException e) {
+                    e.printStackTrace();
+                }
+                instance = s;
+            }
+            return instance;
+        }
+
+        static class ServerThread implements Runnable {
+
+            final Socket s;
+            final InputStream in;
+            final OutputStream out;
+            final int size;
+            volatile boolean isDone = false;
+
+            ServerThread(Socket s, int size) throws IOException {
+                this.s = s;
+                this.size = size;
+                in = s.getInputStream();
+                out = s.getOutputStream();
+            }
+
+            @Override
+            public void run() {
+                byte[] a = new byte[size];
+                while (!isDone) {
+                    try {
+                        readN(a, size, this.in);
+                        out.write(a);
+                    } catch (IOException e) {
+                        if (!isDone) {
+                            e.printStackTrace();
+                        }
+                    }
+                }
+            }
+
+            public void close() throws IOException {
+                isDone = true;
+                s.close();
+            }
+
+        }
+    }
+
+    static void readN(byte[] array, int size, InputStream in) throws IOException {
+        int nread = 0;
+        while (size > 0) {
+            int n = in.read(array, nread, size);
+            if (n < 0) throw new RuntimeException();
+            nread += n;
+            size -= n;
+        }
+    }
+
+    EchoServer server;
+
+    @Param({"1", "1024", "8192", "64000", "128000"})
+    public int size;
+
+    @Param({"false", "true"})
+    public boolean timeout;
+
+    Socket s;
+    InputStream in;
+    OutputStream out;
+    byte[] array;
 
     @Setup
-    public void beforeRun() throws IOException {
-        InetAddress iaddr = InetAddress.getLocalHost();
-
-        ss = new ServerSocket(0);
-        s1 = new Socket(iaddr, ss.getLocalPort());
-        s2 = ss.accept();
-
-        os = s1.getOutputStream();
-        is = s2.getInputStream();
-
-        rt = new ReadThread(is);
-        rt.start();
+    public void setup() throws IOException {
+        server = EchoServer.startServer(size, timeout);
+        int port = server.port;
+        s = new Socket(address, port);
+        s.setTcpNoDelay(true);
+        if (timeout) {
+            s.setSoTimeout(TIMEOUT);
+            // 10 seconds times is quite large and never will happen (for microbenchmarking),
+            // but it's required since other paths inside SocketImpl are involved
+        }
+        in = s.getInputStream();
+        out = s.getOutputStream();
+        array = new byte[size];
+        ThreadLocalRandom.current().nextBytes(array);
     }
 
     @TearDown
-    public void afterRun() throws IOException, InterruptedException {
-        os.write(0);
-        os.close();
-        is.close();
-        s1.close();
-        s2.close();
-        ss.close();
-        rt.join();
+    public void tearDown() throws IOException {
+        server.close();
+        s.close();
     }
 
     @Benchmark
-    public void test() throws IOException {
-        os.write((byte) 4711);
+    public void echo() throws IOException {
+        out.write(array);
+        readN(array, size, in);
     }
-
-    static class ReadThread extends Thread {
-        private InputStream is;
-
-        public ReadThread(InputStream is) {
-            this.is = is;
-        }
-
-        public void run() {
-            try {
-                while (is.read() > 0);
-            } catch (SocketException ex) {
-                // ignore - most likely "socket closed", which means shutdown
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-    }
-
 }