changeset 10884:adc340baec52 icedtea-3.18.0

Merge jdk8u282-ga
author Andrew John Hughes <gnu_andrew@member.fsf.org>
date Wed, 03 Feb 2021 05:23:32 +0000
parents fe46f1f4ef29 (current diff) 54f222098a52 (diff)
children bd59a2227d4d
files .hgtags THIRD_PARTY_README make/bsd/makefiles/gcc.make make/linux/makefiles/gcc.make make/solaris/makefiles/gcc.make src/cpu/x86/vm/x86_32.ad src/cpu/zero/vm/cppInterpreter_zero.cpp src/os/bsd/vm/os_bsd.cpp src/os/linux/vm/os_linux.cpp src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp src/os_cpu/linux_x86/vm/os_linux_x86.cpp src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp src/os_cpu/linux_zero/vm/os_linux_zero.cpp src/share/vm/classfile/classFileParser.cpp src/share/vm/classfile/classLoader.cpp src/share/vm/classfile/defaultMethods.cpp src/share/vm/classfile/symbolTable.cpp src/share/vm/classfile/systemDictionary.cpp src/share/vm/classfile/verifier.cpp src/share/vm/compiler/compileBroker.cpp src/share/vm/compiler/compilerOracle.cpp src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp src/share/vm/gc_implementation/g1/g1RemSet.cpp src/share/vm/gc_implementation/g1/heapRegion.cpp src/share/vm/gc_interface/collectedHeap.cpp src/share/vm/gc_interface/collectedHeap.hpp src/share/vm/memory/allocation.cpp src/share/vm/memory/genCollectedHeap.cpp src/share/vm/memory/heapInspection.hpp src/share/vm/memory/metaspaceShared.hpp src/share/vm/oops/constantPool.hpp src/share/vm/oops/oop.inline.hpp src/share/vm/opto/c2_globals.hpp src/share/vm/prims/jvm.cpp src/share/vm/prims/whitebox.cpp src/share/vm/runtime/globals.hpp src/share/vm/runtime/objectMonitor.cpp src/share/vm/runtime/os.cpp src/share/vm/runtime/reflection.cpp src/share/vm/runtime/sharedRuntime.cpp src/share/vm/services/jmm.h src/share/vm/services/management.cpp src/share/vm/services/memTracker.hpp src/share/vm/utilities/taskqueue.hpp test/runtime/containers/docker/Dockerfile-BasicTest test/runtime/containers/docker/Dockerfile-BasicTest-aarch64 test/runtime/containers/docker/Dockerfile-BasicTest-ppc64le test/runtime/containers/docker/Dockerfile-BasicTest-s390x test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
diffstat 73 files changed, 1241 insertions(+), 826 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Tue Jan 19 17:18:24 2021 +0000
+++ b/.hgtags	Wed Feb 03 05:23:32 2021 +0000
@@ -1412,13 +1412,23 @@
 cbabffce5685f9a18bfd05bd1fb18c4c73be98cf jdk8u272-b04
 1b2d99958c293b7ab324c5786664f82c8e9c4e50 jdk8u272-b05
 4b0aa85a95653f44cc45f2ec0571153017ebbf03 jdk8u272-b06
+4b0aa85a95653f44cc45f2ec0571153017ebbf03 jdk8u282-b00
 4689eaf1a5c9c5e284d466631420761f4bd4ecae jdk8u272-b07
 a0eb08e2db5a40956a9c2d6b7dea76a894559033 jdk8u272-b08
 176a7e5cc0609cface769e5e8a31b00700d223ba jdk8u272-b09
 6b836efa38fef1b50ba798b6e344ab44ee995812 jdk8u272-b10
 6b836efa38fef1b50ba798b6e344ab44ee995812 jdk8u272-ga
 7caa24d952f7a997decdd33dcfed5261f6e0b74b icedtea-3.17.0
+7f7c1e1fbc8a70f9730339872ddf56fee812304c jdk8u282-b01
 6b836efa38fef1b50ba798b6e344ab44ee995812 jdk8u275-b00
 b36c3f635d937798abe5e7c5a40a868705fed15e jdk8u275-b01
 b36c3f635d937798abe5e7c5a40a868705fed15e jdk8u275-ga
 e7fd2b284bd059020c3edfa7ba8c02febe0d5a59 icedtea-3.17.1
+312e9cb580c5c3f8f6ebf660b1f78ff060590ac4 jdk8u282-b02
+83661fdee9f08747a1d7a98123c00732b6a3a43d jdk8u282-b03
+d7c102fe9c4736bca65b25da69093d84da141e65 jdk8u282-b04
+d84cbe66ce9f5a4ea0a2e6c0fa99535248d32f00 jdk8u282-b05
+a29ba3f778d781d63dc725b24526ef4ad3cd5931 jdk8u282-b06
+3d42d5d7117dc6559c0d71fc8fceaaab96de376f jdk8u282-b07
+fcfacb8f9da0749c20b9618246adda82e5e6241f jdk8u282-b08
+fcfacb8f9da0749c20b9618246adda82e5e6241f jdk8u282-ga
--- a/THIRD_PARTY_README	Tue Jan 19 17:18:24 2021 +0000
+++ b/THIRD_PARTY_README	Wed Feb 03 05:23:32 2021 +0000
@@ -155,11 +155,11 @@
 -------------------------------------------------------------------------------
 
 %% This notice is provided with respect to CUP Parser Generator for 
-Java 0.10k, which may be included with JRE 8, JDK 8, and OpenJDK 8.
+Java 0.10b, which may be included with JRE 8, JDK 8, and OpenJDK 8.
 
 --- begin of LICENSE ---
 
-Copyright 1996-1999 by Scott Hudson, Frank Flannery, C. Scott Ananian
+Copyright 1996-2015 by Scott Hudson, Frank Flannery, C. Scott Ananian, Michael Petter
 
 Permission to use, copy, modify, and distribute this software and its
 documentation for any purpose and without fee is hereby granted, provided
@@ -1672,13 +1672,13 @@
 
 -------------------------------------------------------------------------------
 
-%% This notice is provided with respect to Little CMS 2.9, which may be
+%% This notice is provided with respect to Little CMS 2.11, which may be
 included with JRE 8, JDK 8, and OpenJDK 8.
 
 --- begin of LICENSE ---
 
 Little CMS
-Copyright (c) 1998-2011 Marti Maria Saguer
+Copyright (c) 1998-2020 Marti Maria Saguer
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
@@ -3028,7 +3028,7 @@
   Apache Commons Math 3.2
   Apache Derby 10.11.1.2
   Apache Jakarta BCEL 5.1 
-  Apache Santuario XML Security for Java 2.1.1
+  Apache Santuario XML Security for Java 2.1.3
   Apache Xalan-Java 2.7.2
   Apache Xerces Java 2.10.0 
   Apache XML Resolver 1.1 
--- a/make/bsd/makefiles/gcc.make	Tue Jan 19 17:18:24 2021 +0000
+++ b/make/bsd/makefiles/gcc.make	Wed Feb 03 05:23:32 2021 +0000
@@ -260,7 +260,7 @@
   WARNINGS_ARE_ERRORS += -Wno-empty-body
 endif
 
-WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value
+WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wformat=2
 
 ifeq ($(USE_CLANG),)
   # Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
@@ -289,7 +289,7 @@
 # The flags to use for an Optimized g++ build
 ifeq ($(OS_VENDOR), Darwin)
   # use -Os by default, unless -O3 can be proved to be worth the cost, as per policy
-  # <http://wikis.sun.com/display/OpenJDK/Mac+OS+X+Port+Compilers>
+  # <https://wiki.openjdk.java.net/display/MacOSXPort/Compiler+Errata>
   OPT_CFLAGS_DEFAULT ?= SIZE
 else
   OPT_CFLAGS_DEFAULT ?= SPEED
--- a/make/linux/makefiles/gcc.make	Tue Jan 19 17:18:24 2021 +0000
+++ b/make/linux/makefiles/gcc.make	Wed Feb 03 05:23:32 2021 +0000
@@ -214,7 +214,7 @@
   WARNINGS_ARE_ERRORS += -Wno-return-type -Wno-empty-body -Qunused-arguments -Wno-uninitialized
 endif
 
-WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -Wreturn-type
+WARNING_FLAGS = -Wpointer-arith -Wsign-compare -Wundef -Wunused-function -Wunused-value -Wformat=2 -Wreturn-type
 
 ifeq ($(USE_CLANG),)
   # Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
--- a/make/solaris/makefiles/gcc.make	Tue Jan 19 17:18:24 2021 +0000
+++ b/make/solaris/makefiles/gcc.make	Wed Feb 03 05:23:32 2021 +0000
@@ -120,7 +120,7 @@
 WARNINGS_ARE_ERRORS = -Werror
 endif
 # Enable these warnings. See 'info gcc' about details on these options
-WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef
+WARNING_FLAGS = -Wpointer-arith -Wconversion -Wsign-compare -Wundef -Wformat=2
 CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(WARNING_FLAGS)
 # Special cases 
 CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@))  
--- a/src/cpu/zero/vm/cppInterpreter_zero.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -100,7 +100,9 @@
     case T_DOUBLE:
     case T_VOID:
       return result;
-    default  : ShouldNotReachHere(); return NULL_WORD;
+    default:
+      ShouldNotReachHere();
+      return NULL_WORD; // silence compiler warnings
   }
 }
 
--- a/src/os/bsd/vm/os_bsd.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/os/bsd/vm/os_bsd.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1885,7 +1885,7 @@
         jrelib_p = buf + len;
         snprintf(jrelib_p, buflen-len, "/%s", COMPILER_VARIANT);
         if (0 != access(buf, F_OK)) {
-          snprintf(jrelib_p, buflen-len, "");
+          snprintf(jrelib_p, buflen-len, "%s", "");
         }
 
         // If the path exists within JAVA_HOME, add the JVM library name
--- a/src/os/linux/vm/osContainer_linux.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/os/linux/vm/osContainer_linux.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -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
@@ -34,12 +34,15 @@
 
 bool  OSContainer::_is_initialized   = false;
 bool  OSContainer::_is_containerized = false;
+int   OSContainer::_active_processor_count = 1;
 julong _unlimited_memory;
 
 class CgroupSubsystem: CHeapObj<mtInternal> {
  friend class OSContainer;
 
  private:
+    volatile jlong _next_check_counter;
+
     /* mountinfo contents */
     char *_root;
     char *_mount_point;
@@ -52,6 +55,7 @@
       _root = os::strdup(root);
       _mount_point = os::strdup(mountpoint);
       _path = NULL;
+      _next_check_counter = min_jlong;
     }
 
     /*
@@ -80,14 +84,14 @@
             buf[MAXPATHLEN-1] = '\0';
             _path = os::strdup(buf);
           } else {
-            char *p = strstr(_root, cgroup_path);
+            char *p = strstr(cgroup_path, _root);
             if (p != NULL && p == _root) {
               if (strlen(cgroup_path) > strlen(_root)) {
                 int buflen;
                 strncpy(buf, _mount_point, MAXPATHLEN);
                 buf[MAXPATHLEN-1] = '\0';
                 buflen = strlen(buf);
-                if ((buflen + strlen(cgroup_path)) > (MAXPATHLEN-1)) {
+                if ((buflen + strlen(cgroup_path) - strlen(_root)) > (MAXPATHLEN-1)) {
                   return;
                 }
                 strncat(buf, cgroup_path + strlen(_root), MAXPATHLEN-buflen);
@@ -101,6 +105,14 @@
     }
 
     char *subsystem_path() { return _path; }
+
+    bool cache_has_expired() {
+      return os::elapsed_counter() > _next_check_counter;
+    }
+
+    void set_cache_expiry_time(jlong timeout) {
+      _next_check_counter = os::elapsed_counter() + timeout;
+    }
 };
 
 CgroupSubsystem* memory = NULL;
@@ -214,16 +226,11 @@
  * we are running under cgroup control.
  */
 void OSContainer::init() {
-  int mountid;
-  int parentid;
-  int major;
-  int minor;
   FILE *mntinfo = NULL;
   FILE *cgroup = NULL;
   char buf[MAXPATHLEN+1];
   char tmproot[MAXPATHLEN+1];
   char tmpmount[MAXPATHLEN+1];
-  char tmpbase[MAXPATHLEN+1];
   char *p;
   jlong mem_limit;
 
@@ -263,99 +270,27 @@
       return;
   }
 
-  while ( (p = fgets(buf, MAXPATHLEN, mntinfo)) != NULL) {
-    // Look for the filesystem type and see if it's cgroup
-    char fstype[MAXPATHLEN+1];
-    fstype[0] = '\0';
-    char *s =  strstr(p, " - ");
-    if (s != NULL &&
-        sscanf(s, " - %s", fstype) == 1 &&
-        strcmp(fstype, "cgroup") == 0) {
+  while ((p = fgets(buf, MAXPATHLEN, mntinfo)) != NULL) {
+    char tmpcgroups[MAXPATHLEN+1];
+    char *cptr = tmpcgroups;
+    char *token;
 
-      if (strstr(p, "memory") != NULL) {
-        int matched = sscanf(p, "%d %d %d:%d %s %s",
-                             &mountid,
-                             &parentid,
-                             &major,
-                             &minor,
-                             tmproot,
-                             tmpmount);
-        if (matched == 6) {
-          memory = new CgroupSubsystem(tmproot, tmpmount);
-        }
-        else
-          if (PrintContainerInfo) {
-            tty->print_cr("Incompatible str containing cgroup and memory: %s", p);
-          }
-      } else if (strstr(p, "cpuset") != NULL) {
-        int matched = sscanf(p, "%d %d %d:%d %s %s",
-                             &mountid,
-                             &parentid,
-                             &major,
-                             &minor,
-                             tmproot,
-                             tmpmount);
-        if (matched == 6) {
-          cpuset = new CgroupSubsystem(tmproot, tmpmount);
-        }
-        else {
-          if (PrintContainerInfo) {
-            tty->print_cr("Incompatible str containing cgroup and cpuset: %s", p);
-          }
-        }
-      } else if (strstr(p, "cpu,cpuacct") != NULL || strstr(p, "cpuacct,cpu") != NULL) {
-        int matched = sscanf(p, "%d %d %d:%d %s %s",
-                             &mountid,
-                             &parentid,
-                             &major,
-                             &minor,
-                             tmproot,
-                             tmpmount);
-        if (matched == 6) {
-          cpu = new CgroupSubsystem(tmproot, tmpmount);
-          cpuacct = new CgroupSubsystem(tmproot, tmpmount);
-        }
-        else {
-          if (PrintContainerInfo) {
-            tty->print_cr("Incompatible str containing cgroup and cpu,cpuacct: %s", p);
-          }
-        }
-      } else if (strstr(p, "cpuacct") != NULL) {
-        int matched = sscanf(p, "%d %d %d:%d %s %s",
-                             &mountid,
-                             &parentid,
-                             &major,
-                             &minor,
-                             tmproot,
-                             tmpmount);
-        if (matched == 6) {
-          cpuacct = new CgroupSubsystem(tmproot, tmpmount);
-        }
-        else {
-          if (PrintContainerInfo) {
-            tty->print_cr("Incompatible str containing cgroup and cpuacct: %s", p);
-          }
-        }
-      } else if (strstr(p, "cpu") != NULL) {
-        int matched = sscanf(p, "%d %d %d:%d %s %s",
-                             &mountid,
-                             &parentid,
-                             &major,
-                             &minor,
-                             tmproot,
-                             tmpmount);
-        if (matched == 6) {
-          cpu = new CgroupSubsystem(tmproot, tmpmount);
-        }
-        else {
-          if (PrintContainerInfo) {
-            tty->print_cr("Incompatible str containing cgroup and cpu: %s", p);
-          }
-        }
+    // mountinfo format is documented at https://www.kernel.org/doc/Documentation/filesystems/proc.txt
+    if (sscanf(p, "%*d %*d %*d:%*d %s %s %*[^-]- cgroup %*s %s", tmproot, tmpmount, tmpcgroups) != 3) {
+      continue;
+    }
+    while ((token = strsep(&cptr, ",")) != NULL) {
+      if (strcmp(token, "memory") == 0) {
+        memory = new CgroupSubsystem(tmproot, tmpmount);
+      } else if (strcmp(token, "cpuset") == 0) {
+        cpuset = new CgroupSubsystem(tmproot, tmpmount);
+      } else if (strcmp(token, "cpu") == 0) {
+        cpu = new CgroupSubsystem(tmproot, tmpmount);
+      } else if (strcmp(token, "cpuacct") == 0) {
+        cpuacct= new CgroupSubsystem(tmproot, tmpmount);
       }
     }
   }
-
   fclose(mntinfo);
 
   if (memory == NULL) {
@@ -415,30 +350,30 @@
     return;
   }
 
-  while ( (p = fgets(buf, MAXPATHLEN, cgroup)) != NULL) {
-    int cgno;
-    int matched;
-    char *controller;
+  while ((p = fgets(buf, MAXPATHLEN, cgroup)) != NULL) {
+    char *controllers;
+    char *token;
     char *base;
 
     /* Skip cgroup number */
     strsep(&p, ":");
-    /* Get controller and base */
-    controller = strsep(&p, ":");
+    /* Get controllers and base */
+    controllers = strsep(&p, ":");
     base = strsep(&p, "\n");
 
-    if (controller != NULL) {
-      if (strstr(controller, "memory") != NULL) {
+    if (controllers == NULL) {
+      continue;
+    }
+
+    while ((token = strsep(&controllers, ",")) != NULL) {
+      if (strcmp(token, "memory") == 0) {
         memory->set_subsystem_path(base);
-      } else if (strstr(controller, "cpuset") != NULL) {
+      } else if (strcmp(token, "cpuset") == 0) {
         cpuset->set_subsystem_path(base);
-      } else if (strstr(controller, "cpu,cpuacct") != NULL || strstr(controller, "cpuacct,cpu") != NULL) {
+      } else if (strcmp(token, "cpu") == 0) {
         cpu->set_subsystem_path(base);
+      } else if (strcmp(token, "cpuacct") == 0) {
         cpuacct->set_subsystem_path(base);
-      } else if (strstr(controller, "cpuacct") != NULL) {
-        cpuacct->set_subsystem_path(base);
-      } else if (strstr(controller, "cpu") != NULL) {
-        cpu->set_subsystem_path(base);
       }
     }
   }
@@ -584,6 +519,17 @@
   int cpu_count, limit_count;
   int result;
 
+  // We use a cache with a timeout to avoid performing expensive
+  // computations in the event this function is called frequently.
+  // [See 8227006].
+  if (!cpu->cache_has_expired()) {
+    if (PrintContainerInfo) {
+      tty->print_cr("OSContainer::active_processor_count (cached): %d", OSContainer::_active_processor_count);
+    }
+
+    return OSContainer::_active_processor_count;
+  }
+
   cpu_count = limit_count = os::Linux::active_processor_count();
   int quota  = cpu_quota();
   int period = cpu_period();
@@ -622,6 +568,11 @@
   if (PrintContainerInfo) {
     tty->print_cr("OSContainer::active_processor_count: %d", result);
   }
+
+  // Update the value and reset the cache timeout
+  OSContainer::_active_processor_count = result;
+  cpu->set_cache_expiry_time(OSCONTAINER_CACHE_TIMEOUT);
+
   return result;
 }
 
--- a/src/os/linux/vm/osContainer_linux.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/os/linux/vm/osContainer_linux.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -31,11 +31,15 @@
 
 #define OSCONTAINER_ERROR (-2)
 
+// 20ms timeout between re-reads of _active_processor_count.
+#define OSCONTAINER_CACHE_TIMEOUT (NANOSECS_PER_SEC/50)
+
 class OSContainer: AllStatic {
 
  private:
   static bool   _is_initialized;
   static bool   _is_containerized;
+  static int    _active_processor_count;
 
  public:
   static void init();
--- a/src/os/linux/vm/os_linux.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/os/linux/vm/os_linux.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1952,6 +1952,9 @@
   #ifndef EM_486
   #define EM_486          6               /* Intel 80486 */
   #endif
+  #ifndef EM_AARCH64
+  #define EM_AARCH64    183               /* ARM AARCH64 */
+  #endif
 
   #ifndef EM_AARCH64
   #define EM_AARCH64	183
@@ -5863,7 +5866,6 @@
 PRAGMA_FORMAT_NONLITERAL_IGNORED
 static jlong slow_thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
   static bool proc_task_unchecked = true;
-  static const char *proc_stat_path = "/proc/%d/stat";
   pid_t  tid = thread->osthread()->thread_id();
   char *s;
   char stat[2048];
@@ -5876,6 +5878,8 @@
   long ldummy;
   FILE *fp;
 
+  snprintf(proc_name, 64, "/proc/%d/stat", tid);
+
   // The /proc/<tid>/stat aggregates per-process usage on
   // new Linux kernels 2.6+ where NPTL is supported.
   // The /proc/self/task/<tid>/stat still has the per-thread usage.
@@ -5887,12 +5891,11 @@
     proc_task_unchecked = false;
     fp = fopen("/proc/self/task", "r");
     if (fp != NULL) {
-      proc_stat_path = "/proc/self/task/%d/stat";
+      snprintf(proc_name, 64, "/proc/self/task/%d/stat", tid);
       fclose(fp);
     }
   }
 
-  sprintf(proc_name, proc_stat_path, tid);
   fp = fopen(proc_name, "r");
   if ( fp == NULL ) return -1;
   statlen = fread(stat, 1, 2047, fp);
--- a/src/os_cpu/bsd_zero/vm/orderAccess_bsd_zero.inline.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/os_cpu/bsd_zero/vm/orderAccess_bsd_zero.inline.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -29,7 +29,7 @@
 #include "runtime/orderAccess.hpp"
 #include "vm_version_zero.hpp"
 
-#ifdef ARM
+#if defined(ARM)   // ----------------------------------------------------
 
 /*
  * ARM Kernel helper for memory barrier.
@@ -40,32 +40,36 @@
 typedef void (__kernel_dmb_t) (void);
 #define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0)
 
-#define FULL_MEM_BARRIER __kernel_dmb()
-#define READ_MEM_BARRIER __kernel_dmb()
+#define READ_MEM_BARRIER  __kernel_dmb()
 #define WRITE_MEM_BARRIER __kernel_dmb()
+#define FULL_MEM_BARRIER  __kernel_dmb()
 
-#else // ARM
-
-#define FULL_MEM_BARRIER __sync_synchronize()
-
-#ifdef PPC
+#elif defined(PPC) // ----------------------------------------------------
 
 #ifdef __NO_LWSYNC__
-#define READ_MEM_BARRIER __asm __volatile ("sync":::"memory")
+#define READ_MEM_BARRIER  __asm __volatile ("sync":::"memory")
 #define WRITE_MEM_BARRIER __asm __volatile ("sync":::"memory")
 #else
-#define READ_MEM_BARRIER __asm __volatile ("lwsync":::"memory")
+#define READ_MEM_BARRIER  __asm __volatile ("lwsync":::"memory")
 #define WRITE_MEM_BARRIER __asm __volatile ("lwsync":::"memory")
 #endif
+#define FULL_MEM_BARRIER  __sync_synchronize()
 
-#else // PPC
+#elif defined(X86) // ----------------------------------------------------
 
-#define READ_MEM_BARRIER __asm __volatile ("":::"memory")
+#define READ_MEM_BARRIER  __asm __volatile ("":::"memory")
 #define WRITE_MEM_BARRIER __asm __volatile ("":::"memory")
+#define FULL_MEM_BARRIER  __sync_synchronize()
 
-#endif // PPC
+#else              // ----------------------------------------------------
+
+// Default to strongest barriers for correctness.
 
-#endif // ARM
+#define READ_MEM_BARRIER  __sync_synchronize()
+#define WRITE_MEM_BARRIER __sync_synchronize()
+#define FULL_MEM_BARRIER  __sync_synchronize()
+
+#endif             // ----------------------------------------------------
 
 
 inline void OrderAccess::loadload()   { acquire(); }
--- a/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -457,7 +457,7 @@
     long long unsigned int oldval,
     long long unsigned int newval) {
     ShouldNotCallThis();
-    return 0;
+    return 0; // silence compiler warnings
   }
 };
 #endif // !_LP64
--- a/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/os_cpu/linux_zero/vm/orderAccess_linux_zero.inline.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -29,7 +29,7 @@
 #include "runtime/orderAccess.hpp"
 #include "vm_version_zero.hpp"
 
-#ifdef ARM
+#if defined(ARM)   // ----------------------------------------------------
 
 /*
  * ARM Kernel helper for memory barrier.
@@ -40,31 +40,35 @@
 typedef void (__kernel_dmb_t) (void);
 #define __kernel_dmb (*(__kernel_dmb_t *) 0xffff0fa0)
 
-#define FULL_MEM_BARRIER __kernel_dmb()
-#define READ_MEM_BARRIER __kernel_dmb()
+#define READ_MEM_BARRIER  __kernel_dmb()
 #define WRITE_MEM_BARRIER __kernel_dmb()
-
-#else // ARM
+#define FULL_MEM_BARRIER  __kernel_dmb()
 
-#define FULL_MEM_BARRIER __sync_synchronize()
+#elif defined(PPC) // ----------------------------------------------------
 
-#ifdef PPC
-
-#define READ_MEM_BARRIER __asm __volatile ("isync":::"memory")
+#define READ_MEM_BARRIER  __asm __volatile ("isync":::"memory")
 #ifdef __NO_LWSYNC__
 #define WRITE_MEM_BARRIER __asm __volatile ("sync":::"memory")
 #else
 #define WRITE_MEM_BARRIER __asm __volatile ("lwsync":::"memory")
 #endif
+#define FULL_MEM_BARRIER  __sync_synchronize()
 
-#else // PPC
+#elif defined(X86) // ----------------------------------------------------
 
-#define READ_MEM_BARRIER __asm __volatile ("":::"memory")
+#define READ_MEM_BARRIER  __asm __volatile ("":::"memory")
 #define WRITE_MEM_BARRIER __asm __volatile ("":::"memory")
+#define FULL_MEM_BARRIER  __sync_synchronize()
 
-#endif // PPC
+#else              // ----------------------------------------------------
+
+// Default to strongest barriers for correctness.
 
-#endif // ARM
+#define READ_MEM_BARRIER  __sync_synchronize()
+#define WRITE_MEM_BARRIER __sync_synchronize()
+#define FULL_MEM_BARRIER  __sync_synchronize()
+
+#endif             // ----------------------------------------------------
 
 
 inline void OrderAccess::loadload()   { acquire(); }
--- a/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/os_cpu/linux_zero/vm/os_linux_zero.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -498,7 +498,7 @@
     long long unsigned int oldval,
     long long unsigned int newval) {
     ShouldNotCallThis();
-    return 0;
+    return 0; // silence compiler warnings
   }
 };
 #endif // !_LP64
--- a/src/share/vm/classfile/classFileParser.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/classfile/classFileParser.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -3796,6 +3796,16 @@
   info->has_nonstatic_fields = has_nonstatic_fields;
 }
 
+static bool relax_format_check_for(ClassLoaderData* loader_data) {
+  bool trusted = (loader_data->is_the_null_class_loader_data() ||
+                  SystemDictionary::is_ext_class_loader(loader_data->class_loader()));
+  bool need_verify =
+    // verifyAll
+    (BytecodeVerificationLocal && BytecodeVerificationRemote) ||
+    // verifyRemote
+    (!BytecodeVerificationLocal && BytecodeVerificationRemote && !trusted);
+  return !need_verify;
+}
 
 instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
                                                     ClassLoaderData* loader_data,
@@ -3815,7 +3825,13 @@
   Handle class_loader(THREAD, loader_data->class_loader());
   bool has_default_methods = false;
   bool declares_default_methods = false;
-  ResourceMark rm(THREAD);
+  // JDK-8252904:
+  // The stream (resource) attached to the instance klass may
+  // be reallocated by this method. When JFR is included the
+  // stream may need to survive beyond the end of the call. So,
+  // the caller is expected to declare the ResourceMark that
+  // determines the lifetime of resources allocated under this
+  // call.
 
   ClassFileStream* cfs = stream();
   // Timing
@@ -3942,7 +3958,7 @@
 
   // Check if verification needs to be relaxed for this class file
   // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376)
-  _relax_verify = Verifier::relax_verify_for(class_loader());
+  _relax_verify = relax_format_check_for(_loader_data);
 
   // Constant pool
   constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle));
--- a/src/share/vm/classfile/classLoader.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/classfile/classLoader.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1183,6 +1183,11 @@
     ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
     Handle protection_domain;
     TempNewSymbol parsed_name = NULL;
+    // Callers are expected to declare a ResourceMark to determine
+    // the lifetime of any updated (resource) allocated under
+    // this call to parseClassFile
+    // We do not declare another ResourceMark here, reusing the one declared
+    // at the start of the method
     instanceKlassHandle result = parser.parseClassFile(h_name,
                                                        loader_data,
                                                        protection_domain,
@@ -1634,12 +1639,13 @@
 }
 
 void ClassLoader::compile_the_world_in(char* name, Handle loader, TRAPS) {
-  int len = (int)strlen(name);
+  size_t len = strlen(name);
   if (len > 6 && strcmp(".class", name + len - 6) == 0) {
     // We have a .class file
     char buffer[2048];
-    strncpy(buffer, name, len - 6);
-    buffer[len-6] = 0;
+    if (len-6 >= sizeof(buffer)) return;
+    strncpy(buffer, name, sizeof(buffer));
+    buffer[len-6] = 0; // Truncate ".class" suffix.
     // If the file has a period after removing .class, it's not really a
     // valid class file.  The class loader will check everything else.
     if (strchr(buffer, '.') == NULL) {
--- a/src/share/vm/classfile/systemDictionary.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/classfile/systemDictionary.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1026,14 +1026,21 @@
   //
   // Note: "name" is updated.
 
-  instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,
-                                                             loader_data,
-                                                             protection_domain,
-                                                             host_klass,
-                                                             cp_patches,
-                                                             parsed_name,
-                                                             true,
-                                                             THREAD);
+  instanceKlassHandle k;
+  {
+  // Callers are expected to declare a ResourceMark to determine
+  // the lifetime of any updated (resource) allocated under
+  // this call to parseClassFile
+  ResourceMark rm(THREAD);
+  k = ClassFileParser(st).parseClassFile(class_name,
+                                         loader_data,
+                                         protection_domain,
+                                         host_klass,
+                                         cp_patches,
+                                         parsed_name,
+                                         true,
+                                         THREAD);
+  }
 
 
   if (host_klass.not_null() && k.not_null()) {
@@ -1120,6 +1127,10 @@
   //
   // Note: "name" is updated.
 
+  // Callers are expected to declare a ResourceMark to determine
+  // the lifetime of any updated (resource) allocated under
+  // this call to parseClassFile
+  ResourceMark rm(THREAD);
   ClassFileParser parser(st);
   instanceKlassHandle k = parser.parseClassFile(class_name,
                                                 loader_data,
--- a/src/share/vm/classfile/verifier.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/classfile/verifier.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -101,7 +101,7 @@
     BytecodeVerificationLocal : BytecodeVerificationRemote;
 }
 
-bool Verifier::relax_verify_for(oop loader) {
+bool Verifier::relax_access_for(oop loader) {
   bool trusted = java_lang_ClassLoader::is_trusted_loader(loader);
   bool need_verify =
     // verifyAll
--- a/src/share/vm/classfile/verifier.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/classfile/verifier.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,8 +57,8 @@
   // -Xverify:all/none override this value
   static bool should_verify_for(oop class_loader, bool should_verify_class);
 
-  // Relax certain verifier checks to enable some broken 1.1 apps to run on 1.2.
-  static bool relax_verify_for(oop class_loader);
+  // Relax certain access checks to enable some broken 1.1 apps to run on 1.2.
+  static bool relax_access_for(oop class_loader);
 
  private:
   static bool is_eligible_for_verification(instanceKlassHandle klass, bool should_verify_class);
--- a/src/share/vm/compiler/compileBroker.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/compiler/compileBroker.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -2042,6 +2042,15 @@
         event.set_failureMessage(failure_reason);
         event.commit();
       }
+
+      if (AbortVMOnCompilationFailure) {
+        if (compilable == ciEnv::MethodCompilable_not_at_tier) {
+          fatal(err_msg("Not compilable at tier %d: %s", task_level, failure_reason));
+        }
+        if (compilable == ciEnv::MethodCompilable_never) {
+          fatal(err_msg("Never compilable: %s", failure_reason));
+        }
+      }
     } else {
       task->mark_success();
       task->set_num_inlined_bytecodes(ci_env.num_inlined_bytecodes());
--- a/src/share/vm/compiler/compilerOracle.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/compiler/compilerOracle.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -503,25 +503,8 @@
         "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
 
 #define RANGE0 "[*" RANGEBASE "]"
-#define RANGEDOT "[*" RANGEBASE ".]"
 #define RANGESLASH "[*" RANGEBASE "/]"
 
-
-// Accept several syntaxes for these patterns
-//  original syntax
-//   cmd  java.lang.String foo
-//  PrintCompilation syntax
-//   cmd  java.lang.String::foo
-//  VM syntax
-//   cmd  java/lang/String[. ]foo
-//
-
-static const char* patterns[] = {
-  "%*[ \t]%255" RANGEDOT    " "     "%255"  RANGE0 "%n",
-  "%*[ \t]%255" RANGEDOT   "::"     "%255"  RANGE0 "%n",
-  "%*[ \t]%255" RANGESLASH "%*[ .]" "%255"  RANGE0 "%n",
-};
-
 static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) {
   int match = MethodMatcher::Exact;
   while (name[0] == '*') {
@@ -550,12 +533,10 @@
                       int* bytes_read, const char*& error_msg) {
   *bytes_read = 0;
   error_msg = NULL;
-  for (uint i = 0; i < ARRAY_SIZE(patterns); i++) {
-    if (2 == sscanf(line, patterns[i], class_name, method_name, bytes_read)) {
-      *c_mode = check_mode(class_name, error_msg);
-      *m_mode = check_mode(method_name, error_msg);
-      return *c_mode != MethodMatcher::Unknown && *m_mode != MethodMatcher::Unknown;
-    }
+  if (2 == sscanf(line, "%*[ \t]%255" RANGESLASH "%*[ ]" "%255"  RANGE0 "%n", class_name, method_name, bytes_read)) {
+    *c_mode = check_mode(class_name, error_msg);
+    *m_mode = check_mode(method_name, error_msg);
+    return *c_mode != MethodMatcher::Unknown && *m_mode != MethodMatcher::Unknown;
   }
   return false;
 }
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -998,18 +998,13 @@
       // and the klass read.
       OrderAccess::loadload();
 
-      // must read from what 'p' points to in each loop.
-      Klass* k = ((volatile oopDesc*)p)->klass_or_null();
+      // Ensure klass read before size.
+      Klass* k = oop(p)->klass_or_null_acquire();
       if (k != NULL) {
         assert(k->is_klass(), "Should really be klass oop.");
         oop o = (oop)p;
         assert(o->is_oop(true /* ignore mark word */), "Should be an oop.");
 
-        // Bugfix for systems with weak memory model (PPC64/IA64).
-        // The object o may be an array. Acquire to make sure that the array
-        // size (third word) is consistent.
-        OrderAccess::acquire();
-
         size_t res = o->size_given_klass(k);
         res = adjustObjectSize(res);
         assert(res != 0, "Block size should not be 0");
@@ -1057,21 +1052,13 @@
       // and the klass read.
       OrderAccess::loadload();
 
-      // must read from what 'p' points to in each loop.
-      Klass* k = ((volatile oopDesc*)p)->klass_or_null();
-      // We trust the size of any object that has a non-NULL
-      // klass and (for those in the perm gen) is parsable
-      // -- irrespective of its conc_safe-ty.
+      // Ensure klass read before size.
+      Klass* k = oop(p)->klass_or_null_acquire();
       if (k != NULL) {
         assert(k->is_klass(), "Should really be klass oop.");
         oop o = (oop)p;
         assert(o->is_oop(), "Should be an oop");
 
-        // Bugfix for systems with weak memory model (PPC64/IA64).
-        // The object o may be an array. Acquire to make sure that the array
-        // size (third word) is consistent.
-        OrderAccess::acquire();
-
         size_t res = o->size_given_klass(k);
         res = adjustObjectSize(res);
         assert(res != 0, "Block size should not be 0");
@@ -1124,7 +1111,7 @@
   // and the klass read.
   OrderAccess::loadload();
 
-  Klass* k = oop(p)->klass_or_null();
+  Klass* k = oop(p)->klass_or_null_acquire();
   if (k != NULL) {
     // Ignore mark word because it may have been used to
     // chain together promoted objects (the last one
--- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -6740,7 +6740,7 @@
 HeapWord* CMSCollector::next_card_start_after_block(HeapWord* addr) const {
   size_t sz = 0;
   oop p = (oop)addr;
-  if (p->klass_or_null() != NULL) {
+  if (p->klass_or_null_acquire() != NULL) {
     sz = CompactibleFreeListSpace::adjustObjectSize(p->size());
   } else {
     sz = block_size_using_printezis_bits(addr);
@@ -7198,7 +7198,7 @@
   }
   if (_bitMap->isMarked(addr)) {
     // it's marked; is it potentially uninitialized?
-    if (p->klass_or_null() != NULL) {
+    if (p->klass_or_null_acquire() != NULL) {
         // an initialized object; ignore mark word in verification below
         // since we are running concurrent with mutators
         assert(p->is_oop(true), "should be an oop");
@@ -7239,7 +7239,7 @@
     }
   } else {
     // Either a not yet marked object or an uninitialized object
-    if (p->klass_or_null() == NULL) {
+    if (p->klass_or_null_acquire() == NULL) {
       // An uninitialized object, skip to the next card, since
       // we may not be able to read its P-bits yet.
       assert(size == 0, "Initial value");
@@ -7450,7 +7450,7 @@
     assert(_skipBits == 0, "tautology");
     _skipBits = 2;  // skip next two marked bits ("Printezis-marks")
     oop p = oop(addr);
-    if (p->klass_or_null() == NULL) {
+    if (p->klass_or_null_acquire() == NULL) {
       DEBUG_ONLY(if (!_verifying) {)
         // We re-dirty the cards on which this object lies and increase
         // the _threshold so that we'll come back to scan this object
@@ -7470,7 +7470,7 @@
           if (_threshold < end_card_addr) {
             _threshold = end_card_addr;
           }
-          if (p->klass_or_null() != NULL) {
+          if (p->klass_or_null_acquire() != NULL) {
             // Redirty the range of cards...
             _mut->mark_range(redirty_range);
           } // ...else the setting of klass will dirty the card anyway.
@@ -7621,7 +7621,7 @@
     assert(_skip_bits == 0, "tautology");
     _skip_bits = 2;  // skip next two marked bits ("Printezis-marks")
     oop p = oop(addr);
-    if (p->klass_or_null() == NULL) {
+    if (p->klass_or_null_acquire() == NULL) {
       // in the case of Clean-on-Enter optimization, redirty card
       // and avoid clearing card by increasing  the threshold.
       return true;
@@ -8608,7 +8608,7 @@
            "alignment problem");
 
 #ifdef ASSERT
-      if (oop(addr)->klass_or_null() != NULL) {
+      if (oop(addr)->klass_or_null_acquire() != NULL) {
         // Ignore mark word because we are running concurrent with mutators
         assert(oop(addr)->is_oop(true), "live block should be an oop");
         assert(size ==
@@ -8619,7 +8619,7 @@
 
   } else {
     // This should be an initialized object that's alive.
-    assert(oop(addr)->klass_or_null() != NULL,
+    assert(oop(addr)->klass_or_null_acquire() != NULL,
            "Should be an initialized object");
     // Ignore mark word because we are running concurrent with mutators
     assert(oop(addr)->is_oop(true), "live block should be an oop");
--- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1130,11 +1130,11 @@
     _rs_length_diff_seq->add((double) rs_length_diff);
 
     size_t freed_bytes = _heap_used_bytes_before_gc - cur_used_bytes;
-    size_t copied_bytes = _collection_set_bytes_used_before - freed_bytes;
-    double cost_per_byte_ms = 0.0;
 
-    if (copied_bytes > 0) {
-      cost_per_byte_ms = phase_times()->average_time_ms(G1GCPhaseTimes::ObjCopy) / (double) copied_bytes;
+    if (_collection_set_bytes_used_before > freed_bytes) {
+      size_t copied_bytes = _collection_set_bytes_used_before - freed_bytes;
+      double average_copy_time = phase_times()->average_time_ms(G1GCPhaseTimes::ObjCopy);
+      double cost_per_byte_ms = average_copy_time / (double) copied_bytes;
       if (_in_marking_window) {
         _cost_per_byte_ms_during_cm_seq->add(cost_per_byte_ms);
       } else {
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -568,20 +568,18 @@
   // fail arbitrarily). We tell the iteration code to perform this
   // filtering when it has been determined that there has been an actual
   // allocation in this region and making it safe to check the young type.
-  bool filter_young = true;
 
-  HeapWord* stop_point =
+  bool card_processed =
     r->oops_on_card_seq_iterate_careful(dirtyRegion,
                                         &filter_then_update_rs_oop_cl,
-                                        filter_young,
                                         card_ptr);
 
-  // If stop_point is non-null, then we encountered an unallocated region
-  // (perhaps the unfilled portion of a TLAB.)  For now, we'll dirty the
-  // card and re-enqueue: if we put off the card until a GC pause, then the
-  // unallocated portion will be filled in.  Alternatively, we might try
-  // the full complexity of the technique used in "regular" precleaning.
-  if (stop_point != NULL) {
+  // If unable to process the card then we encountered an unparsable
+  // part of the heap (e.g. a partially allocated object).  Redirty
+  // and re-enqueue: if we put off the card until a GC pause, then the
+  // allocation will have completed.
+  if (!card_processed) {
+    assert(!_g1->is_gc_active(), "Unparsable heap during GC");
     // The card might have gotten re-dirtied and re-enqueued while we
     // worked.  (In fact, it's pretty likely.)
     if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
--- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -407,19 +407,10 @@
   return NULL;
 }
 
-HeapWord*
-HeapRegion::
-oops_on_card_seq_iterate_careful(MemRegion mr,
-                                 FilterOutOfRegionClosure* cl,
-                                 bool filter_young,
-                                 jbyte* card_ptr) {
-  // Currently, we should only have to clean the card if filter_young
-  // is true and vice versa.
-  if (filter_young) {
-    assert(card_ptr != NULL, "pre-condition");
-  } else {
-    assert(card_ptr == NULL, "pre-condition");
-  }
+bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr,
+                                                  FilterOutOfRegionClosure* cl,
+                                                  jbyte* card_ptr) {
+  assert(card_ptr != NULL, "pre-condition");
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   // If we're within a stop-world GC, then we might look at a card in a
@@ -430,7 +421,9 @@
   } else {
     mr = mr.intersection(used_region());
   }
-  if (mr.is_empty()) return NULL;
+  if (mr.is_empty()) {
+    return true;
+  }
   // Otherwise, find the obj that extends onto mr.start().
 
   // The intersection of the incoming mr (for the card) and the
@@ -439,27 +432,21 @@
   // G1CollectedHeap.cpp that allocates a new region sets the
   // is_young tag on the region before allocating. Thus we
   // safely know if this region is young.
-  if (is_young() && filter_young) {
-    return NULL;
+  if (is_young()) {
+    return true;
   }
 
-  assert(!is_young(), "check value of filter_young");
-
   // We can only clean the card here, after we make the decision that
-  // the card is not young. And we only clean the card if we have been
-  // asked to (i.e., card_ptr != NULL).
-  if (card_ptr != NULL) {
-    *card_ptr = CardTableModRefBS::clean_card_val();
-    // We must complete this write before we do any of the reads below.
-    OrderAccess::storeload();
-  }
+  // the card is not young.
+  *card_ptr = CardTableModRefBS::clean_card_val();
+  // We must complete this write before we do any of the reads below.
+  OrderAccess::storeload();
 
   // Cache the boundaries of the memory region in some const locals
   HeapWord* const start = mr.start();
   HeapWord* const end = mr.end();
 
-  // We used to use "block_start_careful" here.  But we're actually happy
-  // to update the BOT while we do this...
+  // Update BOT as needed while finding start of (potential) object.
   HeapWord* cur = block_start(start);
   assert(cur <= start, "Postcondition");
 
@@ -471,7 +458,9 @@
     obj = oop(cur);
     if (obj->klass_or_null() == NULL) {
       // Ran into an unparseable point.
-      return cur;
+      assert(!g1h->is_gc_active(),
+             err_msg("Unparsable heap during GC at " PTR_FORMAT, p2i(cur)));
+      return false;
     }
     // Otherwise...
     next = cur + block_size(cur);
@@ -488,7 +477,9 @@
     assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant");
     if (obj->klass_or_null() == NULL) {
       // Ran into an unparseable point.
-      return cur;
+      assert(!g1h->is_gc_active(),
+             err_msg("Unparsable heap during GC at " PTR_FORMAT, p2i(cur)));
+      return false;
     }
 
     // Advance the current pointer. "obj" still points to the object to iterate.
@@ -507,7 +498,7 @@
     }
   } while (cur < end);
 
-  return NULL;
+  return true;
 }
 
 // Code roots support
--- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -718,16 +718,17 @@
   HeapWord*
   object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl);
 
-  // filter_young: if true and the region is a young region then we
-  // skip the iteration.
-  // card_ptr: if not NULL, and we decide that the card is not young
-  // and we iterate over it, we'll clean the card before we start the
-  // iteration.
-  HeapWord*
-  oops_on_card_seq_iterate_careful(MemRegion mr,
-                                   FilterOutOfRegionClosure* cl,
-                                   bool filter_young,
-                                   jbyte* card_ptr);
+  // Iterate over the card in the card designated by card_ptr,
+  // applying cl to all references in the region.
+  // mr: the memory region covered by the card.
+  // card_ptr: if we decide that the card is not young and we iterate
+  // over it, we'll clean the card before we start the iteration.
+  // Returns true if card was successfully processed, false if an
+  // unparsable part of the heap was encountered, which should only
+  // happen when invoked concurrently with the mutator.
+  bool oops_on_card_seq_iterate_careful(MemRegion mr,
+                                        FilterOutOfRegionClosure* cl,
+                                        jbyte* card_ptr);
 
   size_t recorded_rs_length() const        { return _recorded_rs_length; }
   double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; }
--- a/src/share/vm/gc_interface/collectedHeap.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/gc_interface/collectedHeap.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -286,8 +286,6 @@
     return NULL;
   }
 
-  AllocTracer::send_allocation_in_new_tlab_event(klass, obj, new_tlab_size * HeapWordSize, size * HeapWordSize, Thread::current());
-
   if (ZeroTLAB) {
     // ..and clear it.
     Copy::zero_to_words(obj, new_tlab_size);
--- a/src/share/vm/gc_interface/collectedHeap.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/gc_interface/collectedHeap.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -320,9 +320,6 @@
   inline static oop array_allocate(KlassHandle klass, int size, int length, TRAPS);
   inline static oop array_allocate_nozero(KlassHandle klass, int size, int length, TRAPS);
 
-  inline static void post_allocation_install_obj_klass(KlassHandle klass,
-                                                       oop obj);
-
   // Raw memory allocation facilities
   // The obj and array allocate methods are covers for these methods.
   // mem_allocate() should never be
--- a/src/share/vm/gc_interface/collectedHeap.inline.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/gc_interface/collectedHeap.inline.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,14 +39,22 @@
 // Inline allocation implementations.
 
 void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
-                                                 HeapWord* obj) {
-  post_allocation_setup_no_klass_install(klass, obj);
-  post_allocation_install_obj_klass(klass, oop(obj));
+                                                 HeapWord* obj_ptr) {
+  post_allocation_setup_no_klass_install(klass, obj_ptr);
+  oop obj = (oop)obj_ptr;
+#if ! INCLUDE_ALL_GCS
+  obj->set_klass(klass());
+#else
+  // Need a release store to ensure array/class length, mark word, and
+  // object zeroing are visible before setting the klass non-NULL, for
+  // concurrent collectors.
+  obj->release_set_klass(klass());
+#endif
 }
 
 void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
-                                                           HeapWord* objPtr) {
-  oop obj = (oop)objPtr;
+                                                           HeapWord* obj_ptr) {
+  oop obj = (oop)obj_ptr;
 
   assert(obj != NULL, "NULL object pointer");
   if (UseBiasedLocking && (klass() != NULL)) {
@@ -57,20 +65,22 @@
   }
 }
 
-void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
-                                                   oop obj) {
-  // These asserts are kind of complicated because of klassKlass
-  // and the beginning of the world.
-  assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
-  assert(klass() == NULL || klass()->is_klass(), "not a klass");
-  assert(obj != NULL, "NULL object pointer");
-  obj->set_klass(klass());
-  assert(!Universe::is_fully_initialized() || obj->klass() != NULL,
-         "missing klass");
+inline void send_jfr_allocation_event(KlassHandle klass, HeapWord* obj, size_t size) {
+  Thread* t = Thread::current();
+  ThreadLocalAllocBuffer& tlab = t->tlab();
+  if (obj == tlab.start()) {
+    // allocate in new TLAB
+    size_t new_tlab_size = tlab.hard_size_bytes();
+    AllocTracer::send_allocation_in_new_tlab_event(klass, obj, new_tlab_size, size * HeapWordSize, t);
+  } else if (!tlab.in_used(obj)) {
+    // allocate outside TLAB
+    AllocTracer::send_allocation_outside_tlab_event(klass, obj, size * HeapWordSize, t);
+  }
 }
 
-// Support for jvmti and dtrace
+// Support for jvmti, dtrace and jfr
 inline void post_allocation_notify(KlassHandle klass, oop obj, int size) {
+  send_jfr_allocation_event(klass, (HeapWord*)obj, size);
   // support low memory notifications (no-op if not enabled)
   LowMemoryDetector::detect_low_memory_for_collected_pools();
 
@@ -86,25 +96,26 @@
 }
 
 void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
-                                              HeapWord* obj,
+                                              HeapWord* obj_ptr,
                                               int size) {
-  post_allocation_setup_common(klass, obj);
+  post_allocation_setup_common(klass, obj_ptr);
+  oop obj = (oop)obj_ptr;
   assert(Universe::is_bootstrapping() ||
-         !((oop)obj)->is_array(), "must not be an array");
+         !obj->is_array(), "must not be an array");
   // notify jvmti and dtrace
-  post_allocation_notify(klass, (oop)obj, size);
+  post_allocation_notify(klass, obj, size);
 }
 
 void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
-                                                HeapWord* obj,
+                                                HeapWord* obj_ptr,
                                                 int length) {
-  // Set array length before setting the _klass field
-  // in post_allocation_setup_common() because the klass field
-  // indicates that the object is parsable by concurrent GC.
+  // Set array length before setting the _klass field because a
+  // non-NULL klass field indicates that the object is parsable by
+  // concurrent GC.
   assert(length >= 0, "length should be non-negative");
-  ((arrayOop)obj)->set_length(length);
-  post_allocation_setup_common(klass, obj);
-  oop new_obj = (oop)obj;
+  ((arrayOop)obj_ptr)->set_length(length);
+  post_allocation_setup_common(klass, obj_ptr);
+  oop new_obj = (oop)obj_ptr;
   assert(new_obj->is_array(), "must be an array");
   // notify jvmti and dtrace (must be after length is set for dtrace)
   post_allocation_notify(klass, new_obj, new_obj->size());
@@ -140,8 +151,6 @@
            "Unexpected exception, will result in uninitialized storage");
     THREAD->incr_allocated_bytes(size * HeapWordSize);
 
-    AllocTracer::send_allocation_outside_tlab_event(klass, result, size * HeapWordSize, Thread::current());
-
     return result;
   }
 
--- a/src/share/vm/jfr/periodic/sampling/jfrThreadSampler.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/jfr/periodic/sampling/jfrThreadSampler.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -285,13 +285,13 @@
 
 void JfrThreadSampleClosure::commit_events(JfrSampleType type) {
   if (JAVA_SAMPLE == type) {
-    assert(_added_java <= MAX_NR_OF_JAVA_SAMPLES, "invariant");
+    assert(_added_java > 0 && _added_java <= MAX_NR_OF_JAVA_SAMPLES, "invariant");
     for (uint i = 0; i < _added_java; ++i) {
       _events[i].commit();
     }
   } else {
     assert(NATIVE_SAMPLE == type, "invariant");
-    assert(_added_native <= MAX_NR_OF_NATIVE_SAMPLES, "invariant");
+    assert(_added_native > 0 && _added_native <= MAX_NR_OF_NATIVE_SAMPLES, "invariant");
     for (uint i = 0; i < _added_native; ++i) {
       _events_native[i].commit();
     }
@@ -537,7 +537,7 @@
   JfrThreadSampleClosure sample_task(samples, samples_native);
 
   const uint sample_limit = JAVA_SAMPLE == type ? MAX_NR_OF_JAVA_SAMPLES : MAX_NR_OF_NATIVE_SAMPLES;
-  uint num_sample_attempts = 0;
+  uint num_samples = 0;
   JavaThread* start = NULL;
 
   {
@@ -555,7 +555,7 @@
       JavaThread* current = Threads::includes(*last_thread) ? *last_thread : NULL;
       JavaThread* start = NULL;
 
-      while (num_sample_attempts < sample_limit) {
+      while (num_samples < sample_limit) {
         current = next_thread(threads_list, index, start, current);
         if (current == NULL) {
           break;
@@ -566,8 +566,9 @@
         if (current->is_Compiler_thread()) {
           continue;
         }
-        sample_task.do_sample_thread(current, _frames, _max_frames, type);
-        num_sample_attempts++;
+        if (sample_task.do_sample_thread(current, _frames, _max_frames, type)) {
+          num_samples++;
+        }
       }
       *last_thread = current;  // remember the thread we last attempted to sample
       FREE_C_HEAP_ARRAY(JavaThread *, threads_list, mtInternal);
@@ -576,7 +577,7 @@
     if (LogJFR && Verbose) tty->print_cr("JFR thread sampling done in %3.7f secs with %d java %d native samples",
                    sample_time.seconds(), sample_task.java_entries(), sample_task.native_entries());
   }
-  if (num_sample_attempts > 0) {
+  if (num_samples > 0) {
     sample_task.commit_events(type);
   }
 }
--- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSet.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -263,13 +263,17 @@
   assert(k != NULL, "invariant");
   const InstanceKlass* const ik = (const InstanceKlass*)k;
   if (ik->is_anonymous()) {
-    CStringEntryPtr entry =
-      artifacts->map_cstring(JfrSymbolId::anonymous_klass_name_hash_code(ik));
+    CStringEntryPtr entry = NULL;
+    {
+      ResourceMark rm;
+      uintptr_t hashcode = JfrSymbolId::anonymous_klass_name_hash_code(ik);
+      entry = artifacts->map_cstring(JfrSymbolId::get_anonymous_klass_chars(ik, hashcode), hashcode);
+    }
     assert(entry != NULL, "invariant");
     return write__artifact__cstring__entry__(writer, entry);
   }
 
-  SymbolEntryPtr entry = artifacts->map_symbol(JfrSymbolId::regular_klass_name_hash_code(ik));
+  SymbolEntryPtr entry = artifacts->map_symbol(ik->name());
   return write__artifact__symbol__entry__(writer, entry);
 }
 
@@ -326,8 +330,12 @@
   assert(_predicate(klass), "invariant");
   const InstanceKlass* const ik = (const InstanceKlass*)klass;
   if (ik->is_anonymous()) {
-    CStringEntryPtr entry =
-      this->_artifacts->map_cstring(JfrSymbolId::anonymous_klass_name_hash_code(ik));
+    CStringEntryPtr entry = NULL;
+    {
+      ResourceMark rm;
+      uintptr_t hashcode = JfrSymbolId::anonymous_klass_name_hash_code(ik);
+      entry = _artifacts->map_cstring(JfrSymbolId::get_anonymous_klass_chars(ik, hashcode), hashcode);
+    }
     assert(entry != NULL, "invariant");
     return _unique_predicate(entry->id()) ? write__artifact__cstring__entry__(this->_writer, entry) : 0;
   }
@@ -345,7 +353,7 @@
   const Klass* class_loader_klass = cld->class_loader() != NULL ? cld->class_loader()->klass() : NULL;
   if (class_loader_klass == NULL) {
     // (primordial) boot class loader
-    CStringEntryPtr entry = this->_artifacts->map_cstring(0);
+    CStringEntryPtr entry = this->_artifacts->map_cstring(BOOTSTRAP_LOADER_NAME, 0);
     assert(entry != NULL, "invariant");
     assert(strncmp(entry->literal(),
       BOOTSTRAP_LOADER_NAME,
--- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -75,10 +75,7 @@
   const char* const anonymous_symbol =
     create_anonymous_klass_symbol((const InstanceKlass*)k, anonymous_symbol_hash_code);
 
-  if (anonymous_symbol == NULL) {
-    return 0;
-  }
-
+  assert(anonymous_symbol != NULL, "create_anonymous_klass_symbol fail");
   assert(anonymous_symbol_hash_code != 0, "invariant");
   traceid symbol_id = mark(anonymous_symbol, anonymous_symbol_hash_code);
   assert(mark(anonymous_symbol, anonymous_symbol_hash_code) == symbol_id, "invariant");
@@ -89,12 +86,8 @@
   return _sym_table->lookup_only(symbol, (uintptr_t)const_cast<Symbol*>(symbol)->identity_hash());
 }
 
-const JfrSymbolId::SymbolEntry* JfrSymbolId::map_symbol(uintptr_t hash) const {
-  return _sym_table->lookup_only(NULL, hash);
-}
-
-const JfrSymbolId::CStringEntry* JfrSymbolId::map_cstring(uintptr_t hash) const {
-  return _cstring_table->lookup_only(NULL, hash);
+const JfrSymbolId::CStringEntry* JfrSymbolId::map_cstring(const char* const str, uintptr_t hash) const {
+  return _cstring_table->lookup_only(str, hash);
 }
 
 void JfrSymbolId::assign_id(SymbolEntry* entry) {
@@ -104,10 +97,10 @@
 }
 
 bool JfrSymbolId::equals(const Symbol* query, uintptr_t hash, const SymbolEntry* entry) {
-  // query might be NULL
   assert(entry != NULL, "invariant");
   assert(entry->hash() == hash, "invariant");
-  return true;
+  assert(query != NULL, "invariant");
+  return query == entry->literal();
 }
 
 void JfrSymbolId::assign_id(CStringEntry* entry) {
@@ -116,11 +109,18 @@
   entry->set_id(++_symbol_id_counter);
 }
 
+static bool string_compare(const char* query, const char* candidate) {
+  assert(query != NULL, "invariant");
+  assert(candidate != NULL, "invariant");
+  const size_t length = strlen(query);
+  return strncmp(query, candidate, length) == 0;
+}
+
 bool JfrSymbolId::equals(const char* query, uintptr_t hash, const CStringEntry* entry) {
-  // query might be NULL
   assert(entry != NULL, "invariant");
   assert(entry->hash() == hash, "invariant");
-  return true;
+  assert(query != NULL, "invariant");
+  return string_compare(query, entry->literal());
 }
 
 traceid JfrSymbolId::mark(const Klass* k) {
@@ -182,6 +182,22 @@
   return (uintptr_t)mirror->identity_hash();
 }
 
+const char* JfrSymbolId::get_anonymous_klass_chars(const InstanceKlass* ik, uintptr_t hashcode) {
+  assert(ik != NULL, "invariant");
+  assert(ik->is_anonymous(), "invariant");
+  assert(0 != hashcode, "invariant");
+  char hash_buf[40];
+  sprintf(hash_buf, "/" UINTX_FORMAT, hashcode);
+  const size_t hash_len = strlen(hash_buf);
+  const size_t result_len = ik->name()->utf8_length();
+  char* anonymous_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
+  ik->name()->as_klass_external_name(anonymous_symbol, (int)result_len + 1);
+  assert(strlen(anonymous_symbol) == result_len, "invariant");
+  strcpy(anonymous_symbol + result_len, hash_buf);
+  assert(strlen(anonymous_symbol) == result_len + hash_len, "invariant");
+  return anonymous_symbol;
+}
+
 const char* JfrSymbolId::create_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t& hashcode) {
   assert(ik != NULL, "invariant");
   assert(ik->is_anonymous(), "invariant");
@@ -189,17 +205,8 @@
   char* anonymous_symbol = NULL;
   const oop mirror = ik->java_mirror();
   assert(mirror != NULL, "invariant");
-  char hash_buf[40];
   hashcode = anonymous_klass_name_hash_code(ik);
-  sprintf(hash_buf, "/" UINTX_FORMAT, hashcode);
-  const size_t hash_len = strlen(hash_buf);
-  const size_t result_len = ik->name()->utf8_length();
-  anonymous_symbol = NEW_RESOURCE_ARRAY(char, result_len + hash_len + 1);
-  ik->name()->as_klass_external_name(anonymous_symbol, (int)result_len + 1);
-  assert(strlen(anonymous_symbol) == result_len, "invariant");
-  strcpy(anonymous_symbol + result_len, hash_buf);
-  assert(strlen(anonymous_symbol) == result_len + hash_len, "invariant");
-  return anonymous_symbol;
+  return get_anonymous_klass_chars(ik, hashcode);
 }
 
 uintptr_t JfrSymbolId::regular_klass_name_hash_code(const Klass* k) {
@@ -264,12 +271,8 @@
   return _symbol_id->map_symbol(symbol);
 }
 
-const JfrSymbolId::SymbolEntry* JfrArtifactSet::map_symbol(uintptr_t hash) const {
-  return _symbol_id->map_symbol(hash);
-}
-
-const JfrSymbolId::CStringEntry* JfrArtifactSet::map_cstring(uintptr_t hash) const {
-  return _symbol_id->map_cstring(hash);
+const JfrSymbolId::CStringEntry* JfrArtifactSet::map_cstring(const char* const str, uintptr_t hash) const {
+  return _symbol_id->map_cstring(str, hash);
 }
 
 bool JfrArtifactSet::has_klass_entries() const {
--- a/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/jfr/recorder/checkpoint/types/jfrTypeSetUtils.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -243,6 +243,7 @@
 
  public:
   static bool is_anonymous_klass(const Klass* k);
+  static const char* get_anonymous_klass_chars(const InstanceKlass* ik, uintptr_t hashcode);
   static const char* create_anonymous_klass_symbol(const InstanceKlass* ik, uintptr_t& hashcode);
   static uintptr_t anonymous_klass_name_hash_code(const InstanceKlass* ik);
   static uintptr_t regular_klass_name_hash_code(const Klass* k);
@@ -266,31 +267,7 @@
   }
 
   const SymbolEntry* map_symbol(const Symbol* symbol) const;
-  const SymbolEntry* map_symbol(uintptr_t hash) const;
-  const CStringEntry* map_cstring(uintptr_t hash) const;
-
-  template <typename T>
-  void symbol(T& functor, const Klass* k) {
-    if (is_anonymous_klass(k)) {
-      return;
-    }
-    functor(map_symbol(regular_klass_name_hash_code(k)));
-  }
-
-  template <typename T>
-  void symbol(T& functor, const Method* method) {
-    assert(method != NULL, "invariant");
-    functor(map_symbol((uintptr_t)method->name()->identity_hash()));
-    functor(map_symbol((uintptr_t)method->signature()->identity_hash()));
-  }
-
-  template <typename T>
-  void cstring(T& functor, const Klass* k) {
-    if (!is_anonymous_klass(k)) {
-      return;
-    }
-    functor(map_cstring(anonymous_klass_name_hash_code((const InstanceKlass*)k)));
-  }
+  const CStringEntry* map_cstring(const char* const str, uintptr_t hash) const;
 
   template <typename T>
   void iterate_symbols(T& functor) {
@@ -344,8 +321,7 @@
   traceid markPackage(const char* const name, uintptr_t hash);
 
   const JfrSymbolId::SymbolEntry* map_symbol(const Symbol* symbol) const;
-  const JfrSymbolId::SymbolEntry* map_symbol(uintptr_t hash) const;
-  const JfrSymbolId::CStringEntry* map_cstring(uintptr_t hash) const;
+  const JfrSymbolId::CStringEntry* map_cstring(const char* const str, uintptr_t hash) const;
 
   bool has_klass_entries() const;
   int entries() const;
--- a/src/share/vm/jfr/recorder/repository/jfrChunkWriter.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/jfr/recorder/repository/jfrChunkWriter.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -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
@@ -46,13 +46,9 @@
   return _chunkstate != NULL;
 }
 
-static fio_fd open_existing(const char* path) {
-  return os::open(path, O_RDWR, S_IREAD | S_IWRITE);
-}
-
 static fio_fd open_chunk(const char* path) {
   assert(JfrStream_lock->owned_by_self(), "invariant");
-  return path != NULL ? open_existing(path) : invalid_fd;
+  return path != NULL ? os::open(path, O_CREAT | O_RDWR, S_IREAD | S_IWRITE) : invalid_fd;
 }
 
 bool JfrChunkWriter::open() {
--- a/src/share/vm/jfr/recorder/repository/jfrEmergencyDump.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/jfr/recorder/repository/jfrEmergencyDump.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -24,17 +24,314 @@
 
 #include "precompiled.hpp"
 #include "jfr/jfrEvents.hpp"
+#include "jfr/jni/jfrJavaSupport.hpp"
 #include "jfr/leakprofiler/leakProfiler.hpp"
 #include "jfr/recorder/repository/jfrEmergencyDump.hpp"
 #include "jfr/recorder/service/jfrPostBox.hpp"
 #include "jfr/recorder/service/jfrRecorderService.hpp"
 #include "jfr/utilities/jfrTypes.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/arguments.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/mutexLocker.hpp"
-#include "runtime/thread.hpp"
+#include "runtime/os.hpp"
+#include "runtime/thread.inline.hpp"
+#include "utilities/growableArray.hpp"
+
+static const char vm_error_filename_fmt[] = "hs_err_pid%p.jfr";
+static const char vm_oom_filename_fmt[] = "hs_oom_pid%p.jfr";
+static const char vm_soe_filename_fmt[] = "hs_soe_pid%p.jfr";
+static const char chunk_file_jfr_ext[] = ".jfr";
+static const size_t iso8601_len = 19; // "YYYY-MM-DDTHH:MM:SS"
+
+static fio_fd open_exclusivly(const char* path) {
+  return os::open(path, O_CREAT | O_RDWR, S_IREAD | S_IWRITE);
+}
+
+static int file_sort(const char** const file1, const char** file2) {
+  assert(NULL != *file1 && NULL != *file2, "invariant");
+  int cmp = strncmp(*file1, *file2, iso8601_len);
+  if (0 == cmp) {
+    const char* const dot1 = strchr(*file1, '.');
+    assert(NULL != dot1, "invariant");
+    const char* const dot2 = strchr(*file2, '.');
+    assert(NULL != dot2, "invariant");
+    ptrdiff_t file1_len = dot1 - *file1;
+    ptrdiff_t file2_len = dot2 - *file2;
+    if (file1_len < file2_len) {
+      return -1;
+    }
+    if (file1_len > file2_len) {
+      return 1;
+    }
+    assert(file1_len == file2_len, "invariant");
+    cmp = strncmp(*file1, *file2, file1_len);
+  }
+  assert(cmp != 0, "invariant");
+  return cmp;
+}
+
+static void iso8601_to_date_time(char* iso8601_str) {
+  assert(iso8601_str != NULL, "invariant");
+  assert(strlen(iso8601_str) == iso8601_len, "invariant");
+  // "YYYY-MM-DDTHH:MM:SS"
+  for (size_t i = 0; i < iso8601_len; ++i) {
+    switch (iso8601_str[i]) {
+    case 'T':
+    case '-':
+    case ':':
+      iso8601_str[i] = '_';
+      break;
+    }
+  }
+  // "YYYY_MM_DD_HH_MM_SS"
+}
+
+static void date_time(char* buffer, size_t buffer_len) {
+  assert(buffer != NULL, "invariant");
+  assert(buffer_len >= iso8601_len, "buffer too small");
+  os::iso8601_time(buffer, buffer_len);
+  assert(strlen(buffer) >= iso8601_len + 1, "invariant");
+  // "YYYY-MM-DDTHH:MM:SS"
+  buffer[iso8601_len] = '\0';
+  iso8601_to_date_time(buffer);
+}
+
+static int64_t file_size(fio_fd fd) {
+  assert(fd != invalid_fd, "invariant");
+  const int64_t current_offset = os::current_file_offset(fd);
+  const int64_t size = os::lseek(fd, 0, SEEK_END);
+  os::seek_to_file_offset(fd, current_offset);
+  return size;
+}
+
+class RepositoryIterator : public StackObj {
+ private:
+  const char* const _repo;
+  const size_t _repository_len;
+  GrowableArray<const char*>* _files;
+  const char* const fully_qualified(const char* entry) const;
+  mutable int _iterator;
+
+ public:
+  RepositoryIterator(const char* repository, size_t repository_len);
+  ~RepositoryIterator() {}
+  const char* const filter(const char* entry) const;
+  bool has_next() const;
+  const char* const next() const;
+};
+
+const char* const RepositoryIterator::fully_qualified(const char* entry) const {
+  assert(NULL != entry, "invariant");
+  char* file_path_entry = NULL;
+  // only use files that have content, not placeholders
+  const char* const file_separator = os::file_separator();
+  if (NULL != file_separator) {
+    const size_t entry_len = strlen(entry);
+    const size_t file_separator_length = strlen(file_separator);
+    const size_t file_path_entry_length = _repository_len + file_separator_length + entry_len;
+    file_path_entry = NEW_RESOURCE_ARRAY_RETURN_NULL(char, file_path_entry_length + 1);
+    if (NULL == file_path_entry) {
+      return NULL;
+    }
+    int position = 0;
+    position += jio_snprintf(&file_path_entry[position], _repository_len + 1, "%s", _repo);
+    position += jio_snprintf(&file_path_entry[position], file_separator_length + 1, "%s", os::file_separator());
+    position += jio_snprintf(&file_path_entry[position], entry_len + 1, "%s", entry);
+    file_path_entry[position] = '\0';
+    assert((size_t)position == file_path_entry_length, "invariant");
+    assert(strlen(file_path_entry) == (size_t)position, "invariant");
+  }
+  return file_path_entry;
+}
+
+const char* const RepositoryIterator::filter(const char* entry) const {
+  if (entry == NULL) {
+    return NULL;
+  }
+  const size_t entry_len = strlen(entry);
+  if (entry_len <= 2) {
+    // for "." and ".."
+    return NULL;
+  }
+  char* entry_name = NEW_RESOURCE_ARRAY_RETURN_NULL(char, entry_len + 1);
+  if (entry_name == NULL) {
+    return NULL;
+  }
+  strncpy(entry_name, entry, entry_len + 1);
+  const char* const fully_qualified_path_entry = fully_qualified(entry_name);
+  if (NULL == fully_qualified_path_entry) {
+    return NULL;
+  }
+  const fio_fd entry_fd = open_exclusivly(fully_qualified_path_entry);
+  if (invalid_fd == entry_fd) {
+    return NULL;
+  }
+  const int64_t entry_size = file_size(entry_fd);
+  os::close(entry_fd);
+  if (0 == entry_size) {
+    return NULL;
+  }
+  return entry_name;
+}
+
+RepositoryIterator::RepositoryIterator(const char* repository, size_t repository_len) :
+  _repo(repository),
+  _repository_len(repository_len),
+  _files(NULL),
+  _iterator(0) {
+  if (NULL != _repo) {
+    assert(strlen(_repo) == _repository_len, "invariant");
+    _files = new GrowableArray<const char*>(10);
+    DIR* dirp = os::opendir(_repo);
+    if (dirp == NULL) {
+      if (true) tty->print_cr("Unable to open repository %s", _repo);
+      return;
+    }
+    struct dirent* dentry;
+    while ((dentry = os::readdir(dirp)) != NULL) {
+      const char* const entry_path = filter(dentry->d_name);
+      if (NULL != entry_path) {
+        _files->append(entry_path);
+      }
+    }
+    os::closedir(dirp);
+    if (_files->length() > 1) {
+      _files->sort(file_sort);
+    }
+  }
+}
+
+bool RepositoryIterator::has_next() const {
+  return (_files != NULL && _iterator < _files->length());
+}
+
+const char* const RepositoryIterator::next() const {
+  return _iterator >= _files->length() ? NULL : fully_qualified(_files->at(_iterator++));
+}
+
+static void write_emergency_file(fio_fd emergency_fd, const RepositoryIterator& iterator) {
+  assert(emergency_fd != invalid_fd, "invariant");
+  const size_t size_of_file_copy_block = 1 * M; // 1 mb
+  jbyte* const file_copy_block = NEW_RESOURCE_ARRAY_RETURN_NULL(jbyte, size_of_file_copy_block);
+  if (file_copy_block == NULL) {
+    return;
+  }
+  while (iterator.has_next()) {
+    fio_fd current_fd = invalid_fd;
+    const char* const fqn = iterator.next();
+    if (fqn != NULL) {
+      current_fd = open_exclusivly(fqn);
+      if (current_fd != invalid_fd) {
+        const int64_t current_filesize = file_size(current_fd);
+        assert(current_filesize > 0, "invariant");
+        int64_t bytes_read = 0;
+        int64_t bytes_written = 0;
+        while (bytes_read < current_filesize) {
+          const ssize_t read_result = os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read);
+          if (-1 == read_result) {
+            if (LogJFR) tty->print_cr("Unable to recover JFR data");
+            break;
+          }
+          bytes_read += (int64_t)read_result;
+          assert(bytes_read - bytes_written <= (int64_t)size_of_file_copy_block, "invariant");
+          bytes_written += (int64_t)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written);
+          assert(bytes_read == bytes_written, "invariant");
+        }
+        os::close(current_fd);
+      }
+    }
+  }
+}
+
+static const char* create_emergency_dump_path() {
+  assert(JfrStream_lock->owned_by_self(), "invariant");
+  char* buffer = NEW_RESOURCE_ARRAY_RETURN_NULL(char, JVM_MAXPATHLEN);
+  if (NULL == buffer) {
+    return NULL;
+  }
+  const char* const cwd = os::get_current_directory(buffer, JVM_MAXPATHLEN);
+  if (NULL == cwd) {
+    return NULL;
+  }
+  size_t pos = strlen(cwd);
+  const int fsep_len = jio_snprintf(&buffer[pos], JVM_MAXPATHLEN - pos, "%s", os::file_separator());
+  const char* filename_fmt = NULL;
+  // fetch specific error cause
+  switch (JfrJavaSupport::cause()) {
+    case JfrJavaSupport::OUT_OF_MEMORY:
+      filename_fmt = vm_oom_filename_fmt;
+      break;
+    case JfrJavaSupport::STACK_OVERFLOW:
+      filename_fmt = vm_soe_filename_fmt;
+      break;
+    default:
+      filename_fmt = vm_error_filename_fmt;
+  }
+  char* emergency_dump_path = NULL;
+  pos += fsep_len;
+  if (Arguments::copy_expand_pid(filename_fmt, strlen(filename_fmt), &buffer[pos], JVM_MAXPATHLEN - pos)) {
+    const size_t emergency_filename_length = strlen(buffer);
+    emergency_dump_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, emergency_filename_length + 1);
+    if (NULL == emergency_dump_path) {
+      return NULL;
+    }
+    strncpy(emergency_dump_path, buffer, emergency_filename_length + 1);
+  }
+  if (emergency_dump_path != NULL) {
+    if (LogJFR) tty->print_cr( // For user, should not be "jfr, system"
+      "Attempting to recover JFR data, emergency jfr file: %s", emergency_dump_path);
+  }
+  return emergency_dump_path;
+}
+
+// Caller needs ResourceMark
+static const char* create_emergency_chunk_path(const char* repository_path) {
+  assert(repository_path != NULL, "invariant");
+  assert(JfrStream_lock->owned_by_self(), "invariant");
+  const size_t repository_path_len = strlen(repository_path);
+  // date time
+  char date_time_buffer[32] = { 0 };
+  date_time(date_time_buffer, sizeof(date_time_buffer));
+  size_t date_time_len = strlen(date_time_buffer);
+  size_t chunkname_max_len = repository_path_len          // repository_base_path
+                             + 1                          // "/"
+                             + date_time_len              // date_time
+                             + strlen(chunk_file_jfr_ext) // .jfr
+                             + 1;
+  char* chunk_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, chunkname_max_len);
+  if (chunk_path == NULL) {
+    return NULL;
+  }
+  // append the individual substrings
+  jio_snprintf(chunk_path, chunkname_max_len, "%s%s%s%s", repository_path_len, os::file_separator(), date_time_buffer, chunk_file_jfr_ext);
+  return chunk_path;
+}
+
+static fio_fd emergency_dump_file_descriptor() {
+  assert(JfrStream_lock->owned_by_self(), "invariant");
+  ResourceMark rm;
+  const char* const emergency_dump_path = create_emergency_dump_path();
+  return emergency_dump_path != NULL ? open_exclusivly(emergency_dump_path) : invalid_fd;
+}
+
+const char* JfrEmergencyDump::build_dump_path(const char* repository_path) {
+  return repository_path == NULL ? create_emergency_dump_path() : create_emergency_chunk_path(repository_path);
+}
+
+void JfrEmergencyDump::on_vm_error(const char* repository_path) {
+  assert(repository_path != NULL, "invariant");
+  ResourceMark rm;
+  MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
+  const fio_fd emergency_fd = emergency_dump_file_descriptor();
+  if (emergency_fd != invalid_fd) {
+    RepositoryIterator iterator(repository_path, strlen(repository_path));
+    write_emergency_file(emergency_fd, iterator);
+    os::close(emergency_fd);
+  }
+}
 
 /*
 * We are just about to exit the VM, so we will be very aggressive
--- a/src/share/vm/jfr/recorder/repository/jfrEmergencyDump.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/jfr/recorder/repository/jfrEmergencyDump.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -33,6 +33,8 @@
 class JfrEmergencyDump : AllStatic {
  public:
   static void on_vm_shutdown(bool exception_handler);
+  static void on_vm_error(const char* repository_path);
+  static const char* build_dump_path(const char* repository_path);
 };
 
 #endif // SHARE_VM_JFR_RECORDER_INTERNAL_JFREMERGENCY_HPP
--- a/src/share/vm/jfr/recorder/repository/jfrRepository.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/jfr/recorder/repository/jfrRepository.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -28,12 +28,12 @@
 #include "jfr/recorder/jfrRecorder.hpp"
 #include "jfr/recorder/repository/jfrChunkState.hpp"
 #include "jfr/recorder/repository/jfrChunkWriter.hpp"
+#include "jfr/recorder/repository/jfrEmergencyDump.hpp"
 #include "jfr/recorder/repository/jfrRepository.hpp"
 #include "jfr/recorder/service/jfrPostBox.hpp"
 #include "memory/resourceArea.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/arguments.hpp"
-#include "runtime/os.hpp"
 #include "runtime/thread.inline.hpp"
 
 static JfrRepository* _instance = NULL;
@@ -84,320 +84,13 @@
   _instance = NULL;
 }
 
-static const char vm_error_filename_fmt[] = "hs_err_pid%p.jfr";
-static const char vm_oom_filename_fmt[] = "hs_oom_pid%p.jfr";
-static const char vm_soe_filename_fmt[] = "hs_soe_pid%p.jfr";
-static const char chunk_file_jfr_ext[] = ".jfr";
-static const size_t iso8601_len = 19; // "YYYY-MM-DDTHH:MM:SS"
-
-static fio_fd open_exclusivly(const char* path) {
-  return os::open(path, O_CREAT | O_WRONLY, S_IREAD | S_IWRITE);
-}
-
-static fio_fd open_existing(const char* path) {
-  return os::open(path, O_RDWR, S_IREAD | S_IWRITE);
-}
-
-static int file_sort(const char** const file1, const char** file2) {
-  assert(NULL != *file1 && NULL != *file2, "invariant");
-  int cmp = strncmp(*file1, *file2, iso8601_len);
-  if (0 == cmp) {
-    const char* const dot1 = strchr(*file1, '.');
-    assert(NULL != dot1, "invariant");
-    const char* const dot2 = strchr(*file2, '.');
-    assert(NULL != dot2, "invariant");
-    ptrdiff_t file1_len = dot1 - *file1;
-    ptrdiff_t file2_len = dot2 - *file2;
-    if (file1_len < file2_len) {
-      return -1;
-    }
-    if (file1_len > file2_len) {
-      return 1;
-    }
-    assert(file1_len == file2_len, "invariant");
-    cmp = strncmp(*file1, *file2, file1_len);
-  }
-  assert(cmp != 0, "invariant");
-  return cmp;
-}
-
-static void iso8601_to_date_time(char* iso8601_str) {
-  assert(iso8601_str != NULL, "invariant");
-  assert(strlen(iso8601_str) == iso8601_len, "invariant");
-  // "YYYY-MM-DDTHH:MM:SS"
-  for (size_t i = 0; i < iso8601_len; ++i) {
-    switch(iso8601_str[i]) {
-      case 'T' :
-      case '-' :
-      case ':' :
-        iso8601_str[i] = '_';
-        break;
-    }
-  }
-  // "YYYY_MM_DD_HH_MM_SS"
-}
-
-static void date_time(char* buffer, size_t buffer_len) {
-  assert(buffer != NULL, "invariant");
-  assert(buffer_len >= iso8601_len, "buffer too small");
-  os::iso8601_time(buffer, buffer_len);
-  assert(strlen(buffer) >= iso8601_len + 1, "invariant");
-  // "YYYY-MM-DDTHH:MM:SS"
-  buffer[iso8601_len] = '\0';
-  iso8601_to_date_time(buffer);
-}
-
-static int64_t file_size(fio_fd fd) {
-  assert(fd != invalid_fd, "invariant");
-  const int64_t current_offset = os::current_file_offset(fd);
-  const int64_t size = os::lseek(fd, 0, SEEK_END);
-  os::seek_to_file_offset(fd, current_offset);
-  return size;
-}
-
-class RepositoryIterator : public StackObj {
- private:
-  const char* const _repo;
-  const size_t _repository_len;
-  GrowableArray<const char*>* _files;
-  const char* const fully_qualified(const char* entry) const;
-  mutable int _iterator;
-
- public:
-   RepositoryIterator(const char* repository, size_t repository_len);
-   ~RepositoryIterator() {}
-  debug_only(void print_repository_files() const;)
-  const char* const filter(const char* entry) const;
-  bool has_next() const;
-  const char* const next() const;
-};
-
-const char* const RepositoryIterator::fully_qualified(const char* entry) const {
-  assert(NULL != entry, "invariant");
-  char* file_path_entry = NULL;
-   // only use files that have content, not placeholders
-  const char* const file_separator = os::file_separator();
-  if (NULL != file_separator) {
-    const size_t entry_len = strlen(entry);
-    const size_t file_separator_length = strlen(file_separator);
-    const size_t file_path_entry_length = _repository_len + file_separator_length + entry_len;
-    file_path_entry = NEW_RESOURCE_ARRAY_RETURN_NULL(char, file_path_entry_length + 1);
-    if (NULL == file_path_entry) {
-      return NULL;
-    }
-    int position = 0;
-    position += jio_snprintf(&file_path_entry[position], _repository_len + 1, "%s", _repo);
-    position += jio_snprintf(&file_path_entry[position], file_separator_length + 1, "%s", os::file_separator());
-    position += jio_snprintf(&file_path_entry[position], entry_len + 1, "%s", entry);
-    file_path_entry[position] = '\0';
-    assert((size_t)position == file_path_entry_length, "invariant");
-    assert(strlen(file_path_entry) == (size_t)position, "invariant");
-  }
-  return file_path_entry;
-}
-
-const char* const RepositoryIterator::filter(const char* entry) const {
-  if (entry == NULL) {
-    return NULL;
-  }
-  const size_t entry_len = strlen(entry);
-  if (entry_len <= 2) {
-    // for "." and ".."
-    return NULL;
-  }
-  char* entry_name = NEW_RESOURCE_ARRAY_RETURN_NULL(char, entry_len + 1);
-  if (entry_name == NULL) {
-    return NULL;
-  }
-  strncpy(entry_name, entry, entry_len + 1);
-  const char* const fully_qualified_path_entry = fully_qualified(entry_name);
-  if (NULL == fully_qualified_path_entry) {
-    return NULL;
-  }
-  const fio_fd entry_fd = open_existing(fully_qualified_path_entry);
-  if (invalid_fd == entry_fd) {
-    return NULL;
-  }
-  const int64_t entry_size = file_size(entry_fd);
-  os::close(entry_fd);
-  if (0 == entry_size) {
-    return NULL;
-  }
-  return entry_name;
-}
-
-RepositoryIterator::RepositoryIterator(const char* repository, size_t repository_len) :
-  _repo(repository),
-  _repository_len(repository_len),
-  _files(NULL),
-  _iterator(0) {
-  if (NULL != _repo) {
-    assert(strlen(_repo) == _repository_len, "invariant");
-    _files = new GrowableArray<const char*>(10);
-    DIR* dirp = os::opendir(_repo);
-    if (dirp == NULL) {
-      if (true) tty->print_cr("Unable to open repository %s", _repo);
-      return;
-    }
-    struct dirent* dentry;
-    while ((dentry = os::readdir(dirp)) != NULL) {
-      const char* const entry_path = filter(dentry->d_name);
-      if (NULL != entry_path) {
-        _files->append(entry_path);
-      }
-    }
-    os::closedir(dirp);
-    if (_files->length() > 1) {
-      _files->sort(file_sort);
-    }
-  }
-}
-
-#ifdef ASSERT
-void RepositoryIterator::print_repository_files() const {
-  while (has_next()) {
-    if (true) tty->print_cr( "%s", next());
-  }
-}
-#endif
-
-bool RepositoryIterator::has_next() const {
-  return (_files != NULL && _iterator < _files->length());
-}
-
-const char* const RepositoryIterator::next() const {
-  return _iterator >= _files->length() ? NULL : fully_qualified(_files->at(_iterator++));
-}
-
-static void write_emergency_file(fio_fd emergency_fd, const RepositoryIterator& iterator) {
-  assert(emergency_fd != invalid_fd, "invariant");
-  const size_t size_of_file_copy_block = 1 * M; // 1 mb
-  jbyte* const file_copy_block = NEW_RESOURCE_ARRAY_RETURN_NULL(jbyte, size_of_file_copy_block);
-  if (file_copy_block == NULL) {
-    return;
-  }
- int64_t bytes_written_total = 0;
-  while (iterator.has_next()) {
-    fio_fd current_fd = invalid_fd;
-    const char* const fqn = iterator.next();
-    if (fqn != NULL) {
-      current_fd = open_existing(fqn);
-      if (current_fd != invalid_fd) {
-        const int64_t current_filesize = file_size(current_fd);
-        assert(current_filesize > 0, "invariant");
-        int64_t bytes_read = 0;
-        int64_t bytes_written = 0;
-        while (bytes_read < current_filesize) {
-          const ssize_t read_result = os::read_at(current_fd, file_copy_block, size_of_file_copy_block, bytes_read);
-          if (-1 == read_result) {
-            if (LogJFR) tty->print_cr("Unable to recover JFR data");
-            break;
-          }
-          bytes_read += (int64_t)read_result;
-          assert(bytes_read - bytes_written <= (int64_t)size_of_file_copy_block, "invariant");
-          bytes_written += (int64_t)os::write(emergency_fd, file_copy_block, bytes_read - bytes_written);
-          assert(bytes_read == bytes_written, "invariant");
-        }
-        os::close(current_fd);
-        bytes_written_total += bytes_written;
-      }
-    }
-  }
-}
-
-static const char* create_emergency_dump_path() {
-  assert(JfrStream_lock->owned_by_self(), "invariant");
-  char* buffer = NEW_RESOURCE_ARRAY_RETURN_NULL(char, O_BUFLEN);
-  if (NULL == buffer) {
-    return NULL;
-  }
-  const char* const cwd = os::get_current_directory(buffer, O_BUFLEN);
-  if (NULL == cwd) {
-    return NULL;
-  }
-  size_t pos = strlen(cwd);
-  const int fsep_len = jio_snprintf(&buffer[pos], O_BUFLEN - pos, "%s", os::file_separator());
-  const char* filename_fmt = NULL;
-  // fetch specific error cause
-  switch (JfrJavaSupport::cause()) {
-    case JfrJavaSupport::OUT_OF_MEMORY:
-      filename_fmt = vm_oom_filename_fmt;
-      break;
-    case JfrJavaSupport::STACK_OVERFLOW:
-      filename_fmt = vm_soe_filename_fmt;
-      break;
-    default:
-      filename_fmt = vm_error_filename_fmt;
-  }
-  char* emergency_dump_path = NULL;
-  pos += fsep_len;
-  if (Arguments::copy_expand_pid(filename_fmt, strlen(filename_fmt), &buffer[pos], O_BUFLEN - pos)) {
-    const size_t emergency_filename_length = strlen(buffer);
-    emergency_dump_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, emergency_filename_length + 1);
-    if (NULL == emergency_dump_path) {
-      return NULL;
-    }
-    strncpy(emergency_dump_path, buffer, emergency_filename_length + 1);
-  }
-  return emergency_dump_path;
-}
-
-// Caller needs ResourceMark
-static const char* create_emergency_chunk_path(const char* repository_base, size_t repository_len) {
-  assert(repository_base != NULL, "invariant");
-  assert(JfrStream_lock->owned_by_self(), "invariant");
-  // date time
-  char date_time_buffer[32] = {0};
-  date_time(date_time_buffer, sizeof(date_time_buffer));
-  size_t date_time_len = strlen(date_time_buffer);
-  size_t chunkname_max_len = repository_len               // repository_base
-                             + 1                          // "/"
-                             + date_time_len              // date_time
-                             + strlen(chunk_file_jfr_ext) // .jfr
-                             + 1;
-  char* chunk_path = NEW_RESOURCE_ARRAY_RETURN_NULL(char, chunkname_max_len);
-  if (chunk_path == NULL) {
-    return NULL;
-  }
-  // append the individual substrings
-  jio_snprintf(chunk_path, chunkname_max_len, "%s%s%s%s", repository_base, os::file_separator(), date_time_buffer, chunk_file_jfr_ext);
-  return chunk_path;
-}
-
-static fio_fd emergency_dump_file() {
-  assert(JfrStream_lock->owned_by_self(), "invariant");
-  ResourceMark rm;
-  const char* const emergency_dump_path = create_emergency_dump_path();
-  if (emergency_dump_path == NULL) {
-    return invalid_fd;
-  }
-  const fio_fd fd = open_exclusivly(emergency_dump_path);
-  if (fd != invalid_fd) {
-    if (LogJFR) tty->print_cr( // For user, should not be "jfr, system"
-      "Attempting to recover JFR data, emergency jfr file: %s", emergency_dump_path);
-  }
-  return fd;
-}
-
-static const char* emergency_path(const char* repository, size_t repository_len) {
-  return repository == NULL ? create_emergency_dump_path() : create_emergency_chunk_path(repository, repository_len);
-}
-
 void JfrRepository::on_vm_error() {
   assert(!JfrStream_lock->owned_by_self(), "invariant");
-  const char* path = _path;
-  if (path == NULL) {
+  if (_path == NULL) {
     // completed already
     return;
   }
-  ResourceMark rm;
-  MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag);
-  const fio_fd emergency_fd = emergency_dump_file();
-  if (emergency_fd != invalid_fd) {
-    RepositoryIterator iterator(path, strlen(path));
-    write_emergency_file(emergency_fd, iterator);
-    os::close(emergency_fd);
-  }
+  JfrEmergencyDump::on_vm_error(_path);
 }
 
 bool JfrRepository::set_path(const char* path) {
@@ -466,10 +159,7 @@
   assert(JfrStream_lock->owned_by_self(), "invariant");
   if (vm_error) {
     ResourceMark rm;
-    const char* repository_path = _path;
-    const size_t repository_path_len = repository_path != NULL ? strlen(repository_path) : 0;
-    const char* const path = emergency_path(repository_path, repository_path_len);
-    _chunkwriter->set_chunk_path(path);
+    _chunkwriter->set_chunk_path(JfrEmergencyDump::build_dump_path(_path));
   }
   return _chunkwriter->open();
 }
--- a/src/share/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/jfr/recorder/stacktrace/jfrStackTraceRepository.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -376,6 +376,7 @@
     vfs.next();
   }
 
+  _hash = 1;
   while (!vfs.at_end()) {
     if (count >= _max_frames) {
       _reached_root = false;
@@ -391,7 +392,9 @@
       bci = vfs.bci();
     }
     // Can we determine if it's inlined?
-    _hash = (_hash << 2) + (unsigned int)(((size_t)mid >> 2) + (bci << 4) + type);
+    _hash = (_hash * 31) + mid;
+    _hash = (_hash * 31) + bci;
+    _hash = (_hash * 31) + type;
     _frames[count] = JfrStackFrame(mid, bci, type, method);
     vfs.next();
     count++;
@@ -406,6 +409,7 @@
   u4 count = 0;
   _reached_root = true;
 
+  _hash = 1;
   while (!st.at_end()) {
     if (count >= _max_frames) {
       _reached_root = false;
@@ -427,7 +431,9 @@
     }
     const int lineno = method->line_number_from_bci(bci);
     // Can we determine if it's inlined?
-    _hash = (_hash << 2) + (unsigned int)(((size_t)mid >> 2) + (bci << 4) + type);
+    _hash = (_hash * 31) + mid;
+    _hash = (_hash * 31) + bci;
+    _hash = (_hash * 31) + type;
     _frames[count] = JfrStackFrame(mid, bci, type, lineno);
     st.samples_next();
     count++;
--- a/src/share/vm/memory/allocation.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/memory/allocation.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -529,7 +529,7 @@
 // change the size
 void Arena::set_size_in_bytes(size_t size) {
   if (_size_in_bytes != size) {
-    long delta = (long)(size - size_in_bytes());
+    ssize_t delta = size - size_in_bytes();
     _size_in_bytes = size;
     MemTracker::record_arena_size_change(delta, _flags);
   }
--- a/src/share/vm/memory/genCollectedHeap.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/memory/genCollectedHeap.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1181,7 +1181,7 @@
 
 
 void GenCollectedHeap::prepare_for_compaction() {
-  guarantee(_n_gens = 2, "Wrong number of generations");
+  guarantee(_n_gens == 2, "Wrong number of generations");
   Generation* old_gen = _gens[1];
   // Start by compacting into same gen.
   CompactPoint cp(old_gen);
--- a/src/share/vm/memory/padded.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/memory/padded.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -80,6 +80,12 @@
   // super class that is specialized for the pad_size == 0 case.
 };
 
+// Similar to PaddedEnd, this macro defines a _pad_buf#id field
+// that is (alignment - size) bytes in size. This macro is used
+// to add padding in between non-class fields in a class or struct.
+#define DEFINE_PAD_MINUS_SIZE(id, alignment, size) \
+          char _pad_buf##id[(alignment) - (size)]
+
 // Helper class to create an array of PaddedEnd<T> objects. All elements will
 // start at a multiple of alignment and the size will be aligned to alignment.
 template <class T, MEMFLAGS flags, size_t alignment = DEFAULT_CACHE_LINE_SIZE>
--- a/src/share/vm/memory/resourceArea.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/memory/resourceArea.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,8 +31,11 @@
 
 void ResourceArea::bias_to(MEMFLAGS new_flags) {
   if (new_flags != _flags) {
+    size_t size = size_in_bytes();
+    MemTracker::record_arena_size_change(-ssize_t(size), _flags);
     MemTracker::record_arena_free(_flags);
     MemTracker::record_new_arena(new_flags);
+    MemTracker::record_arena_size_change(ssize_t(size), new_flags);
     _flags = new_flags;
   }
 }
--- a/src/share/vm/memory/threadLocalAllocBuffer.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/memory/threadLocalAllocBuffer.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -120,6 +120,8 @@
   size_t free() const                            { return pointer_delta(end(), top()); }
   // Don't discard tlab if remaining space is larger than this.
   size_t refill_waste_limit() const              { return _refill_waste_limit; }
+  size_t hard_size_bytes() const                 { return pointer_delta(hard_end(), start(), 1); }
+  bool in_used(HeapWord* addr) const             { return addr >= start() && addr < top(); }
 
   // Allocate size HeapWords. The memory is NOT initialized to zero.
   inline HeapWord* allocate(size_t size);
--- a/src/share/vm/oops/oop.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/oops/oop.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -83,10 +83,12 @@
 
   Klass* klass() const;
   Klass* klass_or_null() const volatile;
+  Klass* klass_or_null_acquire() const volatile;
   Klass** klass_addr();
   narrowKlass* compressed_klass_addr();
 
   void set_klass(Klass* k);
+  void release_set_klass(Klass* k);
 
   // For klass field compression
   int klass_gap() const;
--- a/src/share/vm/oops/oop.inline.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/oops/oop.inline.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -81,7 +81,6 @@
 }
 
 inline Klass* oopDesc::klass_or_null() const volatile {
-  // can be NULL in CMS
   if (UseCompressedClassPointers) {
     return Klass::decode_klass(_metadata._compressed_klass);
   } else {
@@ -89,6 +88,17 @@
   }
 }
 
+inline Klass* oopDesc::klass_or_null_acquire() const volatile {
+  if (UseCompressedClassPointers) {
+    // Workaround for non-const load_acquire parameter.
+    const volatile narrowKlass* addr = &_metadata._compressed_klass;
+    volatile narrowKlass* xaddr = const_cast<volatile narrowKlass*>(addr);
+    return Klass::decode_klass(OrderAccess::load_acquire(xaddr));
+  } else {
+    return (Klass*)OrderAccess::load_ptr_acquire(&_metadata._klass);
+  }
+}
+
 inline int oopDesc::klass_gap_offset_in_bytes() {
   assert(UseCompressedClassPointers, "only applicable to compressed klass pointers");
   return oopDesc::klass_offset_in_bytes() + sizeof(narrowKlass);
@@ -106,10 +116,14 @@
   return &_metadata._compressed_klass;
 }
 
+#define CHECK_SET_KLASS(k)                                                \
+  do {                                                                    \
+    assert(Universe::is_bootstrapping() || k != NULL, "NULL Klass");      \
+    assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass"); \
+  } while (0)
+
 inline void oopDesc::set_klass(Klass* k) {
-  // since klasses are promoted no store check is needed
-  assert(Universe::is_bootstrapping() || k != NULL, "must be a real Klass*");
-  assert(Universe::is_bootstrapping() || k->is_klass(), "not a Klass*");
+  CHECK_SET_KLASS(k);
   if (UseCompressedClassPointers) {
     *compressed_klass_addr() = Klass::encode_klass_not_null(k);
   } else {
@@ -117,6 +131,18 @@
   }
 }
 
+inline void oopDesc::release_set_klass(Klass* k) {
+  CHECK_SET_KLASS(k);
+  if (UseCompressedClassPointers) {
+    OrderAccess::release_store(compressed_klass_addr(),
+                               Klass::encode_klass_not_null(k));
+  } else {
+    OrderAccess::release_store_ptr(klass_addr(), k);
+  }
+}
+
+#undef CHECK_SET_KLASS
+
 inline int oopDesc::klass_gap() const {
   return *(int*)(((intptr_t)this) + klass_gap_offset_in_bytes());
 }
--- a/src/share/vm/opto/c2_globals.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/opto/c2_globals.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -63,10 +63,10 @@
 
 #define C2_FLAGS(develop, develop_pd, product, product_pd, diagnostic, experimental, notproduct) \
                                                                             \
-  develop(bool, StressLCM, false,                                           \
+  diagnostic(bool, StressLCM, false,                                        \
           "Randomize instruction scheduling in LCM")                        \
                                                                             \
-  develop(bool, StressGCM, false,                                           \
+  diagnostic(bool, StressGCM, false,                                        \
           "Randomize instruction scheduling in GCM")                        \
                                                                             \
   notproduct(intx, CompileZapFirst, 0,                                      \
--- a/src/share/vm/prims/jvm.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/prims/jvm.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/src/share/vm/prims/whitebox.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/prims/whitebox.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -448,6 +448,21 @@
   assert(hash_size > 0, "NMT hash_size should be > 0");
   return (jint)hash_size;
 WB_END
+
+WB_ENTRY(jlong, WB_NMTNewArena(JNIEnv* env, jobject o, jlong init_size))
+  Arena* arena =  new (mtTest) Arena(mtTest, size_t(init_size));
+  return (jlong)arena;
+WB_END
+
+WB_ENTRY(void, WB_NMTFreeArena(JNIEnv* env, jobject o, jlong arena))
+  Arena* a = (Arena*)arena;
+  delete a;
+WB_END
+
+WB_ENTRY(void, WB_NMTArenaMalloc(JNIEnv* env, jobject o, jlong arena, jlong size))
+  Arena* a = (Arena*)arena;
+  a->Amalloc(size_t(size));
+WB_END
 #endif // INCLUDE_NMT
 
 static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
@@ -1244,6 +1259,9 @@
   {CC"NMTIsDetailSupported",CC"()Z",                  (void*)&WB_NMTIsDetailSupported},
   {CC"NMTChangeTrackingLevel", CC"()Z",               (void*)&WB_NMTChangeTrackingLevel},
   {CC"NMTGetHashSize",      CC"()I",                  (void*)&WB_NMTGetHashSize     },
+  {CC"NMTNewArena",         CC"(J)J",                 (void*)&WB_NMTNewArena        },
+  {CC"NMTFreeArena",        CC"(J)V",                 (void*)&WB_NMTFreeArena       },
+  {CC"NMTArenaMalloc",      CC"(JJ)V",                (void*)&WB_NMTArenaMalloc     },
 #endif // INCLUDE_NMT
   {CC"deoptimizeAll",      CC"()V",                   (void*)&WB_DeoptimizeAll     },
   {CC"deoptimizeMethod",   CC"(Ljava/lang/reflect/Executable;Z)I",
--- a/src/share/vm/runtime/globals.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/runtime/globals.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -3499,6 +3499,9 @@
   notproduct(bool, CIObjectFactoryVerify, false,                            \
           "enable potentially expensive verification in ciObjectFactory")   \
                                                                             \
+  diagnostic(bool, AbortVMOnCompilationFailure, false,                      \
+          "Abort VM when method had failed to compile.")                    \
+                                                                            \
   /* Priorities */                                                          \
   product_pd(bool, UseThreadPriorities,  "Use native thread priorities")    \
                                                                             \
--- a/src/share/vm/runtime/objectMonitor.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/runtime/objectMonitor.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -2316,6 +2316,7 @@
   _next     = NULL;
   _prev     = NULL;
   _notified = 0;
+  _notifier_tid = 0;
   TState    = TS_RUN ;
   _thread   = thread;
   _event    = thread->_ParkEvent ;
--- a/src/share/vm/runtime/os.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/runtime/os.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -96,18 +96,6 @@
   os::init_globals();
 }
 
-static time_t get_timezone(const struct tm* time_struct) {
-#if defined(_ALLBSD_SOURCE)
-  return time_struct->tm_gmtoff;
-#elif defined(_WINDOWS)
-  long zone;
-  _get_timezone(&zone);
-  return static_cast<time_t>(zone);
-#else
-  return timezone;
-#endif
-}
-
 int os::snprintf(char* buf, size_t len, const char* fmt, ...) {
   va_list args;
   va_start(args, fmt);
@@ -154,17 +142,31 @@
     assert(false, "Failed localtime_pd");
     return NULL;
   }
-  const time_t zone = get_timezone(&time_struct);
 
-  // If daylight savings time is in effect,
-  // we are 1 hour East of our time zone
   const time_t seconds_per_minute = 60;
   const time_t minutes_per_hour = 60;
   const time_t seconds_per_hour = seconds_per_minute * minutes_per_hour;
-  time_t UTC_to_local = zone;
+
+  time_t UTC_to_local = 0;
+#if defined(_ALLBSD_SOURCE) || defined(_GNU_SOURCE)
+    UTC_to_local = -(time_struct.tm_gmtoff);
+#elif defined(_WINDOWS)
+  long zone;
+  _get_timezone(&zone);
+  UTC_to_local = static_cast<time_t>(zone);
+#else
+  UTC_to_local = timezone;
+#endif
+
+  // tm_gmtoff already includes adjustment for daylight saving
+#if !defined(_ALLBSD_SOURCE) && !defined(_GNU_SOURCE)
+  // If daylight savings time is in effect,
+  // we are 1 hour East of our time zone
   if (time_struct.tm_isdst > 0) {
     UTC_to_local = UTC_to_local - seconds_per_hour;
   }
+#endif
+
   // Compute the time zone offset.
   //    localtime_pd() sets timezone to the difference (in seconds)
   //    between UTC and and local time.
--- a/src/share/vm/runtime/perfData.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/runtime/perfData.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -773,7 +773,7 @@
     static PerfStringVariable* create_string_variable(CounterNS ns,
                                                       const char* name,
                                                       const char *s, TRAPS) {
-      return create_string_variable(ns, name, 0, s, CHECK_NULL);
+      return create_string_variable(ns, name, 0, s, THREAD);
     };
 
     static PerfLongVariable* create_long_variable(CounterNS ns,
@@ -784,7 +784,7 @@
     static PerfLongVariable* create_long_variable(CounterNS ns,
                                                   const char* name,
                                                   PerfData::Units u, TRAPS) {
-      return create_long_variable(ns, name, u, (jlong)0, CHECK_NULL);
+      return create_long_variable(ns, name, u, (jlong)0, THREAD);
     };
 
     static PerfLongVariable* create_long_variable(CounterNS, const char* name,
@@ -805,7 +805,7 @@
 
     static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
                                                 PerfData::Units u, TRAPS) {
-      return create_long_counter(ns, name, u, (jlong)0, CHECK_NULL);
+      return create_long_counter(ns, name, u, (jlong)0, THREAD);
     };
 
     static PerfLongCounter* create_long_counter(CounterNS ns, const char* name,
@@ -823,49 +823,49 @@
 
     static PerfConstant* create_constant(CounterNS ns, const char* name,
                                          PerfData::Units u, jlong val, TRAPS) {
-      return create_long_constant(ns, name, u, val, CHECK_NULL);
+      return create_long_constant(ns, name, u, val, THREAD);
     }
 
     static PerfVariable* create_variable(CounterNS ns, const char* name,
                                          PerfData::Units u, jlong ival, TRAPS) {
-      return create_long_variable(ns, name, u, ival, CHECK_NULL);
+      return create_long_variable(ns, name, u, ival, THREAD);
     }
 
     static PerfVariable* create_variable(CounterNS ns, const char* name,
                                          PerfData::Units u, TRAPS) {
-      return create_long_variable(ns, name, u, (jlong)0, CHECK_NULL);
+      return create_long_variable(ns, name, u, (jlong)0, THREAD);
     }
 
     static PerfVariable* create_variable(CounterNS ns, const char* name,
                                          PerfData::Units u, jlong* sp, TRAPS) {
-      return create_long_variable(ns, name, u, sp, CHECK_NULL);
+      return create_long_variable(ns, name, u, sp, THREAD);
     }
 
     static PerfVariable* create_variable(CounterNS ns, const char* name,
                                          PerfData::Units u,
                                          PerfSampleHelper* sh, TRAPS) {
-      return create_long_variable(ns, name, u, sh, CHECK_NULL);
+      return create_long_variable(ns, name, u, sh, THREAD);
     }
 
     static PerfCounter* create_counter(CounterNS ns, const char* name,
                                        PerfData::Units u, jlong ival, TRAPS) {
-      return create_long_counter(ns, name, u, ival, CHECK_NULL);
+      return create_long_counter(ns, name, u, ival, THREAD);
     }
 
     static PerfCounter* create_counter(CounterNS ns, const char* name,
                                        PerfData::Units u, TRAPS) {
-      return create_long_counter(ns, name, u, (jlong)0, CHECK_NULL);
+      return create_long_counter(ns, name, u, (jlong)0, THREAD);
     }
 
     static PerfCounter* create_counter(CounterNS ns, const char* name,
                                        PerfData::Units u, jlong* sp, TRAPS) {
-      return create_long_counter(ns, name, u, sp, CHECK_NULL);
+      return create_long_counter(ns, name, u, sp, THREAD);
     }
 
     static PerfCounter* create_counter(CounterNS ns, const char* name,
                                        PerfData::Units u,
                                        PerfSampleHelper* sh, TRAPS) {
-      return create_long_counter(ns, name, u, sh, CHECK_NULL);
+      return create_long_counter(ns, name, u, sh, THREAD);
     }
 
     static void destroy();
--- a/src/share/vm/runtime/reflection.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/runtime/reflection.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -506,7 +506,7 @@
       (accessor_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION &&
        accessee_ik->major_version() < Verifier::STRICTER_ACCESS_CTRL_CHECK_VERSION)) {
     return classloader_only &&
-      Verifier::relax_verify_for(accessor_ik->class_loader()) &&
+      Verifier::relax_access_for(accessor_ik->class_loader()) &&
       accessor_ik->protection_domain() == accessee_ik->protection_domain() &&
       accessor_ik->class_loader() == accessee_ik->class_loader();
   } else {
--- a/src/share/vm/services/jmm.h	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/services/jmm.h	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, 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
@@ -219,7 +219,9 @@
 
 typedef struct jmmInterface_1_ {
   void*        reserved1;
-  void*        reserved2;
+  jlong        (JNICALL *GetOneThreadAllocatedMemory)
+                                                 (JNIEnv *env,
+                                                  jlong thread_id);
 
   jint         (JNICALL *GetVersion)             (JNIEnv *env);
 
@@ -317,7 +319,11 @@
   void         (JNICALL *SetVMGlobal)            (JNIEnv *env,
                                                   jstring flag_name,
                                                   jvalue  new_value);
-  void*        reserved6;
+  jobjectArray (JNICALL *DumpThreadsMaxDepth)    (JNIEnv *env,
+                                                  jlongArray ids,
+                                                  jboolean lockedMonitors,
+                                                  jboolean lockedSynchronizers,
+                                                  jint maxDepth);
   jobjectArray (JNICALL *DumpThreads)            (JNIEnv *env,
                                                   jlongArray ids,
                                                   jboolean lockedMonitors,
--- a/src/share/vm/services/mallocTracker.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/services/mallocTracker.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -69,8 +69,9 @@
     }
   }
 
-  inline void resize(long sz) {
+  inline void resize(ssize_t sz) {
     if (sz != 0) {
+      assert(sz >= 0 || _size >= size_t(-sz), "Must be");
       Atomic::add((MemoryCounterType)sz, (volatile MemoryCounterType*)&_size);
       DEBUG_ONLY(_peak_size = MAX2(_size, _peak_size);)
     }
@@ -112,7 +113,7 @@
     _arena.deallocate(0);
   }
 
-  inline void record_arena_size_change(long sz) {
+  inline void record_arena_size_change(ssize_t sz) {
     _arena.resize(sz);
   }
 
@@ -202,7 +203,7 @@
      as_snapshot()->by_type(flag)->record_arena_free();
    }
 
-   static inline void record_arena_size_change(long size, MEMFLAGS flag) {
+   static inline void record_arena_size_change(ssize_t size, MEMFLAGS flag) {
      as_snapshot()->by_type(flag)->record_arena_size_change(size);
    }
 
@@ -356,7 +357,7 @@
     MallocMemorySummary::record_arena_free(flags);
   }
 
-  static inline void record_arena_size_change(int size, MEMFLAGS flags) {
+  static inline void record_arena_size_change(ssize_t size, MEMFLAGS flags) {
     MallocMemorySummary::record_arena_size_change(size, flags);
   }
  private:
--- a/src/share/vm/services/management.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/services/management.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, 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
@@ -1249,8 +1249,12 @@
 //    ids - array of thread IDs; NULL indicates all live threads
 //    locked_monitors - if true, dump locked object monitors
 //    locked_synchronizers - if true, dump locked JSR-166 synchronizers
+//    maxDepth - the maximum depth of stack traces to be dumped:
+//               maxDepth == -1 requests to dump entire stack trace.
+//               maxDepth == 0  requests no stack trace.
 //
-JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboolean locked_monitors, jboolean locked_synchronizers))
+JVM_ENTRY(jobjectArray, jmm_DumpThreadsMaxDepth(JNIEnv *env, jlongArray thread_ids, jboolean locked_monitors,
+                                                jboolean locked_synchronizers, jint maxDepth))
   ResourceMark rm(THREAD);
 
   if (JDK_Version::is_gte_jdk16x_version()) {
@@ -1273,14 +1277,14 @@
     do_thread_dump(&dump_result,
                    ids_ah,
                    num_threads,
-                   -1, /* entire stack */
+                   maxDepth, /* stack depth */
                    (locked_monitors ? true : false),      /* with locked monitors */
                    (locked_synchronizers ? true : false), /* with locked synchronizers */
                    CHECK_NULL);
   } else {
     // obtain thread dump of all threads
     VM_ThreadDump op(&dump_result,
-                     -1, /* entire stack */
+                     maxDepth, /* stack depth */
                      (locked_monitors ? true : false),     /* with locked monitors */
                      (locked_synchronizers ? true : false) /* with locked synchronizers */);
     VMThread::execute(&op);
@@ -1386,6 +1390,25 @@
   return (jobjectArray) JNIHandles::make_local(env, result_h());
 JVM_END
 
+// Dump thread info for the specified threads.
+// It returns an array of ThreadInfo objects. Each element is the ThreadInfo
+// for the thread ID specified in the corresponding entry in
+// the given array of thread IDs; or NULL if the thread does not exist
+// or has terminated.
+//
+// Input parameter:
+//    ids - array of thread IDs; NULL indicates all live threads
+//    locked_monitors - if true, dump locked object monitors
+//    locked_synchronizers - if true, dump locked JSR-166 synchronizers
+//
+// This method exists only for compatbility with compiled binaries that call it.
+// The JDK library uses jmm_DumpThreadsMaxDepth.
+//
+JVM_ENTRY(jobjectArray, jmm_DumpThreads(JNIEnv *env, jlongArray thread_ids, jboolean locked_monitors,
+                                        jboolean locked_synchronizers))
+  return jmm_DumpThreadsMaxDepth(env, thread_ids, locked_monitors, locked_synchronizers, INT_MAX);
+JVM_END
+
 // Returns an array of Class objects.
 JVM_ENTRY(jobjectArray, jmm_GetLoadedClasses(JNIEnv *env))
   ResourceMark rm(THREAD);
@@ -2209,6 +2232,31 @@
 }
 #endif // INCLUDE_MANAGEMENT
 
+// Gets the amount of memory allocated on the Java heap for a single thread.
+// Returns -1 if the thread does not exist or has terminated.
+JVM_ENTRY(jlong, jmm_GetOneThreadAllocatedMemory(JNIEnv *env, jlong thread_id))
+  if (thread_id < 0) {
+    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(),
+               "Invalid thread ID", -1);
+  }
+
+  if (thread_id == 0) {
+    // current thread
+    if (THREAD->is_Java_thread()) {
+      return ((JavaThread*)THREAD)->cooked_allocated_bytes();
+    }
+    return -1;
+  }
+
+  MutexLockerEx ml(Threads_lock);
+  JavaThread* java_thread = Threads::find_java_thread_from_java_tid(thread_id);
+
+  if (java_thread != NULL) {
+    return java_thread->cooked_allocated_bytes();
+  }
+  return -1;
+JVM_END
+
 // Gets an array containing the amount of memory allocated on the Java
 // heap for a set of threads (in bytes).  Each element of the array is
 // the amount of memory allocated for the thread ID specified in the
@@ -2325,7 +2373,7 @@
 #if INCLUDE_MANAGEMENT
 const struct jmmInterface_1_ jmm_interface = {
   NULL,
-  NULL,
+  jmm_GetOneThreadAllocatedMemory,
   jmm_GetVersion,
   jmm_GetOptionalSupport,
   jmm_GetInputArguments,
@@ -2357,7 +2405,7 @@
   jmm_DumpHeap0,
   jmm_FindDeadlockedThreads,
   jmm_SetVMGlobal,
-  NULL,
+  jmm_DumpThreadsMaxDepth,
   jmm_DumpThreads,
   jmm_SetGCNotificationEnabled,
   jmm_GetDiagnosticCommands,
--- a/src/share/vm/services/memTracker.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/services/memTracker.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -57,7 +57,7 @@
 
   static inline void record_new_arena(MEMFLAGS flag) { }
   static inline void record_arena_free(MEMFLAGS flag) { }
-  static inline void record_arena_size_change(int diff, MEMFLAGS flag) { }
+  static inline void record_arena_size_change(ssize_t diff, MEMFLAGS flag) { }
   static inline void record_virtual_memory_reserve(void* addr, size_t size, const NativeCallStack& stack,
                        MEMFLAGS flag = mtNone) { }
   static inline void record_virtual_memory_reserve_and_commit(void* addr, size_t size,
@@ -190,7 +190,7 @@
 
   // Record arena size change. Arena size is the size of all arena
   // chuncks that backing up the arena.
-  static inline void record_arena_size_change(int diff, MEMFLAGS flag) {
+  static inline void record_arena_size_change(ssize_t diff, MEMFLAGS flag) {
     if (tracking_level() < NMT_summary) return;
     MallocTracker::record_arena_size_change(diff, flag);
   }
--- a/src/share/vm/services/threadService.cpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/services/threadService.cpp	Wed Feb 03 05:23:32 2021 +0000
@@ -562,6 +562,10 @@
     vframe* start_vf = _thread->last_java_vframe(&reg_map);
     int count = 0;
     for (vframe* f = start_vf; f; f = f->sender() ) {
+      if (maxDepth >= 0 && count == maxDepth) {
+        // Skip frames if more than maxDepth
+        break;
+      }
       if (f->is_java_frame()) {
         javaVFrame* jvf = javaVFrame::cast(f);
         add_stack_frame(jvf);
@@ -569,10 +573,6 @@
       } else {
         // Ignore non-Java frames
       }
-      if (maxDepth > 0 && count == maxDepth) {
-        // Skip frames if more than maxDepth
-        break;
-      }
     }
   }
 
--- a/src/share/vm/utilities/taskqueue.hpp	Tue Jan 19 17:18:24 2021 +0000
+++ b/src/share/vm/utilities/taskqueue.hpp	Wed Feb 03 05:23:32 2021 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
+#include "memory/padded.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/orderAccess.inline.hpp"
 #include "utilities/globalDefinitions.hpp"
@@ -112,9 +113,6 @@
   // Internal type for indexing the queue; also used for the tag.
   typedef NOT_LP64(uint16_t) LP64_ONLY(uint32_t) idx_t;
 
-  // The first free element after the last one pushed (mod N).
-  volatile uint _bottom;
-
   enum { MOD_N_MASK = N - 1 };
 
   class Age {
@@ -154,6 +152,10 @@
     };
   };
 
+  // The first free element after the last one pushed (mod N).
+  volatile uint _bottom;
+  // Add paddings to reduce false-sharing cache contention between _bottom and _age
+  DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE, sizeof(uint));
   volatile Age _age;
 
   // These both operate mod N.
--- a/test/compiler/5091921/Test7005594.sh	Tue Jan 19 17:18:24 2021 +0000
+++ b/test/compiler/5091921/Test7005594.sh	Wed Feb 03 05:23:32 2021 +0000
@@ -78,7 +78,7 @@
 
 ${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} -d . Test7005594.java
 
-${TESTJAVA}/bin/java ${TESTVMOPTS} -Xms1600m -XX:+IgnoreUnrecognizedVMOptions -XX:-ZapUnusedHeapArea -Xcomp -XX:CompileOnly=Test7005594.test Test7005594 > test.out 2>&1
+${TESTJAVA}/bin/java ${TESTVMOPTS} -Xmx1600m -Xms1600m -XX:+IgnoreUnrecognizedVMOptions -XX:-ZapUnusedHeapArea -Xcomp -XX:CompileOnly=Test7005594.test Test7005594 > test.out 2>&1
 
 result=$?
 
@@ -97,7 +97,7 @@
 fi
 
 # The test should pass when no enough space for object heap
-grep "Could not reserve enough space for object heap" test.out
+grep "Could not reserve enough space for .*object heap" test.out
 if [ $? = 0 ]
 then
   echo "Passed"
--- a/test/compiler/membars/DekkerTest.java	Tue Jan 19 17:18:24 2021 +0000
+++ b/test/compiler/membars/DekkerTest.java	Wed Feb 03 05:23:32 2021 +0000
@@ -25,9 +25,15 @@
  * @test
  * @bug 8007898
  * @summary Incorrect optimization of Memory Barriers in Matcher::post_store_load_barrier().
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
- * @run main/othervm -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:CICompilerCount=1 -XX:-TieredCompilation -XX:+StressGCM -XX:+StressLCM DekkerTest
+ * @run main/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions
+ *      -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM
+ *      DekkerTest
+ * @run main/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions
+ *      -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM
+ *      DekkerTest
+ * @run main/othervm -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions
+ *      -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+StressGCM -XX:+StressLCM
+ *      DekkerTest
  * @author Martin Doerr martin DOT doerr AT sap DOT com
  *
  * Run 3 times since the failure is intermittent.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/ClassFile/BadHelloWorld.jcod	Wed Feb 03 05:23:32 2021 +0000
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This file fuzzes the class name #15 to have a leading 'L' and ending ';'.
+ */
+
+class BadHelloWorld {
+  0xCAFEBABE;
+  0; // minor version
+  52; // version
+  [31] { // Constant Pool
+    ; // first element is empty
+    Utf8 "BadHelloWorld"; // #1     at 0x0A
+    class #1; // #2     at 0x1A
+    Utf8 "java/lang/Object"; // #3     at 0x1D
+    class #3; // #4     at 0x30
+    Utf8 "<init>"; // #5     at 0x33
+    Utf8 "()V"; // #6     at 0x3C
+    NameAndType #5 #6; // #7     at 0x42
+    Method #4 #7; // #8     at 0x47
+    Utf8 "toString"; // #9     at 0x4C
+    Utf8 "()Ljava/lang/String;"; // #10     at 0x57
+    Utf8 "Hello, world!"; // #11     at 0x6E
+    String #11; // #12     at 0x7E
+    Utf8 "main"; // #13     at 0x81
+    Utf8 "([Ljava/lang/String;)V"; // #14     at 0x88
+    Utf8 "LBadHelloWorld;"; // #15     at 0xA1
+    class #15; // #16     at 0xB3
+    Method #16 #7; // #17     at 0xB6
+    Utf8 "java/lang/System"; // #18     at 0xBB
+    class #18; // #19     at 0xCE
+    Utf8 "out"; // #20     at 0xD1
+    Utf8 "Ljava/io/PrintStream;"; // #21     at 0xD7
+    NameAndType #20 #21; // #22     at 0xEF
+    Field #19 #22; // #23     at 0xF4
+    Utf8 "java/io/PrintStream"; // #24     at 0xF9
+    class #24; // #25     at 0x010F
+    Utf8 "println"; // #26     at 0x0112
+    Utf8 "(Ljava/lang/Object;)V"; // #27     at 0x011C
+    NameAndType #26 #27; // #28     at 0x0134
+    Method #25 #28; // #29     at 0x0139
+    Utf8 "Code"; // #30     at 0x013E
+  } // Constant Pool
+
+  0x0021; // access
+  #2;// this_cpx
+  #4;// super_cpx
+
+  [0] { // Interfaces
+  } // Interfaces
+
+  [0] { // fields
+  } // fields
+
+  [3] { // methods
+    { // Member at 0x0151
+      0x0001; // access
+      #5; // name_cpx
+      #6; // sig_cpx
+      [1] { // Attributes
+        Attr(#30, 17) { // Code at 0x0159
+          1; // max_stack
+          1; // max_locals
+          Bytes[5]{
+            0x2AB70008B1;
+          };
+          [0] { // Traps
+          } // end Traps
+          [0] { // Attributes
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+    ;
+    { // Member at 0x0170
+      0x0001; // access
+      #9; // name_cpx
+      #10; // sig_cpx
+      [1] { // Attributes
+        Attr(#30, 15) { // Code at 0x0178
+          1; // max_stack
+          1; // max_locals
+          Bytes[3]{
+            0x120CB0;
+          };
+          [0] { // Traps
+          } // end Traps
+          [0] { // Attributes
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+    ;
+    { // Member at 0x018D
+      0x0089; // access
+      #13; // name_cpx
+      #14; // sig_cpx
+      [1] { // Attributes
+        Attr(#30, 28) { // Code at 0x0195
+          2; // max_stack
+          2; // max_locals
+          Bytes[16]{
+            0xBB001059B700114C;
+            0xB200172BB6001DB1;
+          };
+          [0] { // Traps
+          } // end Traps
+          [0] { // Attributes
+          } // Attributes
+        } // end Code
+      } // Attributes
+    } // Member
+  } // methods
+
+  [0] { // Attributes
+  } // Attributes
+} // end class BadHelloWorld
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/ClassFile/FormatCheckingTest.java	Wed Feb 03 05:23:32 2021 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8148854
+ * @summary Ensure class name loaded by app class loader is format checked by default
+ * @library /testlibrary
+ * @compile BadHelloWorld.jcod
+ * @run main FormatCheckingTest
+ */
+
+import com.oracle.java.testlibrary.OutputAnalyzer;
+import com.oracle.java.testlibrary.ProcessTools;
+
+public class FormatCheckingTest {
+    public static void main(String args[]) throws Throwable {
+        ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("BadHelloWorld");
+        OutputAnalyzer output = new OutputAnalyzer(pb.start());
+        output.shouldContain("java.lang.ClassFormatError: Illegal class name");
+        output.shouldHaveExitValue(1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/runtime/NMT/HugeArenaTracking.java	Wed Feb 03 05:23:32 2021 +0000
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2019, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test
+ * @key nmt jcmd
+ * @library /testlibrary /testlibrary/whitebox
+ * @build HugeArenaTracking
+ * @run main ClassFileInstaller sun.hotspot.WhiteBox
+ * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -XX:NativeMemoryTracking=detail HugeArenaTracking
+ */
+
+import java.util.Random;
+import com.oracle.java.testlibrary.*;
+import sun.hotspot.WhiteBox;
+
+public class HugeArenaTracking {
+  private static final long GB = 1024 * 1024 * 1024;
+
+  public static void main(String args[]) throws Exception {
+    OutputAnalyzer output;
+    final WhiteBox wb = WhiteBox.getWhiteBox();
+
+    // Grab my own PID
+    String pid = Long.toString(ProcessTools.getProcessId());
+    ProcessBuilder pb = new ProcessBuilder();
+
+    long arena1 = wb.NMTNewArena(1024);
+    long arena2 = wb.NMTNewArena(1024);
+
+    // Run 'jcmd <pid> VM.native_memory summary'
+    pb.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary"});
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Test (reserved=2KB, committed=2KB)");
+
+    Random rand = new Random();
+
+    // Allocate 2GB+ from arena
+    long total = 0;
+    while (total < 2 * GB) {
+      // Cap to 10M
+      long inc = rand.nextInt(10 * 1024 * 1024);
+      wb.NMTArenaMalloc(arena1, inc);
+      total += inc;
+    }
+
+    ProcessBuilder pb2 = new ProcessBuilder();
+    // Run 'jcmd <pid> VM.native_memory summary'
+    pb2.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "VM.native_memory", "summary", "scale=GB"});
+    output = new OutputAnalyzer(pb2.start());
+    output.shouldContain("Test (reserved=2GB, committed=2GB)");
+
+    wb.NMTFreeArena(arena1);
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldContain("Test (reserved=1KB, committed=1KB)");
+    wb.NMTFreeArena(arena2);
+
+    output = new OutputAnalyzer(pb.start());
+    output.shouldNotContain("Test (reserved");
+  }
+}
--- a/test/runtime/containers/docker/DockerBasicTest.java	Tue Jan 19 17:18:24 2021 +0000
+++ b/test/runtime/containers/docker/DockerBasicTest.java	Wed Feb 03 05:23:32 2021 +0000
@@ -37,8 +37,6 @@
 
 public class DockerBasicTest {
     private static final String imageNameAndTag = "jdk8-internal:test";
-    // Diganostics: set to false to examine image after the test
-    private static final boolean removeImageAfterTest = true;
 
     public static void main(String[] args) throws Exception {
         if (!DockerTestUtils.canTestDocker()) {
@@ -50,8 +48,9 @@
             testJavaVersion();
             testHelloDocker();
         } finally {
-            if (removeImageAfterTest)
+            if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) {
                 DockerTestUtils.removeDockerImage(imageNameAndTag);
+            }
         }
     }
 
--- a/test/runtime/containers/docker/Dockerfile-BasicTest	Tue Jan 19 17:18:24 2021 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-FROM oraclelinux:7.6
-MAINTAINER mikhailo.seledtsov@oracle.com
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/runtime/containers/docker/Dockerfile-BasicTest-aarch64	Tue Jan 19 17:18:24 2021 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-# Use generic ubuntu Linux on AArch64
-FROM aarch64/ubuntu
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/runtime/containers/docker/Dockerfile-BasicTest-ppc64le	Tue Jan 19 17:18:24 2021 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-# test on x86_64 uses Oracle Linux but we do not have this for ppc64le
-# so use some other Linux where OpenJDK works 
-# FROM oraclelinux:7.2
-FROM ppc64le/ubuntu
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/runtime/containers/docker/Dockerfile-BasicTest-s390x	Tue Jan 19 17:18:24 2021 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-FROM s390x/ubuntu
-
-COPY /jdk /jdk
-
-ENV JAVA_HOME=/jdk
-
-CMD ["/bin/bash"]
--- a/test/testlibrary/com/oracle/java/testlibrary/DockerTestUtils.java	Tue Jan 19 17:18:24 2021 +0000
+++ b/test/testlibrary/com/oracle/java/testlibrary/DockerTestUtils.java	Wed Feb 03 05:23:32 2021 +0000
@@ -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
@@ -25,6 +25,7 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.nio.file.Files;
 import java.nio.file.FileVisitResult;
 import java.nio.file.Path;
@@ -46,8 +47,23 @@
     private static boolean isDockerEngineAvailable = false;
     private static boolean wasDockerEngineChecked = false;
 
-    // Diagnostics: set to true to enable more diagnostic info
-    private static final boolean DEBUG = false;
+    // Use this property to specify docker location on your system.
+    // E.g.: "/usr/local/bin/docker".
+    private static final String DOCKER_COMMAND =
+        System.getProperty("jdk.test.docker.command", "docker");
+
+    // Set this property to true to retain image after test. By default
+    // images are removed after test execution completes.
+    // Retaining the image can be useful for diagnostics and image inspection.
+    // E.g.: start image interactively: docker run -it <IMAGE_NAME>.
+    public static final boolean RETAIN_IMAGE_AFTER_TEST =
+        Boolean.getBoolean("jdk.test.docker.retain.image");
+
+    // Path to a JDK under test.
+    // This may be useful when developing tests on non-Linux platforms.
+    public static final String JDK_UNDER_TEST =
+        System.getProperty("jdk.test.docker.jdk", Utils.TEST_JDK);
+
 
     /**
      * Optimized check of whether the docker engine is available in a given
@@ -95,7 +111,7 @@
      */
     private static boolean isDockerEngineAvailableCheck() throws Exception {
         try {
-            execute("docker", "ps")
+            execute(DOCKER_COMMAND, "ps")
                 .shouldHaveExitValue(0)
                 .shouldContain("CONTAINER")
                 .shouldContain("IMAGE");
@@ -125,13 +141,8 @@
         if (Files.exists(buildDir)) {
             throw new RuntimeException("The docker build directory already exists: " + buildDir);
         }
-        // check for the existance of a platform specific docker file as well
-        String platformSpecificDockerfile = dockerfile + "-" + Platform.getOsArch();
-        if (Files.exists(Paths.get(Utils.TEST_SRC, platformSpecificDockerfile))) {
-          dockerfile = platformSpecificDockerfile;
-        }
 
-        Path jdkSrcDir = Paths.get(Utils.TEST_JDK);
+        Path jdkSrcDir = Paths.get(JDK_UNDER_TEST);
         Path jdkDstDir = buildDir.resolve("jdk");
 
         Files.createDirectories(jdkDstDir);
@@ -156,11 +167,12 @@
      */
     public static void
         buildDockerImage(String imageName, Path dockerfile, Path buildDir) throws Exception {
-        // Copy docker file to the build dir
-        Files.copy(dockerfile, buildDir.resolve("Dockerfile"));
+        generateDockerFile(buildDir.resolve("Dockerfile"),
+                           DockerfileConfig.getBaseImageName(),
+                           DockerfileConfig.getBaseImageVersion());
 
         // Build the docker
-        execute("docker", "build", "--no-cache", "--tag", imageName, buildDir.toString())
+        execute(DOCKER_COMMAND, "build", "--no-cache", "--tag", imageName, buildDir.toString())
             .shouldHaveExitValue(0)
             .shouldContain("Successfully built");
     }
@@ -177,7 +189,7 @@
     public static OutputAnalyzer dockerRunJava(DockerRunOptions opts) throws Exception {
         ArrayList<String> cmd = new ArrayList<>();
 
-        cmd.add("docker");
+        cmd.add(DOCKER_COMMAND);
         cmd.add("run");
         if (opts.tty)
             cmd.add("--tty=true");
@@ -203,11 +215,10 @@
      * Remove docker image
      *
      * @param DockerRunOptions optins for running docker
-     * @return output of the command
      * @throws Exception
      */
-    public static OutputAnalyzer removeDockerImage(String imageNameAndTag) throws Exception {
-        return execute("docker", "rmi", "--force", imageNameAndTag);
+    public static void removeDockerImage(String imageNameAndTag) throws Exception {
+            execute(DOCKER_COMMAND, "rmi", "--force", imageNameAndTag);
     }
 
 
@@ -247,6 +258,18 @@
     }
 
 
+    private static void generateDockerFile(Path dockerfile, String baseImage,
+                                           String baseImageVersion) throws Exception {
+        String template =
+            "FROM %s:%s\n" +
+            "COPY /jdk /jdk\n" +
+            "ENV JAVA_HOME=/jdk\n" +
+            "CMD [\"/bin/bash\"]\n";
+        String dockerFileStr = String.format(template, baseImage, baseImageVersion);
+        Files.write(dockerfile, dockerFileStr.getBytes(StandardCharsets.UTF_8));
+    }
+
+
     private static class CopyFileVisitor extends SimpleFileVisitor<Path> {
         private final Path src;
         private final Path dst;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/com/oracle/java/testlibrary/DockerfileConfig.java	Wed Feb 03 05:23:32 2021 +0000
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.oracle.java.testlibrary;
+
+// Use the following properties to specify docker base image at test execution time:
+// Image name: jdk.test.docker.image.name
+// Image version: jdk.test.docker.image.version
+// Usage:
+//     jtreg -Djdk.test.docker.image.name=<BASE_IMAGE_NAME> -Djdk.test.docker.image.version=<BASE_IMAGE_VERSION> test/hotspot/jtreg/runtime/containers/docker/
+// E.g.:
+//     jtreg -Djdk.test.docker.image.name=ubuntu -Djdk.test.docker.image.version=latest test/hotspot/jtreg/runtime/containers/docker/
+// Using make:
+//     make test TEST="test/hotspot/jtreg/runtime/containers/docker" JTREG="JAVA_OPTIONS=-Djdk.test.docker.image.name=ubuntu -Djdk.test.docker.image.version=latest"
+// Note: base image version should not be an empty string. Use "latest" to get the latest version.
+
+public class DockerfileConfig {
+    static String getBaseImageName() {
+        String name = System.getProperty("jdk.test.docker.image.name");
+        if (name != null) {
+            System.out.println("DockerfileConfig: using custom image name: " + name);
+            return name;
+        }
+
+        switch (Platform.getOsArch()) {
+            case "aarch64":
+                return "aarch64/ubuntu";
+            case "ppc64le":
+                return "ppc64le/ubuntu";
+            case "s390x":
+                return "s390x/ubuntu";
+            default:
+                return "oraclelinux";
+        }
+    }
+
+    static String getBaseImageVersion() {
+        String version = System.getProperty("jdk.test.docker.image.version");
+        if (version != null) {
+            System.out.println("DockerfileConfig: using custom image version: " + version);
+            return version;
+        }
+
+        switch (Platform.getOsArch()) {
+            case "aarch64":
+            case "ppc64le":
+            case "s390x":
+                return "latest";
+            default:
+                return "7.6";
+        }
+    }
+}
--- a/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Tue Jan 19 17:18:24 2021 +0000
+++ b/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java	Wed Feb 03 05:23:32 2021 +0000
@@ -122,6 +122,9 @@
   public native boolean NMTIsDetailSupported();
   public native boolean NMTChangeTrackingLevel();
   public native int NMTGetHashSize();
+  public native long NMTNewArena(long initSize);
+  public native void NMTFreeArena(long arena);
+  public native void NMTArenaMalloc(long arena, long size);
 
   // Compiler
   public native void    deoptimizeAll();