Merge JEP-349-branch
authormgronlun
Tue, 08 Oct 2019 11:57:11 +0200
branchJEP-349-branch
changeset 58495 465ba4fefe62
parent 58485 f40923eeb559 (current diff)
parent 58493 55a8d95c7787 (diff)
child 58498 5a2761a6a564
Merge
src/hotspot/share/runtime/thread.cpp
src/hotspot/share/runtime/thread.hpp
src/java.base/share/native/libjava/verify_stub.c
src/java.base/share/native/libverify/check_format.c
src/java.base/unix/native/libjava/jdk_util_md.c
src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java
test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineDeleteJmethod.java
test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/libRedefineDeleteJmethod.c
--- a/make/gensrc/Gensrc-jdk.internal.vm.compiler.management.gmk	Mon Oct 07 20:15:47 2019 +0200
+++ b/make/gensrc/Gensrc-jdk.internal.vm.compiler.management.gmk	Tue Oct 08 11:57:11 2019 +0200
@@ -73,7 +73,7 @@
 	($(CD) $(GENSRC_DIR)/META-INF/providers && \
 	    p=""; \
 	    impl=""; \
-	    for i in $$($(GREP) '^' * | $(SORT) -t ':' -k 2 | $(SED) 's/:.*//'); do \
+	    for i in $$($(NAWK) '$$0=FILENAME" "$$0' * | $(SORT) -k 2 | $(SED) 's/ .*//'); do \
 	      c=$$($(CAT) $$i | $(TR) -d '\n\r'); \
 	      if test x$$p != x$$c; then \
                 if test x$$p != x; then \
--- a/make/lib/CoreLibraries.gmk	Mon Oct 07 20:15:47 2019 +0200
+++ b/make/lib/CoreLibraries.gmk	Tue Oct 08 11:57:11 2019 +0200
@@ -23,8 +23,6 @@
 # questions.
 #
 
-WIN_VERIFY_LIB := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libverify/verify.lib
-
 # Hook to include the corresponding custom file, if present.
 $(eval $(call IncludeCustomExtension, lib/CoreLibraries.gmk))
 
@@ -110,14 +108,14 @@
     LDFLAGS_macosx := -L$(SUPPORT_OUTPUTDIR)/native/$(MODULE)/, \
     LDFLAGS_windows := -delayload:shell32.dll, \
     LIBS := $(BUILD_LIBFDLIBM_TARGET), \
-    LIBS_unix := -ljvm -lverify, \
+    LIBS_unix := -ljvm, \
     LIBS_linux := $(LIBDL), \
     LIBS_solaris := -lsocket -lnsl -lscf $(LIBDL), \
     LIBS_aix := $(LIBDL) $(LIBM),\
     LIBS_macosx := -framework CoreFoundation \
         -framework Foundation \
         -framework SystemConfiguration, \
-    LIBS_windows := jvm.lib $(WIN_VERIFY_LIB) \
+    LIBS_windows := jvm.lib \
         shell32.lib delayimp.lib \
         advapi32.lib version.lib, \
 ))
--- a/src/hotspot/os/aix/os_aix.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/os/aix/os_aix.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -132,18 +132,6 @@
 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
 
 // excerpts from systemcfg.h that might be missing on older os levels
-#ifndef PV_5_Compat
-  #define PV_5_Compat 0x0F8000   /* Power PC 5 */
-#endif
-#ifndef PV_6
-  #define PV_6 0x100000          /* Power PC 6 */
-#endif
-#ifndef PV_6_1
-  #define PV_6_1 0x100001        /* Power PC 6 DD1.x */
-#endif
-#ifndef PV_6_Compat
-  #define PV_6_Compat 0x108000   /* Power PC 6 */
-#endif
 #ifndef PV_7
   #define PV_7 0x200000          /* Power PC 7 */
 #endif
@@ -156,6 +144,13 @@
 #ifndef PV_8_Compat
   #define PV_8_Compat 0x308000   /* Power PC 8 */
 #endif
+#ifndef PV_9
+  #define PV_9 0x400000          /* Power PC 9 */
+#endif
+#ifndef PV_9_Compat
+  #define PV_9_Compat  0x408000  /* Power PC 9 */
+#endif
+
 
 static address resolve_function_descriptor_to_code_pointer(address p);
 
@@ -1386,15 +1381,7 @@
 void os::print_os_info(outputStream* st) {
   st->print("OS:");
 
-  st->print("uname:");
-  struct utsname name;
-  uname(&name);
-  st->print(name.sysname); st->print(" ");
-  st->print(name.nodename); st->print(" ");
-  st->print(name.release); st->print(" ");
-  st->print(name.version); st->print(" ");
-  st->print(name.machine);
-  st->cr();
+  os::Posix::print_uname_info(st);
 
   uint32_t ver = os::Aix::os_version();
   st->print_cr("AIX kernel version %u.%u.%u.%u",
@@ -1402,16 +1389,12 @@
 
   os::Posix::print_rlimit_info(st);
 
+  os::Posix::print_load_average(st);
+
   // _SC_THREAD_THREADS_MAX is the maximum number of threads within a process.
   long tmax = sysconf(_SC_THREAD_THREADS_MAX);
   st->print_cr("maximum #threads within a process:%ld", tmax);
 
-  // load average
-  st->print("load average:");
-  double loadavg[3] = {-1.L, -1.L, -1.L};
-  os::loadavg(loadavg, 3);
-  st->print_cr("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
-
   // print wpar info
   libperfstat::wparinfo_t wi;
   if (libperfstat::get_wparinfo(&wi)) {
@@ -1504,6 +1487,9 @@
 void os::get_summary_cpu_info(char* buf, size_t buflen) {
   // read _system_configuration.version
   switch (_system_configuration.version) {
+  case PV_9:
+    strncpy(buf, "Power PC 9", buflen);
+    break;
   case PV_8:
     strncpy(buf, "Power PC 8", buflen);
     break;
@@ -1537,6 +1523,9 @@
   case PV_8_Compat:
     strncpy(buf, "PV_8_Compat", buflen);
     break;
+  case PV_9_Compat:
+    strncpy(buf, "PV_9_Compat", buflen);
+    break;
   default:
     strncpy(buf, "unknown", buflen);
   }
--- a/src/hotspot/os/posix/os_posix.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/os/posix/os_posix.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -373,8 +373,12 @@
 void os::Posix::print_load_average(outputStream* st) {
   st->print("load average:");
   double loadavg[3];
-  os::loadavg(loadavg, 3);
-  st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
+  int res = os::loadavg(loadavg, 3);
+  if (res != -1) {
+    st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
+  } else {
+    st->print(" Unavailable");
+  }
   st->cr();
 }
 
--- a/src/hotspot/share/classfile/classLoader.hpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/classfile/classLoader.hpp	Tue Oct 08 11:57:11 2019 +0200
@@ -237,6 +237,8 @@
   CDS_ONLY(static ClassPathEntry* app_classpath_entries() {return _app_classpath_entries;})
   CDS_ONLY(static ClassPathEntry* module_path_entries() {return _module_path_entries;})
 
+  static bool has_bootclasspath_append() { return _first_append_entry != NULL; }
+
  protected:
   // Initialization:
   //   - setup the boot loader's system class path
--- a/src/hotspot/share/classfile/javaClasses.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/classfile/javaClasses.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -377,7 +377,7 @@
 
   if (_to_java_string_fn == NULL) {
     void *lib_handle = os::native_java_library();
-    _to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "NewStringPlatform"));
+    _to_java_string_fn = CAST_TO_FN_PTR(to_java_string_fn_t, os::dll_lookup(lib_handle, "JNU_NewStringPlatform"));
     if (_to_java_string_fn == NULL) {
       fatal("NewStringPlatform missing");
     }
--- a/src/hotspot/share/classfile/systemDictionary.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/classfile/systemDictionary.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -1432,6 +1432,11 @@
         // a named package within the unnamed module.  In all cases,
         // limit visibility to search for the class only in the boot
         // loader's append path.
+        if (!ClassLoader::has_bootclasspath_append()) {
+           // If there is no bootclasspath append entry, no need to continue
+           // searching.
+           return NULL;
+        }
         search_only_bootloader_append = true;
       }
     }
--- a/src/hotspot/share/classfile/verifier.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/classfile/verifier.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -63,29 +63,39 @@
 #define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION       52
 #define MAX_ARRAY_DIMENSIONS 255
 
-// Access to external entry for VerifyClassCodes - old byte code verifier
+// Access to external entry for VerifyClassForMajorVersion - old byte code verifier
 
 extern "C" {
-  typedef jboolean (*verify_byte_codes_fn_t)(JNIEnv *, jclass, char *, jint);
-  typedef jboolean (*verify_byte_codes_fn_new_t)(JNIEnv *, jclass, char *, jint, jint);
+  typedef jboolean (*verify_byte_codes_fn_t)(JNIEnv *, jclass, char *, jint, jint);
 }
 
-static void* volatile _verify_byte_codes_fn = NULL;
+static verify_byte_codes_fn_t volatile _verify_byte_codes_fn = NULL;
+
+static verify_byte_codes_fn_t verify_byte_codes_fn() {
 
-static volatile jint _is_new_verify_byte_codes_fn = (jint) true;
+  if (_verify_byte_codes_fn != NULL)
+    return _verify_byte_codes_fn;
+
+  MutexLocker locker(Verify_lock);
+
+  if (_verify_byte_codes_fn != NULL)
+    return _verify_byte_codes_fn;
 
-static void* verify_byte_codes_fn() {
-  if (OrderAccess::load_acquire(&_verify_byte_codes_fn) == NULL) {
-    void *lib_handle = os::native_java_library();
-    void *func = os::dll_lookup(lib_handle, "VerifyClassCodesForMajorVersion");
-    OrderAccess::release_store(&_verify_byte_codes_fn, func);
-    if (func == NULL) {
-      _is_new_verify_byte_codes_fn = false;
-      func = os::dll_lookup(lib_handle, "VerifyClassCodes");
-      OrderAccess::release_store(&_verify_byte_codes_fn, func);
-    }
-  }
-  return (void*)_verify_byte_codes_fn;
+  // Load verify dll
+  char buffer[JVM_MAXPATHLEN];
+  char ebuf[1024];
+  if (!os::dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"))
+    return NULL; // Caller will throw VerifyError
+
+  void *lib_handle = os::dll_load(buffer, ebuf, sizeof(ebuf));
+  if (lib_handle == NULL)
+    return NULL; // Caller will throw VerifyError
+
+  void *fn = os::dll_lookup(lib_handle, "VerifyClassForMajorVersion");
+  if (fn == NULL)
+    return NULL; // Caller will throw VerifyError
+
+  return _verify_byte_codes_fn = CAST_TO_FN_PTR(verify_byte_codes_fn_t, fn);
 }
 
 
@@ -282,7 +292,7 @@
   JavaThread* thread = (JavaThread*)THREAD;
   JNIEnv *env = thread->jni_environment();
 
-  void* verify_func = verify_byte_codes_fn();
+  verify_byte_codes_fn_t verify_func = verify_byte_codes_fn();
 
   if (verify_func == NULL) {
     jio_snprintf(message, message_len, "Could not link verifier");
@@ -301,16 +311,7 @@
     // ThreadToNativeFromVM takes care of changing thread_state, so safepoint
     // code knows that we have left the VM
 
-    if (_is_new_verify_byte_codes_fn) {
-      verify_byte_codes_fn_new_t func =
-        CAST_TO_FN_PTR(verify_byte_codes_fn_new_t, verify_func);
-      result = (*func)(env, cls, message, (int)message_len,
-          klass->major_version());
-    } else {
-      verify_byte_codes_fn_t func =
-        CAST_TO_FN_PTR(verify_byte_codes_fn_t, verify_func);
-      result = (*func)(env, cls, message, (int)message_len);
-    }
+    result = (*verify_func)(env, cls, message, (int)message_len, klass->major_version());
   }
 
   JNIHandles::destroy_local(cls);
--- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -69,7 +69,8 @@
   // enough, but we also do not want to steal too much CPU from the concurrently running
   // application. Using 1/4 of available threads for concurrent GC seems a good
   // compromise here.
-  if (FLAG_IS_DEFAULT(ConcGCThreads)) {
+  bool ergo_conc = FLAG_IS_DEFAULT(ConcGCThreads);
+  if (ergo_conc) {
     FLAG_SET_DEFAULT(ConcGCThreads, MAX2(1, os::processor_count() / 4));
   }
 
@@ -82,7 +83,8 @@
   // that will overwhelm the OS scheduler. Using 1/2 of available threads seems to be a fair
   // compromise here. Due to implementation constraints, it should not be lower than
   // the number of concurrent threads.
-  if (FLAG_IS_DEFAULT(ParallelGCThreads)) {
+  bool ergo_parallel = FLAG_IS_DEFAULT(ParallelGCThreads);
+  if (ergo_parallel) {
     FLAG_SET_DEFAULT(ParallelGCThreads, MAX2(1, os::processor_count() / 2));
   }
 
@@ -90,9 +92,21 @@
     vm_exit_during_initialization("Shenandoah expects ParallelGCThreads > 0, check -XX:ParallelGCThreads=#");
   }
 
+  // Make sure ergonomic decisions do not break the thread count invariants.
+  // This may happen when user overrides one of the flags, but not the other.
+  // When that happens, we want to adjust the setting that was set ergonomically.
   if (ParallelGCThreads < ConcGCThreads) {
-    warning("Shenandoah expects ConcGCThreads <= ParallelGCThreads, adjusting ParallelGCThreads automatically");
-    FLAG_SET_DEFAULT(ParallelGCThreads, ConcGCThreads);
+    if (ergo_conc && !ergo_parallel) {
+      FLAG_SET_DEFAULT(ConcGCThreads, ParallelGCThreads);
+    } else if (!ergo_conc && ergo_parallel) {
+      FLAG_SET_DEFAULT(ParallelGCThreads, ConcGCThreads);
+    } else if (ergo_conc && ergo_parallel) {
+      // Should not happen, check the ergonomic computation above. Fail with relevant error.
+      vm_exit_during_initialization("Shenandoah thread count ergonomic error");
+    } else {
+      // User settings error, report and ask user to rectify.
+      vm_exit_during_initialization("Shenandoah expects ConcGCThreads <= ParallelGCThreads, check -XX:ParallelGCThreads, -XX:ConcGCThreads");
+    }
   }
 
   if (FLAG_IS_DEFAULT(ParallelRefProcEnabled)) {
--- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp	Tue Oct 08 11:57:11 2019 +0200
@@ -314,9 +314,6 @@
   diagnostic(bool, ShenandoahTerminationTrace, false,                       \
           "Tracing task termination timings")                               \
                                                                             \
-  develop(bool, ShenandoahVerifyObjectEquals, false,                        \
-          "Verify that == and != are not used on oops. Only in fastdebug")  \
-                                                                            \
   diagnostic(bool, ShenandoahAlwaysPreTouch, false,                         \
           "Pre-touch heap memory, overrides global AlwaysPreTouch")         \
                                                                             \
--- a/src/hotspot/share/include/jvm.h	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/include/jvm.h	Tue Oct 08 11:57:11 2019 +0200
@@ -1044,19 +1044,6 @@
 #include "classfile_constants.h"
 
 /*
- * A function defined by the byte-code verifier and called by the VM.
- * This is not a function implemented in the VM.
- *
- * Returns JNI_FALSE if verification fails. A detailed error message
- * will be places in msg_buf, whose length is specified by buf_len.
- */
-typedef jboolean (*verifier_fn_t)(JNIEnv *env,
-                                  jclass cb,
-                                  char * msg_buf,
-                                  jint buf_len);
-
-
-/*
  * Support for a VM-independent class format checker.
  */
 typedef struct {
@@ -1086,28 +1073,6 @@
 
 typedef jstring (*to_java_string_fn_t)(JNIEnv *env, char *str);
 
-typedef char *(*to_c_string_fn_t)(JNIEnv *env, jstring s, jboolean *b);
-
-/* This is the function defined in libjava.so that performs class
- * format checks. This functions fills in size information about
- * the class file and returns:
- *
- *   0: good
- *  -1: out of memory
- *  -2: bad format
- *  -3: unsupported version
- *  -4: bad class name
- */
-
-typedef jint (*check_format_fn_t)(char *class_name,
-                                  unsigned char *data,
-                                  unsigned int data_size,
-                                  class_size_info *class_size,
-                                  char *message_buffer,
-                                  jint buffer_length,
-                                  jboolean measure_only,
-                                  jboolean check_relaxed);
-
 #define JVM_RECOGNIZED_CLASS_MODIFIERS (JVM_ACC_PUBLIC | \
                                         JVM_ACC_FINAL | \
                                         JVM_ACC_SUPER | \
--- a/src/hotspot/share/prims/jniCheck.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jniCheck.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -448,16 +448,16 @@
 Method* jniCheck::validate_jmethod_id(JavaThread* thr, jmethodID method_id) {
   ASSERT_OOPS_ALLOWED;
   // do the fast jmethodID check first
-  Method* moop = Method::checked_resolve_jmethod_id(method_id);
-  if (moop == NULL) {
+  Method* m = Method::checked_resolve_jmethod_id(method_id);
+  if (m == NULL) {
     ReportJNIFatalError(thr, fatal_wrong_class_or_method);
   }
-  // jmethodIDs are supposed to be weak handles in the class loader data,
+  // jmethodIDs are handles in the class loader data,
   // but that can be expensive so check it last
   else if (!Method::is_method_id(method_id)) {
     ReportJNIFatalError(thr, fatal_non_weak_method);
   }
-  return moop;
+  return m;
 }
 
 
@@ -518,18 +518,29 @@
   }
 }
 
-void jniCheck::validate_call_object(JavaThread* thr, jobject obj, jmethodID method_id) {
-  /* validate the object being passed */
+void jniCheck::validate_call(JavaThread* thr, jclass clazz, jmethodID method_id, jobject obj) {
   ASSERT_OOPS_ALLOWED;
-  jniCheck::validate_jmethod_id(thr, method_id);
-  jniCheck::validate_object(thr, obj);
-}
+  Method* m = jniCheck::validate_jmethod_id(thr, method_id);
+  InstanceKlass* holder = m->method_holder();
+
+  if (clazz != NULL) {
+    Klass* k = jniCheck::validate_class(thr, clazz, false);
+    // Check that method is in the class, must be InstanceKlass
+    if (!InstanceKlass::cast(k)->is_subtype_of(holder)) {
+      ReportJNIFatalError(thr, fatal_wrong_class_or_method);
+    }
+  }
 
-void jniCheck::validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id) {
-  /* validate the class being passed */
-  ASSERT_OOPS_ALLOWED;
-  jniCheck::validate_jmethod_id(thr, method_id);
-  jniCheck::validate_class(thr, clazz, false);
+  if (obj != NULL) {
+    oop recv = jniCheck::validate_object(thr, obj);
+    assert(recv != NULL, "validate_object checks that");
+    Klass* ik = recv->klass();
+
+    // Check that the object is a subtype of method holder too.
+    if (!InstanceKlass::cast(ik)->is_subtype_of(holder)) {
+      ReportJNIFatalError(thr, fatal_wrong_class_or_method);
+    }
+  }
 }
 
 
@@ -595,8 +606,7 @@
                                 jboolean isStatic))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_class(thr, cls, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     jobject result = UNCHECKED()->ToReflectedMethod(env, cls, methodID,
                                                     isStatic);
@@ -852,8 +862,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_class(thr, clazz, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, clazz, methodID);
     )
     va_start(args, methodID);
     jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
@@ -869,8 +878,7 @@
                          va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_class(thr, clazz, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, clazz, methodID);
     )
     jobject result = UNCHECKED()->NewObjectV(env,clazz,methodID,args);
     functionExit(thr);
@@ -884,8 +892,7 @@
                          const jvalue *args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_class(thr, clazz, false);
-      jniCheck::validate_jmethod_id(thr, methodID);
+      jniCheck::validate_call(thr, clazz, methodID);
     )
     jobject result = UNCHECKED()->NewObjectA(env,clazz,methodID,args);
     functionExit(thr);
@@ -941,7 +948,7 @@
     functionEnter(thr); \
     va_list args; \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
+      jniCheck::validate_call(thr, NULL, methodID, obj); \
     ) \
     va_start(args,methodID); \
     ResultType result =UNCHECKED()->Call##Result##MethodV(env, obj, methodID, \
@@ -959,7 +966,7 @@
                                     va_list args)) \
     functionEnter(thr); \
     IN_VM(\
-      jniCheck::validate_call_object(thr, obj, methodID); \
+      jniCheck::validate_call(thr, NULL, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->Call##Result##MethodV(env, obj, methodID,\
                                                            args); \
@@ -975,7 +982,7 @@
                                     const jvalue * args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
+      jniCheck::validate_call(thr, NULL, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->Call##Result##MethodA(env, obj, methodID,\
                                                            args); \
@@ -1002,7 +1009,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
+      jniCheck::validate_call(thr, NULL, methodID, obj);
     )
     va_start(args,methodID);
     UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
@@ -1018,7 +1025,7 @@
                               va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
+      jniCheck::validate_call(thr, NULL, methodID, obj);
     )
     UNCHECKED()->CallVoidMethodV(env,obj,methodID,args);
     thr->set_pending_jni_exception_check("CallVoidMethodV");
@@ -1032,7 +1039,7 @@
                               const jvalue * args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
+      jniCheck::validate_call(thr, NULL, methodID, obj);
     )
     UNCHECKED()->CallVoidMethodA(env,obj,methodID,args);
     thr->set_pending_jni_exception_check("CallVoidMethodA");
@@ -1049,8 +1056,7 @@
     functionEnter(thr); \
     va_list args; \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
-      jniCheck::validate_call_class(thr, clazz, methodID); \
+      jniCheck::validate_call(thr, clazz, methodID, obj); \
     ) \
     va_start(args,methodID); \
     ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \
@@ -1072,8 +1078,7 @@
                                               va_list args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
-      jniCheck::validate_call_class(thr, clazz, methodID); \
+      jniCheck::validate_call(thr, clazz, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodV(env, \
                                                                      obj, \
@@ -1093,8 +1098,7 @@
                                               const jvalue * args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_call_object(thr, obj, methodID); \
-      jniCheck::validate_call_class(thr, clazz, methodID); \
+      jniCheck::validate_call(thr, clazz, methodID, obj); \
     ) \
     ResultType result = UNCHECKED()->CallNonvirtual##Result##MethodA(env, \
                                                                      obj, \
@@ -1125,8 +1129,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
-      jniCheck::validate_call_class(thr, clazz, methodID);
+      jniCheck::validate_call(thr, clazz, methodID, obj);
     )
     va_start(args,methodID);
     UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
@@ -1143,8 +1146,7 @@
                                         va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
-      jniCheck::validate_call_class(thr, clazz, methodID);
+      jniCheck::validate_call(thr, clazz, methodID, obj);
     )
     UNCHECKED()->CallNonvirtualVoidMethodV(env,obj,clazz,methodID,args);
     thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodV");
@@ -1159,8 +1161,7 @@
                                         const jvalue * args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_call_object(thr, obj, methodID);
-      jniCheck::validate_call_class(thr, clazz, methodID);
+      jniCheck::validate_call(thr, clazz, methodID, obj);
     )
     UNCHECKED()->CallNonvirtualVoidMethodA(env,obj,clazz,methodID,args);
     thr->set_pending_jni_exception_check("CallNonvirtualVoidMethodA");
@@ -1253,8 +1254,7 @@
     functionEnter(thr); \
     va_list args; \
     IN_VM( \
-      jniCheck::validate_jmethod_id(thr, methodID); \
-      jniCheck::validate_class(thr, clazz, false); \
+      jniCheck::validate_call(thr, clazz, methodID); \
     ) \
     va_start(args,methodID); \
     ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \
@@ -1274,8 +1274,7 @@
                                           va_list args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_jmethod_id(thr, methodID); \
-      jniCheck::validate_class(thr, clazz, false); \
+      jniCheck::validate_call(thr, clazz, methodID); \
     ) \
     ReturnType result = UNCHECKED()->CallStatic##Result##MethodV(env, \
                                                                  clazz, \
@@ -1293,8 +1292,7 @@
                                           const jvalue *args)) \
     functionEnter(thr); \
     IN_VM( \
-      jniCheck::validate_jmethod_id(thr, methodID); \
-      jniCheck::validate_class(thr, clazz, false); \
+      jniCheck::validate_call(thr, clazz, methodID); \
     ) \
     ReturnType result = UNCHECKED()->CallStatic##Result##MethodA(env, \
                                                                  clazz, \
@@ -1323,8 +1321,7 @@
     functionEnter(thr);
     va_list args;
     IN_VM(
-      jniCheck::validate_jmethod_id(thr, methodID);
-      jniCheck::validate_class(thr, cls, false);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     va_start(args,methodID);
     UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
@@ -1340,8 +1337,7 @@
                                     va_list args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_jmethod_id(thr, methodID);
-      jniCheck::validate_class(thr, cls, false);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     UNCHECKED()->CallStaticVoidMethodV(env,cls,methodID,args);
     thr->set_pending_jni_exception_check("CallStaticVoidMethodV");
@@ -1355,8 +1351,7 @@
                                     const jvalue * args))
     functionEnter(thr);
     IN_VM(
-      jniCheck::validate_jmethod_id(thr, methodID);
-      jniCheck::validate_class(thr, cls, false);
+      jniCheck::validate_call(thr, cls, methodID);
     )
     UNCHECKED()->CallStaticVoidMethodA(env,cls,methodID,args);
     thr->set_pending_jni_exception_check("CallStaticVoidMethodA");
--- a/src/hotspot/share/prims/jniCheck.hpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jniCheck.hpp	Tue Oct 08 11:57:11 2019 +0200
@@ -51,8 +51,7 @@
   static Klass* validate_class(JavaThread* thr, jclass clazz, bool allow_primitive = false);
   static void validate_class_descriptor(JavaThread* thr, const char* name);
   static void validate_throwable_klass(JavaThread* thr, Klass* klass);
-  static void validate_call_object(JavaThread* thr, jobject obj, jmethodID method_id);
-  static void validate_call_class(JavaThread* thr, jclass clazz, jmethodID method_id);
+  static void validate_call(JavaThread* thr, jclass clazz, jmethodID method_id, jobject obj = NULL);
   static Method* validate_jmethod_id(JavaThread* thr, jmethodID method_id);
 };
 
--- a/src/hotspot/share/prims/jvmtiEnv.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiEnv.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -3229,23 +3229,23 @@
 jvmtiError
 JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {
   if (Threads::number_of_threads() == 0) {
-    // Remove this  monitor from pending raw monitors list
+    // Remove this monitor from pending raw monitors list
     // if it has entered in onload or start phase.
     JvmtiPendingMonitors::destroy(rmonitor);
   } else {
     Thread* thread  = Thread::current();
-    if (rmonitor->is_entered(thread)) {
+    if (rmonitor->owner() == thread) {
       // The caller owns this monitor which we are about to destroy.
       // We exit the underlying synchronization object so that the
       // "delete monitor" call below can work without an assertion
       // failure on systems that don't like destroying synchronization
       // objects that are locked.
       int r;
-      intptr_t recursion = rmonitor->recursions();
-      for (intptr_t i = 0; i <= recursion; i++) {
+      int recursion = rmonitor->recursions();
+      for (int i = 0; i <= recursion; i++) {
         r = rmonitor->raw_exit(thread);
-        assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked");
-        if (r != ObjectMonitor::OM_OK) {  // robustness
+        assert(r == JvmtiRawMonitor::M_OK, "raw_exit should have worked");
+        if (r != JvmtiRawMonitor::M_OK) {  // robustness
           return JVMTI_ERROR_INTERNAL;
         }
       }
@@ -3271,7 +3271,7 @@
 jvmtiError
 JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {
   if (Threads::number_of_threads() == 0) {
-    // No JavaThreads exist so ObjectMonitor enter cannot be
+    // No JavaThreads exist so JvmtiRawMonitor enter cannot be
     // used, add this raw monitor to the pending list.
     // The pending monitors will be actually entered when
     // the VM is setup.
@@ -3279,20 +3279,10 @@
     // in thread.cpp.
     JvmtiPendingMonitors::enter(rmonitor);
   } else {
-    int r = 0;
     Thread* thread = Thread::current();
-
     if (thread->is_Java_thread()) {
       JavaThread* current_thread = (JavaThread*)thread;
 
-#ifdef PROPER_TRANSITIONS
-      // Not really unknown but ThreadInVMfromNative does more than we want
-      ThreadInVMfromUnknown __tiv;
-      {
-        ThreadBlockInVM __tbivm(current_thread);
-        r = rmonitor->raw_enter(current_thread);
-      }
-#else
       /* Transition to thread_blocked without entering vm state          */
       /* This is really evil. Normally you can't undo _thread_blocked    */
       /* transitions like this because it would cause us to miss a       */
@@ -3308,22 +3298,11 @@
              current_thread->frame_anchor()->walkable(), "Must be walkable");
       current_thread->set_thread_state(_thread_blocked);
 
-      r = rmonitor->raw_enter(current_thread);
+      rmonitor->raw_enter(current_thread);
       // restore state, still at a safepoint safe state
       current_thread->set_thread_state(state);
-
-#endif /* PROPER_TRANSITIONS */
-      assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
     } else {
-      if (thread->is_Named_thread()) {
-        r = rmonitor->raw_enter(thread);
-      } else {
-        ShouldNotReachHere();
-      }
-    }
-
-    if (r != ObjectMonitor::OM_OK) {  // robustness
-      return JVMTI_ERROR_INTERNAL;
+      rmonitor->raw_enter(thread);
     }
   }
   return JVMTI_ERROR_NONE;
@@ -3342,31 +3321,10 @@
       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
     }
   } else {
-    int r = 0;
     Thread* thread = Thread::current();
-
-    if (thread->is_Java_thread()) {
-      JavaThread* current_thread = (JavaThread*)thread;
-#ifdef PROPER_TRANSITIONS
-      // Not really unknown but ThreadInVMfromNative does more than we want
-      ThreadInVMfromUnknown __tiv;
-#endif /* PROPER_TRANSITIONS */
-      r = rmonitor->raw_exit(current_thread);
-    } else {
-      if (thread->is_Named_thread()) {
-        r = rmonitor->raw_exit(thread);
-      } else {
-        ShouldNotReachHere();
-      }
-    }
-
-    if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
+    int r = rmonitor->raw_exit(thread);
+    if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
-    } else {
-      assert(r == ObjectMonitor::OM_OK, "raw_exit should have worked");
-      if (r != ObjectMonitor::OM_OK) {  // robustness
-        err = JVMTI_ERROR_INTERNAL;
-      }
     }
   }
   return err;
@@ -3381,14 +3339,7 @@
 
   if (thread->is_Java_thread()) {
     JavaThread* current_thread = (JavaThread*)thread;
-#ifdef PROPER_TRANSITIONS
-    // Not really unknown but ThreadInVMfromNative does more than we want
-    ThreadInVMfromUnknown __tiv;
-    {
-      ThreadBlockInVM __tbivm(current_thread);
-      r = rmonitor->raw_wait(millis, true, current_thread);
-    }
-#else
+
     /* Transition to thread_blocked without entering vm state          */
     /* This is really evil. Normally you can't undo _thread_blocked    */
     /* transitions like this because it would cause us to miss a       */
@@ -3408,57 +3359,31 @@
     // restore state, still at a safepoint safe state
     current_thread->set_thread_state(state);
 
-#endif /* PROPER_TRANSITIONS */
   } else {
-    if (thread->is_Named_thread()) {
       r = rmonitor->raw_wait(millis, false, thread);
-    } else {
-      ShouldNotReachHere();
-    }
+      assert(r != JvmtiRawMonitor::M_INTERRUPTED, "non-JavaThread can't be interrupted");
   }
 
   switch (r) {
-  case ObjectMonitor::OM_INTERRUPTED:
+  case JvmtiRawMonitor::M_INTERRUPTED:
     return JVMTI_ERROR_INTERRUPT;
-  case ObjectMonitor::OM_ILLEGAL_MONITOR_STATE:
+  case JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE:
     return JVMTI_ERROR_NOT_MONITOR_OWNER;
+  default:
+    return JVMTI_ERROR_NONE;
   }
-  assert(r == ObjectMonitor::OM_OK, "raw_wait should have worked");
-  if (r != ObjectMonitor::OM_OK) {  // robustness
-    return JVMTI_ERROR_INTERNAL;
-  }
-
-  return JVMTI_ERROR_NONE;
 } /* end RawMonitorWait */
 
 
 // rmonitor - pre-checked for validity
 jvmtiError
 JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {
-  int r = 0;
   Thread* thread = Thread::current();
-
-  if (thread->is_Java_thread()) {
-    JavaThread* current_thread = (JavaThread*)thread;
-    // Not really unknown but ThreadInVMfromNative does more than we want
-    ThreadInVMfromUnknown __tiv;
-    r = rmonitor->raw_notify(current_thread);
-  } else {
-    if (thread->is_Named_thread()) {
-      r = rmonitor->raw_notify(thread);
-    } else {
-      ShouldNotReachHere();
-    }
-  }
-
-  if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
+  int r = rmonitor->raw_notify(thread);
+
+  if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
     return JVMTI_ERROR_NOT_MONITOR_OWNER;
   }
-  assert(r == ObjectMonitor::OM_OK, "raw_notify should have worked");
-  if (r != ObjectMonitor::OM_OK) {  // robustness
-    return JVMTI_ERROR_INTERNAL;
-  }
-
   return JVMTI_ERROR_NONE;
 } /* end RawMonitorNotify */
 
@@ -3466,29 +3391,12 @@
 // rmonitor - pre-checked for validity
 jvmtiError
 JvmtiEnv::RawMonitorNotifyAll(JvmtiRawMonitor * rmonitor) {
-  int r = 0;
   Thread* thread = Thread::current();
-
-  if (thread->is_Java_thread()) {
-    JavaThread* current_thread = (JavaThread*)thread;
-    ThreadInVMfromUnknown __tiv;
-    r = rmonitor->raw_notifyAll(current_thread);
-  } else {
-    if (thread->is_Named_thread()) {
-      r = rmonitor->raw_notifyAll(thread);
-    } else {
-      ShouldNotReachHere();
-    }
-  }
-
-  if (r == ObjectMonitor::OM_ILLEGAL_MONITOR_STATE) {
+  int r = rmonitor->raw_notifyAll(thread);
+
+  if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
     return JVMTI_ERROR_NOT_MONITOR_OWNER;
   }
-  assert(r == ObjectMonitor::OM_OK, "raw_notifyAll should have worked");
-  if (r != ObjectMonitor::OM_OK) {  // robustness
-    return JVMTI_ERROR_INTERNAL;
-  }
-
   return JVMTI_ERROR_NONE;
 } /* end RawMonitorNotifyAll */
 
--- a/src/hotspot/share/prims/jvmtiEnvBase.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -659,10 +659,9 @@
     // thread is not doing an Object.wait() call
     mon = java_thread->current_pending_monitor();
     if (mon != NULL) {
-      // The thread is trying to enter() or raw_enter() an ObjectMonitor.
+      // The thread is trying to enter() an ObjectMonitor.
       obj = (oop)mon->object();
-      // If obj == NULL, then ObjectMonitor is raw which doesn't count
-      // as contended for this API
+      assert(obj != NULL, "ObjectMonitor should have a valid object!");
     }
     // implied else: no contended ObjectMonitor
   } else {
--- a/src/hotspot/share/prims/jvmtiRawMonitor.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -30,21 +30,23 @@
 #include "runtime/orderAccess.hpp"
 #include "runtime/thread.inline.hpp"
 
-GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1,true);
+JvmtiRawMonitor::QNode::QNode(Thread* thread) : _next(NULL), _prev(NULL),
+                                                _event(thread->_ParkEvent),
+                                                _notified(0), TState(TS_RUN) {
+}
+
+GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors =
+  new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1, true);
 
 void JvmtiPendingMonitors::transition_raw_monitors() {
   assert((Threads::number_of_threads()==1),
-         "Java thread has not created yet or more than one java thread \
+         "Java thread has not been created yet or more than one java thread \
 is running. Raw monitor transition will not work");
   JavaThread *current_java_thread = JavaThread::current();
   assert(current_java_thread->thread_state() == _thread_in_vm, "Must be in vm");
-  {
-    ThreadBlockInVM __tbivm(current_java_thread);
-    for(int i=0; i< count(); i++) {
-      JvmtiRawMonitor *rmonitor = monitors()->at(i);
-      int r = rmonitor->raw_enter(current_java_thread);
-      assert(r == ObjectMonitor::OM_OK, "raw_enter should have worked");
-    }
+  for(int i=0; i< count(); i++) {
+    JvmtiRawMonitor *rmonitor = monitors()->at(i);
+    rmonitor->raw_enter(current_java_thread);
   }
   // pending monitors are converted to real monitor so delete them all.
   dispose();
@@ -54,13 +56,16 @@
 // class JvmtiRawMonitor
 //
 
-JvmtiRawMonitor::JvmtiRawMonitor(const char *name) {
+JvmtiRawMonitor::JvmtiRawMonitor(const char *name) : _owner(NULL),
+                                                     _recursions(0),
+                                                     _EntryList(NULL),
+                                                     _WaitSet(NULL),
+                                                     _waiters(0),
+                                                     _magic(JVMTI_RM_MAGIC),
+                                                     _name(NULL) {
 #ifdef ASSERT
   _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
-#else
-  _name = NULL;
 #endif
-  _magic = JVMTI_RM_MAGIC;
 }
 
 JvmtiRawMonitor::~JvmtiRawMonitor() {
@@ -100,41 +105,29 @@
 }
 
 // -------------------------------------------------------------------------
-// The raw monitor subsystem is entirely distinct from normal
-// java-synchronization or jni-synchronization.  raw monitors are not
+// The JVMTI raw monitor subsystem is entirely distinct from normal
+// java-synchronization or jni-synchronization.  JVMTI raw monitors are not
 // associated with objects.  They can be implemented in any manner
 // that makes sense.  The original implementors decided to piggy-back
-// the raw-monitor implementation on the existing Java objectMonitor mechanism.
-// This flaw needs to fixed.  We should reimplement raw monitors as sui-generis.
-// Specifically, we should not implement raw monitors via java monitors.
-// Time permitting, we should disentangle and deconvolve the two implementations
-// and move the resulting raw monitor implementation over to the JVMTI directories.
-// Ideally, the raw monitor implementation would be built on top of
-// park-unpark and nothing else.
-//
-// raw monitors are used mainly by JVMTI
-// The raw monitor implementation borrows the ObjectMonitor structure,
-// but the operators are degenerate and extremely simple.
-//
-// Mixed use of a single objectMonitor instance -- as both a raw monitor
-// and a normal java monitor -- is not permissible.
+// the raw-monitor implementation on the existing Java ObjectMonitor mechanism.
+// Now we just use a simplified form of that ObjectMonitor code.
 //
 // Note that we use the single RawMonitor_lock to protect queue operations for
 // _all_ raw monitors.  This is a scalability impediment, but since raw monitor usage
-// is deprecated and rare, this is not of concern.  The RawMonitor_lock can not
+// is fairly rare, this is not of concern.  The RawMonitor_lock can not
 // be held indefinitely.  The critical sections must be short and bounded.
 //
 // -------------------------------------------------------------------------
 
-int JvmtiRawMonitor::SimpleEnter (Thread * Self) {
+void JvmtiRawMonitor::SimpleEnter (Thread * Self) {
   for (;;) {
     if (Atomic::replace_if_null(Self, &_owner)) {
-       return OS_OK ;
+       return ;
     }
 
-    ObjectWaiter Node (Self) ;
+    QNode Node (Self) ;
     Self->_ParkEvent->reset() ;     // strictly optional
-    Node.TState = ObjectWaiter::TS_ENTER ;
+    Node.TState = QNode::TS_ENTER ;
 
     RawMonitor_lock->lock_without_safepoint_check() ;
     Node._next  = _EntryList ;
@@ -143,21 +136,21 @@
     if (_owner == NULL && Atomic::replace_if_null(Self, &_owner)) {
         _EntryList = Node._next ;
         RawMonitor_lock->unlock() ;
-        return OS_OK ;
+        return ;
     }
     RawMonitor_lock->unlock() ;
-    while (Node.TState == ObjectWaiter::TS_ENTER) {
+    while (Node.TState == QNode::TS_ENTER) {
        Self->_ParkEvent->park() ;
     }
   }
 }
 
-int JvmtiRawMonitor::SimpleExit (Thread * Self) {
+void JvmtiRawMonitor::SimpleExit (Thread * Self) {
   guarantee (_owner == Self, "invariant") ;
-  OrderAccess::release_store(&_owner, (void*)NULL) ;
+  OrderAccess::release_store(&_owner, (Thread*)NULL) ;
   OrderAccess::fence() ;
-  if (_EntryList == NULL) return OS_OK ;
-  ObjectWaiter * w ;
+  if (_EntryList == NULL) return ;
+  QNode * w ;
 
   RawMonitor_lock->lock_without_safepoint_check() ;
   w = _EntryList ;
@@ -166,27 +159,27 @@
   }
   RawMonitor_lock->unlock() ;
   if (w != NULL) {
-      guarantee (w ->TState == ObjectWaiter::TS_ENTER, "invariant") ;
+      guarantee (w ->TState == QNode::TS_ENTER, "invariant") ;
       // Once we set TState to TS_RUN the waiting thread can complete
       // SimpleEnter and 'w' is pointing into random stack space. So we have
       // to ensure we extract the ParkEvent (which is in type-stable memory)
       // before we set the state, and then don't access 'w'.
       ParkEvent * ev = w->_event ;
       OrderAccess::loadstore();
-      w->TState = ObjectWaiter::TS_RUN ;
+      w->TState = QNode::TS_RUN ;
       OrderAccess::fence() ;
       ev->unpark() ;
   }
-  return OS_OK ;
+  return ;
 }
 
 int JvmtiRawMonitor::SimpleWait (Thread * Self, jlong millis) {
   guarantee (_owner == Self  , "invariant") ;
   guarantee (_recursions == 0, "invariant") ;
 
-  ObjectWaiter Node (Self) ;
+  QNode Node (Self) ;
   Node._notified = 0 ;
-  Node.TState    = ObjectWaiter::TS_WAIT ;
+  Node.TState    = QNode::TS_WAIT ;
 
   RawMonitor_lock->lock_without_safepoint_check() ;
   Node._next     = _WaitSet ;
@@ -208,12 +201,12 @@
   // as TState is volatile and the lock-unlock operators are
   // serializing (barrier-equivalent).
 
-  if (Node.TState == ObjectWaiter::TS_WAIT) {
+  if (Node.TState == QNode::TS_WAIT) {
     RawMonitor_lock->lock_without_safepoint_check() ;
-    if (Node.TState == ObjectWaiter::TS_WAIT) {
+    if (Node.TState == QNode::TS_WAIT) {
       // Simple O(n) unlink, but performance isn't critical here.
-      ObjectWaiter * p ;
-      ObjectWaiter * q = NULL ;
+      QNode * p ;
+      QNode * q = NULL ;
       for (p = _WaitSet ; p != &Node; p = p->_next) {
          q = p ;
       }
@@ -225,12 +218,12 @@
         guarantee (p == q->_next, "invariant") ;
         q->_next = p->_next ;
       }
-      Node.TState = ObjectWaiter::TS_RUN ;
+      Node.TState = QNode::TS_RUN ;
     }
     RawMonitor_lock->unlock() ;
   }
 
-  guarantee (Node.TState == ObjectWaiter::TS_RUN, "invariant") ;
+  guarantee (Node.TState == QNode::TS_RUN, "invariant") ;
   SimpleEnter (Self) ;
 
   guarantee (_owner == Self, "invariant") ;
@@ -238,9 +231,9 @@
   return ret ;
 }
 
-int JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) {
+void JvmtiRawMonitor::SimpleNotify (Thread * Self, bool All) {
   guarantee (_owner == Self, "invariant") ;
-  if (_WaitSet == NULL) return OS_OK ;
+  if (_WaitSet == NULL) return ;
 
   // We have two options:
   // A. Transfer the threads from the WaitSet to the EntryList
@@ -252,29 +245,29 @@
   ParkEvent * ev = NULL ;       // consider using a small auto array ...
   RawMonitor_lock->lock_without_safepoint_check() ;
   for (;;) {
-      ObjectWaiter * w = _WaitSet ;
+      QNode * w = _WaitSet ;
       if (w == NULL) break ;
       _WaitSet = w->_next ;
       if (ev != NULL) { ev->unpark(); ev = NULL; }
       ev = w->_event ;
       OrderAccess::loadstore() ;
-      w->TState = ObjectWaiter::TS_RUN ;
+      w->TState = QNode::TS_RUN ;
       OrderAccess::storeload();
       if (!All) break ;
   }
   RawMonitor_lock->unlock() ;
   if (ev != NULL) ev->unpark();
-  return OS_OK ;
+  return ;
 }
 
 // Any JavaThread will enter here with state _thread_blocked
-int JvmtiRawMonitor::raw_enter(TRAPS) {
+void JvmtiRawMonitor::raw_enter(Thread * Self) {
   void * Contended ;
-
+  JavaThread * jt = NULL;
   // don't enter raw monitor if thread is being externally suspended, it will
   // surprise the suspender if a "suspended" thread can still enter monitor
-  JavaThread * jt = (JavaThread *)THREAD;
-  if (THREAD->is_Java_thread()) {
+  if (Self->is_Java_thread()) {
+    jt = (JavaThread*) Self;
     jt->SR_lock()->lock_without_safepoint_check();
     while (jt->is_external_suspend()) {
       jt->SR_lock()->unlock();
@@ -282,150 +275,136 @@
       jt->SR_lock()->lock_without_safepoint_check();
     }
     // guarded by SR_lock to avoid racing with new external suspend requests.
-    Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL);
+    Contended = Atomic::cmpxchg(jt, &_owner, (Thread*)NULL);
     jt->SR_lock()->unlock();
   } else {
-    Contended = Atomic::cmpxchg(THREAD, &_owner, (void*)NULL);
+    Contended = Atomic::cmpxchg(Self, &_owner, (Thread*)NULL);
   }
 
-  if (Contended == THREAD) {
+  if (Contended == Self) {
      _recursions ++ ;
-     return OM_OK ;
+     return ;
   }
 
   if (Contended == NULL) {
-     guarantee (_owner == THREAD, "invariant") ;
+     guarantee (_owner == Self, "invariant") ;
      guarantee (_recursions == 0, "invariant") ;
-     return OM_OK ;
+     return ;
   }
 
-  THREAD->set_current_pending_monitor(this);
+  Self->set_current_pending_raw_monitor(this);
 
-  if (!THREAD->is_Java_thread()) {
-     // No other non-Java threads besides VM thread would acquire
-     // a raw monitor.
-     assert(THREAD->is_VM_thread(), "must be VM thread");
-     SimpleEnter (THREAD) ;
-   } else {
-     guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
-     for (;;) {
-       jt->set_suspend_equivalent();
-       // cleared by handle_special_suspend_equivalent_condition() or
-       // java_suspend_self()
-       SimpleEnter (THREAD) ;
-
-       // were we externally suspended while we were waiting?
-       if (!jt->handle_special_suspend_equivalent_condition()) break ;
+  if (!Self->is_Java_thread()) {
+     SimpleEnter (Self) ;
+  } else {
+    guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
+    for (;;) {
+      jt->set_suspend_equivalent();
+      // cleared by handle_special_suspend_equivalent_condition() or
+      // java_suspend_self()
+      SimpleEnter (jt) ;
 
-       // This thread was externally suspended
-       //
-       // This logic isn't needed for JVMTI raw monitors,
-       // but doesn't hurt just in case the suspend rules change. This
-           // logic is needed for the JvmtiRawMonitor.wait() reentry phase.
-           // We have reentered the contended monitor, but while we were
-           // waiting another thread suspended us. We don't want to reenter
-           // the monitor while suspended because that would surprise the
-           // thread that suspended us.
-           //
-           // Drop the lock -
-       SimpleExit (THREAD) ;
+      // were we externally suspended while we were waiting?
+      if (!jt->handle_special_suspend_equivalent_condition()) break ;
 
-           jt->java_suspend_self();
-         }
+      // This thread was externally suspended
+      // We have reentered the contended monitor, but while we were
+      // waiting another thread suspended us. We don't want to reenter
+      // the monitor while suspended because that would surprise the
+      // thread that suspended us.
+      //
+      // Drop the lock
+      SimpleExit (jt) ;
 
-     assert(_owner == THREAD, "Fatal error with monitor owner!");
-     assert(_recursions == 0, "Fatal error with monitor recursions!");
+      jt->java_suspend_self();
+    }
   }
 
-  THREAD->set_current_pending_monitor(NULL);
+  Self->set_current_pending_raw_monitor(NULL);
+
+  guarantee (_owner == Self, "invariant") ;
   guarantee (_recursions == 0, "invariant") ;
-  return OM_OK;
 }
 
-// Used mainly for JVMTI raw monitor implementation
-// Also used for JvmtiRawMonitor::wait().
-int JvmtiRawMonitor::raw_exit(TRAPS) {
-  if (THREAD != _owner) {
-    return OM_ILLEGAL_MONITOR_STATE;
+int JvmtiRawMonitor::raw_exit(Thread * Self) {
+  if (Self != _owner) {
+    return M_ILLEGAL_MONITOR_STATE;
   }
   if (_recursions > 0) {
     --_recursions ;
-    return OM_OK ;
+  } else {
+    SimpleExit (Self) ;
   }
 
-  void * List = _EntryList ;
-  SimpleExit (THREAD) ;
-
-  return OM_OK;
+  return M_OK;
 }
 
-// Used for JVMTI raw monitor implementation.
 // All JavaThreads will enter here with state _thread_blocked
 
-int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, TRAPS) {
-  if (THREAD != _owner) {
-    return OM_ILLEGAL_MONITOR_STATE;
+int JvmtiRawMonitor::raw_wait(jlong millis, bool interruptible, Thread * Self) {
+  if (Self != _owner) {
+    return M_ILLEGAL_MONITOR_STATE;
   }
 
   // To avoid spurious wakeups we reset the parkevent -- This is strictly optional.
   // The caller must be able to tolerate spurious returns from raw_wait().
-  THREAD->_ParkEvent->reset() ;
+  Self->_ParkEvent->reset() ;
   OrderAccess::fence() ;
 
+  JavaThread * jt = NULL;
   // check interrupt event
   if (interruptible) {
-    assert(THREAD->is_Java_thread(), "Only JavaThreads can be interruptible");
-    JavaThread* jt = (JavaThread*) THREAD;
+    assert(Self->is_Java_thread(), "Only JavaThreads can be interruptible");
+    jt = (JavaThread*) Self;
     if (jt->is_interrupted(true)) {
-      return OM_INTERRUPTED;
+      return M_INTERRUPTED;
     }
+  } else {
+    assert(!Self->is_Java_thread(), "JavaThreads must be interuptible");
   }
 
   intptr_t save = _recursions ;
   _recursions = 0 ;
   _waiters ++ ;
-  if (THREAD->is_Java_thread()) {
-    guarantee (((JavaThread *) THREAD)->thread_state() == _thread_blocked, "invariant") ;
-    ((JavaThread *)THREAD)->set_suspend_equivalent();
+  if (Self->is_Java_thread()) {
+    guarantee (jt->thread_state() == _thread_blocked, "invariant") ;
+    jt->set_suspend_equivalent();
   }
-  int rv = SimpleWait (THREAD, millis) ;
+  int rv = SimpleWait (Self, millis) ;
   _recursions = save ;
   _waiters -- ;
 
-  guarantee (THREAD == _owner, "invariant") ;
-  if (THREAD->is_Java_thread()) {
-     JavaThread * jSelf = (JavaThread *) THREAD ;
+  guarantee (Self == _owner, "invariant") ;
+  if (Self->is_Java_thread()) {
      for (;;) {
-        if (!jSelf->handle_special_suspend_equivalent_condition()) break ;
-        SimpleExit (THREAD) ;
-        jSelf->java_suspend_self();
-        SimpleEnter (THREAD) ;
-        jSelf->set_suspend_equivalent() ;
+        if (!jt->handle_special_suspend_equivalent_condition()) break ;
+        SimpleExit (jt) ;
+        jt->java_suspend_self();
+        SimpleEnter (jt) ;
+        jt->set_suspend_equivalent() ;
      }
+     guarantee (jt == _owner, "invariant") ;
   }
-  guarantee (THREAD == _owner, "invariant") ;
 
-  if (interruptible) {
-    JavaThread* jt = (JavaThread*) THREAD;
-    if (jt->is_interrupted(true)) {
-      return OM_INTERRUPTED;
-    }
+  if (interruptible && jt->is_interrupted(true)) {
+    return M_INTERRUPTED;
   }
-  return OM_OK ;
+
+  return M_OK ;
 }
 
-int JvmtiRawMonitor::raw_notify(TRAPS) {
-  if (THREAD != _owner) {
-    return OM_ILLEGAL_MONITOR_STATE;
+int JvmtiRawMonitor::raw_notify(Thread * Self) {
+  if (Self != _owner) {
+    return M_ILLEGAL_MONITOR_STATE;
   }
-  SimpleNotify (THREAD, false) ;
-  return OM_OK;
+  SimpleNotify (Self, false) ;
+  return M_OK;
 }
 
-int JvmtiRawMonitor::raw_notifyAll(TRAPS) {
-  if (THREAD != _owner) {
-    return OM_ILLEGAL_MONITOR_STATE;
+int JvmtiRawMonitor::raw_notifyAll(Thread * Self) {
+  if (Self != _owner) {
+    return M_ILLEGAL_MONITOR_STATE;
   }
-  SimpleNotify (THREAD, true) ;
-  return OM_OK;
+  SimpleNotify (Self, true) ;
+  return M_OK;
 }
--- a/src/hotspot/share/prims/jvmtiRawMonitor.hpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiRawMonitor.hpp	Tue Oct 08 11:57:11 2019 +0200
@@ -25,7 +25,8 @@
 #ifndef SHARE_PRIMS_JVMTIRAWMONITOR_HPP
 #define SHARE_PRIMS_JVMTIRAWMONITOR_HPP
 
-#include "runtime/objectMonitor.hpp"
+#include "memory/allocation.hpp"
+#include "runtime/park.hpp"
 #include "utilities/growableArray.hpp"
 
 //
@@ -33,31 +34,69 @@
 //
 // Used by JVMTI methods: All RawMonitor methods (CreateRawMonitor, EnterRawMonitor, etc.)
 //
-// Wrapper for ObjectMonitor class that saves the Monitor's name
+// A simplified version of the ObjectMonitor code.
 //
 
-class JvmtiRawMonitor : public ObjectMonitor  {
-private:
+class JvmtiRawMonitor : public CHeapObj<mtSynchronizer>  {
+
+  // Helper class to allow Threads to be linked into queues.
+  // This is a stripped down version of ObjectWaiter.
+  class QNode : public StackObj {
+    friend class JvmtiRawMonitor;
+    enum TStates { TS_READY, TS_RUN, TS_WAIT, TS_ENTER };
+    QNode* volatile _next;
+    QNode* volatile _prev;
+    ParkEvent *   _event;
+    volatile int  _notified;
+    volatile TStates TState;
+
+    QNode(Thread* thread);
+  };
+
+  Thread* volatile _owner;          // pointer to owning thread
+  volatile int _recursions;         // recursion count, 0 for first entry
+  QNode* volatile _EntryList;       // Threads blocked on entry or reentry.
+                                    // The list is actually composed of nodes,
+                                    // acting as proxies for Threads.
+  QNode* volatile _WaitSet;         // Threads wait()ing on the monitor
+  volatile jint  _waiters;          // number of waiting threads
   int           _magic;
   char *        _name;
   // JVMTI_RM_MAGIC is set in contructor and unset in destructor.
   enum { JVMTI_RM_MAGIC = (int)(('T' << 24) | ('I' << 16) | ('R' << 8) | 'M') };
 
-  int       SimpleEnter (Thread * Self) ;
-  int       SimpleExit  (Thread * Self) ;
+  void      SimpleEnter (Thread * Self) ;
+  void      SimpleExit  (Thread * Self) ;
   int       SimpleWait  (Thread * Self, jlong millis) ;
-  int       SimpleNotify (Thread * Self, bool All) ;
+  void      SimpleNotify(Thread * Self, bool All) ;
 
 public:
+
+  // return codes
+  enum {
+    M_OK,                    // no error
+    M_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
+    M_INTERRUPTED            // Thread.interrupt()
+  };
+
+  // Non-aborting operator new
+  void* operator new(size_t size) throw() {
+    return CHeapObj::operator new(size, std::nothrow);
+  }
+
   JvmtiRawMonitor(const char *name);
   ~JvmtiRawMonitor();
-  int       raw_enter(TRAPS);
-  int       raw_exit(TRAPS);
-  int       raw_wait(jlong millis, bool interruptable, TRAPS);
-  int       raw_notify(TRAPS);
-  int       raw_notifyAll(TRAPS);
-  int            magic()   { return _magic;  }
-  const char *get_name()   { return _name; }
+
+  Thread *  owner() const { return _owner; }
+  void      set_owner(Thread * owner) { _owner = owner; }
+  int       recursions() const { return _recursions; }
+  void      raw_enter(Thread * Self);
+  int       raw_exit(Thread * Self);
+  int       raw_wait(jlong millis, bool interruptable, Thread * Self);
+  int       raw_notify(Thread * Self);
+  int       raw_notifyAll(Thread * Self);
+  int       magic() const { return _magic;  }
+  const char *get_name() const { return _name; }
   bool        is_valid();
 };
 
--- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -3528,15 +3528,6 @@
              "should be replaced");
     }
   }
-  // Update deleted jmethodID
-  for (int j = 0; j < _deleted_methods_length; ++j) {
-    Method* old_method = _deleted_methods[j];
-    jmethodID jmid = old_method->find_jmethod_id_or_null();
-    if (jmid != NULL) {
-      // Change the jmethodID to point to NSME.
-      Method::change_method_associated_with_jmethod_id(jmid, Universe::throw_no_such_method_error());
-    }
-  }
 }
 
 int VM_RedefineClasses::check_methods_and_mark_as_obsolete() {
--- a/src/hotspot/share/runtime/mutexLocker.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/mutexLocker.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -66,7 +66,6 @@
 Mutex*   RetData_lock                 = NULL;
 Monitor* VMOperationQueue_lock        = NULL;
 Monitor* VMOperationRequest_lock      = NULL;
-Monitor* SerializePage_lock           = NULL;
 Monitor* Threads_lock                 = NULL;
 Mutex*   NonJavaThreadsList_lock      = NULL;
 Mutex*   NonJavaThreadsListSync_lock  = NULL;
@@ -118,6 +117,7 @@
 Monitor* Service_lock                 = NULL;
 Monitor* PeriodicTask_lock            = NULL;
 Monitor* RedefineClasses_lock         = NULL;
+Mutex*   Verify_lock                  = NULL;
 
 #if INCLUDE_JFR
 Mutex*   JfrStacktrace_lock           = NULL;
@@ -298,6 +298,7 @@
   def(CompileThread_lock           , PaddedMonitor, nonleaf+5,   false, _safepoint_check_always);
   def(PeriodicTask_lock            , PaddedMonitor, nonleaf+5,   true,  _safepoint_check_always);
   def(RedefineClasses_lock         , PaddedMonitor, nonleaf+5,   true,  _safepoint_check_always);
+  def(Verify_lock                  , PaddedMutex,   nonleaf+5,   true,  _safepoint_check_always);
 
   if (WhiteBoxAPI) {
     def(Compilation_lock           , PaddedMonitor, leaf,        false, _safepoint_check_never);
--- a/src/hotspot/share/runtime/mutexLocker.hpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/mutexLocker.hpp	Tue Oct 08 11:57:11 2019 +0200
@@ -103,7 +103,6 @@
 extern Mutex*   RawMonitor_lock;
 extern Mutex*   PerfDataMemAlloc_lock;           // a lock on the allocator for PerfData memory for performance data
 extern Mutex*   PerfDataManager_lock;            // a long on access to PerfDataManager resources
-extern Mutex*   ParkerFreeList_lock;
 extern Mutex*   OopMapCacheAlloc_lock;           // protects allocation of oop_map caches
 
 extern Mutex*   FreeList_lock;                   // protects the free region list during safepoints
@@ -114,6 +113,7 @@
 extern Monitor* Service_lock;                    // a lock used for service thread operation
 extern Monitor* PeriodicTask_lock;               // protects the periodic task structure
 extern Monitor* RedefineClasses_lock;            // locks classes from parallel redefinition
+extern Mutex*   Verify_lock;                     // synchronize initialization of verify library
 extern Monitor* ThreadsSMRDelete_lock;           // Used by ThreadsSMRSupport to take pressure off the Threads_lock
 extern Mutex*   ThreadIdTableCreate_lock;        // Used by ThreadIdTable to lazily create the thread id table
 extern Mutex*   SharedDecoder_lock;              // serializes access to the decoder during normal (not error reporting) use
--- a/src/hotspot/share/runtime/objectMonitor.hpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/objectMonitor.hpp	Tue Oct 08 11:57:11 2019 +0200
@@ -43,7 +43,6 @@
 class ObjectWaiter : public StackObj {
  public:
   enum TStates { TS_UNDEF, TS_READY, TS_RUN, TS_WAIT, TS_ENTER, TS_CXQ };
-  enum Sorted  { PREPEND, APPEND, SORTED };
   ObjectWaiter* volatile _next;
   ObjectWaiter* volatile _prev;
   Thread*       _thread;
@@ -51,7 +50,6 @@
   ParkEvent *   _event;
   volatile int  _notified;
   volatile TStates TState;
-  Sorted        _Sorted;           // List placement disposition
   bool          _active;           // Contention monitoring is enabled
  public:
   ObjectWaiter(Thread* thread);
@@ -68,10 +66,6 @@
 // WARNING: This is a very sensitive and fragile class. DO NOT make any
 // changes unless you are fully aware of the underlying semantics.
 //
-// Class JvmtiRawMonitor currently inherits from ObjectMonitor so
-// changes in this class must be careful to not break JvmtiRawMonitor.
-// These two subsystems should be separated.
-//
 // ObjectMonitor Layout Overview/Highlights/Restrictions:
 //
 // - The _header field must be at offset 0 because the displaced header
@@ -127,16 +121,6 @@
 //     in a 64-bit JVM.
 
 class ObjectMonitor {
- public:
-  enum {
-    OM_OK,                    // no error
-    OM_SYSTEM_ERROR,          // operating system error
-    OM_ILLEGAL_MONITOR_STATE, // IllegalMonitorStateException
-    OM_INTERRUPTED,           // Thread.interrupt()
-    OM_TIMED_OUT              // Object.wait() timed out
-  };
-
- private:
   friend class ObjectSynchronizer;
   friend class ObjectWaiter;
   friend class VMStructs;
@@ -158,16 +142,13 @@
   DEFINE_PAD_MINUS_SIZE(0, DEFAULT_CACHE_LINE_SIZE,
                         sizeof(volatile markWord) + sizeof(void* volatile) +
                         sizeof(ObjectMonitor *));
- protected:                         // protected for JvmtiRawMonitor
   void* volatile _owner;            // pointer to owning thread OR BasicLock
- private:
   volatile jlong _previous_owner_tid;  // thread id of the previous owner of the monitor
- protected:                         // protected for JvmtiRawMonitor
   volatile intptr_t _recursions;    // recursion count, 0 for first entry
   ObjectWaiter* volatile _EntryList;  // Threads blocked on entry or reentry.
                                       // The list is actually composed of WaitNodes,
                                       // acting as proxies for Threads.
- private:
+
   ObjectWaiter* volatile _cxq;      // LL of recently-arrived threads blocked on entry.
   Thread* volatile _succ;           // Heir presumptive thread - used for futile wakeup throttling
   Thread* volatile _Responsible;
--- a/src/hotspot/share/runtime/os.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/os.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -536,14 +536,6 @@
     char buffer[JVM_MAXPATHLEN];
     char ebuf[1024];
 
-    // Try to load verify dll first. In 1.3 java dll depends on it and is not
-    // always able to find it when the loading executable is outside the JDK.
-    // In order to keep working with 1.2 we ignore any loading errors.
-    if (dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(),
-                       "verify")) {
-      dll_load(buffer, ebuf, sizeof(ebuf));
-    }
-
     // Load java dll
     if (dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(),
                        "java")) {
--- a/src/hotspot/share/runtime/thread.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/thread.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -258,6 +258,7 @@
   _current_pending_monitor = NULL;
   _current_pending_monitor_is_from_java = true;
   _current_waiting_monitor = NULL;
+  _current_pending_raw_monitor = NULL;
   _num_nested_signal = 0;
   om_free_list = NULL;
   om_free_count = 0;
@@ -3847,7 +3848,7 @@
   // Create the VMThread
   { TraceTime timer("Start VMThread", TRACETIME_LOG(Info, startuptime));
 
-  VMThread::create();
+    VMThread::create();
     Thread* vmthread = VMThread::vm_thread();
 
     if (!os::create_thread(vmthread, os::vm_thread)) {
--- a/src/hotspot/share/runtime/thread.hpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/runtime/thread.hpp	Tue Oct 08 11:57:11 2019 +0200
@@ -62,6 +62,7 @@
 class ThreadsList;
 class ThreadsSMRSupport;
 
+class JvmtiRawMonitor;
 class JvmtiThreadState;
 class ThreadStatistics;
 class ConcurrentLocksDump;
@@ -404,6 +405,9 @@
   ObjectMonitor* _current_pending_monitor;      // ObjectMonitor this thread
                                                 // is waiting to lock
   bool _current_pending_monitor_is_from_java;   // locking is from Java code
+  JvmtiRawMonitor* _current_pending_raw_monitor; // JvmtiRawMonitor this thread
+                                                 // is waiting to lock
+
 
   // ObjectMonitor on which this thread called Object.wait()
   ObjectMonitor* _current_waiting_monitor;
@@ -640,6 +644,14 @@
     _current_waiting_monitor = monitor;
   }
 
+  // For tracking the Jvmti raw monitor the thread is pending on.
+  JvmtiRawMonitor* current_pending_raw_monitor() {
+    return _current_pending_raw_monitor;
+  }
+  void set_current_pending_raw_monitor(JvmtiRawMonitor* monitor) {
+    _current_pending_raw_monitor = monitor;
+  }
+
   // GC support
   // Apply "f->do_oop" to all root oops in "this".
   //   Used by JavaThread::oops_do.
@@ -786,7 +798,7 @@
  public:
   volatile intptr_t _Stalled;
   volatile int _TypeTag;
-  ParkEvent * _ParkEvent;                     // for synchronized()
+  ParkEvent * _ParkEvent;                     // for Object monitors and JVMTI raw monitors
   ParkEvent * _MuxEvent;                      // for low-level muxAcquire-muxRelease
   int NativeSyncRecursion;                    // diagnostic
 
--- a/src/hotspot/share/services/threadService.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/hotspot/share/services/threadService.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -32,6 +32,7 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.inline.hpp"
 #include "oops/oop.inline.hpp"
+#include "prims/jvmtiRawMonitor.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/init.hpp"
@@ -217,10 +218,10 @@
   } else {
     ObjectMonitor *enter_obj = thread->current_pending_monitor();
     if (enter_obj != NULL) {
-      // thread is trying to enter() or raw_enter() an ObjectMonitor.
+      // thread is trying to enter() an ObjectMonitor.
       obj = (oop) enter_obj->object();
+      assert(obj != NULL, "ObjectMonitor should have an associated object!");
     }
-    // If obj == NULL, then ObjectMonitor is raw which doesn't count.
   }
 
   Handle h(Thread::current(), obj);
@@ -354,13 +355,15 @@
   }
 }
 
-// Find deadlocks involving object monitors and concurrent locks if concurrent_locks is true
+// Find deadlocks involving raw monitors, object monitors and concurrent locks
+// if concurrent_locks is true.
 DeadlockCycle* ThreadService::find_deadlocks_at_safepoint(ThreadsList * t_list, bool concurrent_locks) {
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
 
   // This code was modified from the original Threads::find_deadlocks code.
   int globalDfn = 0, thisDfn;
   ObjectMonitor* waitingToLockMonitor = NULL;
+  JvmtiRawMonitor* waitingToLockRawMonitor = NULL;
   oop waitingToLockBlocker = NULL;
   bool blocked_on_monitor = false;
   JavaThread *currentThread, *previousThread;
@@ -391,13 +394,30 @@
     // When there is a deadlock, all the monitors involved in the dependency
     // cycle must be contended and heavyweight. So we only care about the
     // heavyweight monitor a thread is waiting to lock.
-    waitingToLockMonitor = (ObjectMonitor*)jt->current_pending_monitor();
+    waitingToLockMonitor = jt->current_pending_monitor();
+    // JVM TI raw monitors can also be involved in deadlocks, and we can be
+    // waiting to lock both a raw monitor and ObjectMonitor at the same time.
+    // It isn't clear how to make deadlock detection work correctly if that
+    // happens.
+    waitingToLockRawMonitor = jt->current_pending_raw_monitor();
+
     if (concurrent_locks) {
       waitingToLockBlocker = jt->current_park_blocker();
     }
-    while (waitingToLockMonitor != NULL || waitingToLockBlocker != NULL) {
+
+    while (waitingToLockMonitor != NULL ||
+           waitingToLockRawMonitor != NULL ||
+           waitingToLockBlocker != NULL) {
       cycle->add_thread(currentThread);
-      if (waitingToLockMonitor != NULL) {
+      // Give preference to the raw monitor
+      if (waitingToLockRawMonitor != NULL) {
+        Thread* owner = waitingToLockRawMonitor->owner();
+        if (owner != NULL && // the raw monitor could be released at any time
+            owner->is_Java_thread()) {
+          // only JavaThreads can be reported here
+          currentThread = (JavaThread*) owner;
+        }
+      } else if (waitingToLockMonitor != NULL) {
         address currentOwner = (address)waitingToLockMonitor->owner();
         if (currentOwner != NULL) {
           currentThread = Threads::owning_thread_from_monitor_owner(t_list,
@@ -948,28 +968,44 @@
 
   JavaThread* currentThread;
   ObjectMonitor* waitingToLockMonitor;
+  JvmtiRawMonitor* waitingToLockRawMonitor;
   oop waitingToLockBlocker;
   int len = _threads->length();
   for (int i = 0; i < len; i++) {
     currentThread = _threads->at(i);
-    waitingToLockMonitor = (ObjectMonitor*)currentThread->current_pending_monitor();
+    waitingToLockMonitor = currentThread->current_pending_monitor();
+    waitingToLockRawMonitor = currentThread->current_pending_raw_monitor();
     waitingToLockBlocker = currentThread->current_park_blocker();
     st->cr();
     st->print_cr("\"%s\":", currentThread->get_thread_name());
     const char* owner_desc = ",\n  which is held by";
+
+    // Note: As the JVM TI "monitor contended enter" event callback is executed after ObjectMonitor
+    // sets the current pending monitor, it is possible to then see a pending raw monitor as well.
+    if (waitingToLockRawMonitor != NULL) {
+      st->print("  waiting to lock JVM TI raw monitor " INTPTR_FORMAT, p2i(waitingToLockRawMonitor));
+      Thread* owner = waitingToLockRawMonitor->owner();
+      // Could be NULL as the raw monitor could be released at any time if held by non-JavaThread
+      if (owner != NULL) {
+        if (owner->is_Java_thread()) {
+          currentThread = (JavaThread*) owner;
+          st->print_cr("%s \"%s\"", owner_desc, currentThread->get_thread_name());
+        } else {
+          st->print_cr(",\n  which has now been released");
+        }
+      } else {
+        st->print_cr("%s non-Java thread=" PTR_FORMAT, owner_desc, p2i(owner));
+      }
+    }
+
     if (waitingToLockMonitor != NULL) {
       st->print("  waiting to lock monitor " INTPTR_FORMAT, p2i(waitingToLockMonitor));
       oop obj = (oop)waitingToLockMonitor->object();
-      if (obj != NULL) {
-        st->print(" (object " INTPTR_FORMAT ", a %s)", p2i(obj),
-                   obj->klass()->external_name());
+      st->print(" (object " INTPTR_FORMAT ", a %s)", p2i(obj),
+                 obj->klass()->external_name());
 
-        if (!currentThread->current_pending_monitor_is_from_java()) {
-          owner_desc = "\n  in JNI, which is held by";
-        }
-      } else {
-        // No Java object associated - a JVMTI raw monitor
-        owner_desc = " (JVMTI raw monitor),\n  which is held by";
+      if (!currentThread->current_pending_monitor_is_from_java()) {
+        owner_desc = "\n  in JNI, which is held by";
       }
       currentThread = Threads::owning_thread_from_monitor_owner(t_list,
                                                                 (address)waitingToLockMonitor->owner());
@@ -978,7 +1014,7 @@
         // that owns waitingToLockMonitor should be findable, but
         // if it is not findable, then the previous currentThread is
         // blocked permanently.
-        st->print("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc,
+        st->print_cr("%s UNKNOWN_owner_addr=" PTR_FORMAT, owner_desc,
                   p2i(waitingToLockMonitor->owner()));
         continue;
       }
@@ -992,11 +1028,10 @@
       currentThread = java_lang_Thread::thread(ownerObj);
       assert(currentThread != NULL, "AbstractOwnableSynchronizer owning thread is unexpectedly NULL");
     }
-    st->print("%s \"%s\"", owner_desc, currentThread->get_thread_name());
+    st->print_cr("%s \"%s\"", owner_desc, currentThread->get_thread_name());
   }
 
   st->cr();
-  st->cr();
 
   // Print stack traces
   bool oldJavaMonitorsInStackTrace = JavaMonitorsInStackTrace;
--- a/src/java.base/share/classes/java/util/Collection.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/classes/java/util/Collection.java	Tue Oct 08 11:57:11 2019 +0200
@@ -188,6 +188,38 @@
  * or if the only reference to the backing collection is through an
  * unmodifiable view, the view can be considered effectively immutable.
  *
+ * <h2><a id="serializable">Serializability of Collections</a></h2>
+ *
+ * <p>Serializability of collections is optional. As such, none of the collections
+ * interfaces are declared to implement the {@link java.io.Serializable} interface.
+ * However, serializability is regarded as being generally useful, so most collection
+ * implementations are serializable.
+ *
+ * <p>The collection implementations that are public classes (such as {@code ArrayList}
+ * or {@code HashMap}) are declared to implement the {@code Serializable} interface if they
+ * are in fact serializable. Some collections implementations are not public classes,
+ * such as the <a href="#unmodifiable">unmodifiable collections.</a> In such cases, the
+ * serializability of such collections is described in the specification of the method
+ * that creates them, or in some other suitable place. In cases where the serializability
+ * of a collection is not specified, there is no guarantee about the serializability of such
+ * collections. In particular, many <a href="#view">view collections</a> are not serializable.
+ *
+ * <p>A collection implementation that implements the {@code Serializable} interface cannot
+ * be guaranteed to be serializable. The reason is that in general, collections
+ * contain elements of other types, and it is not possible to determine statically
+ * whether instances of some element type are actually serializable. For example, consider
+ * a serializable {@code Collection<E>}, where {@code E} does not implement the
+ * {@code Serializable} interface. The collection may be serializable, if it contains only
+ * elements of some serializable subtype of {@code E}, or if it is empty. Collections are
+ * thus said to be <i>conditionally serializable,</i> as the serializability of the collection
+ * as a whole depends on whether the collection itself is serializable and on whether all
+ * contained elements are also serializable.
+ *
+ * <p>An additional case occurs with instances of {@link SortedSet} and {@link SortedMap}.
+ * These collections can be created with a {@link Comparator} that imposes an ordering on
+ * the set elements or map keys. Such a collection is serializable only if the provided
+ * {@code Comparator} is also serializable.
+ *
  * <p>This interface is a member of the
  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
  * Java Collections Framework</a>.
--- a/src/java.base/share/native/libjava/Class.c	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/Class.c	Tue Oct 08 11:57:11 2019 +0200
@@ -35,12 +35,9 @@
 #include "jni.h"
 #include "jni_util.h"
 #include "jvm.h"
+#include "check_classname.h"
 #include "java_lang_Class.h"
 
-/* defined in libverify.so/verify.dll (src file common/check_format.c) */
-extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed);
-extern jboolean VerifyFixClassname(char *utf_name);
-
 #define OBJ "Ljava/lang/Object;"
 #define CLS "Ljava/lang/Class;"
 #define CPL "Ljdk/internal/reflect/ConstantPool;"
@@ -123,14 +120,14 @@
     }
     (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);
 
-    if (VerifyFixClassname(clname) == JNI_TRUE) {
+    if (verifyFixClassname(clname) == JNI_TRUE) {
         /* slashes present in clname, use name b4 translation for exception */
         (*env)->GetStringUTFRegion(env, classname, 0, unicode_len, clname);
         JNU_ThrowClassNotFoundException(env, clname);
         goto done;
     }
 
-    if (!VerifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */
+    if (!verifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */
         JNU_ThrowClassNotFoundException(env, clname);
         goto done;
     }
--- a/src/java.base/share/native/libjava/ClassLoader.c	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/ClassLoader.c	Tue Oct 08 11:57:11 2019 +0200
@@ -30,14 +30,11 @@
 #include "jni_util.h"
 #include "jlong.h"
 #include "jvm.h"
+#include "check_classname.h"
 #include "java_lang_ClassLoader.h"
 #include "java_lang_ClassLoader_NativeLibrary.h"
 #include <string.h>
 
-/* defined in libverify.so/verify.dll (src file common/check_format.c) */
-extern jboolean VerifyClassname(char *utf_name, jboolean arrayAllowed);
-extern jboolean VerifyFixClassname(char *utf_name);
-
 static JNINativeMethod methods[] = {
     {"retrieveDirectives",  "()Ljava/lang/AssertionStatusDirectives;", (void *)&JVM_AssertionStatusDirectives}
 };
@@ -120,7 +117,7 @@
         if (utfName == NULL) {
             goto free_body;
         }
-        VerifyFixClassname(utfName);
+        fixClassname(utfName);
     } else {
         utfName = NULL;
     }
@@ -185,7 +182,7 @@
             JNU_ThrowOutOfMemoryError(env, NULL);
             return result;
         }
-        VerifyFixClassname(utfName);
+        fixClassname(utfName);
     } else {
         utfName = NULL;
     }
@@ -231,9 +228,9 @@
         JNU_ThrowOutOfMemoryError(env, NULL);
         return NULL;
     }
-    VerifyFixClassname(clname);
+    fixClassname(clname);
 
-    if (!VerifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */
+    if (!verifyClassname(clname, JNI_TRUE)) {  /* expects slashed name */
         goto done;
     }
 
--- a/src/java.base/share/native/libjava/VM.c	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/VM.c	Tue Oct 08 11:57:11 2019 +0200
@@ -42,11 +42,6 @@
 
 JNIEXPORT void JNICALL
 Java_jdk_internal_misc_VM_initialize(JNIEnv *env, jclass cls) {
-    if (!JDK_InitJvmHandle()) {
-        JNU_ThrowInternalError(env, "Handle for JVM not found for symbol lookup");
-        return;
-    }
-
     // Registers implementations of native methods described in methods[]
     // above.
     // In particular, registers JVM_GetNanoTimeAdjustment as the implementation
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/native/libjava/check_classname.c	Tue Oct 08 11:57:11 2019 +0200
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "jni.h"
+#include "jvm.h"
+#include "check_classname.h"
+
+typedef unsigned short unicode;
+
+static char *
+skip_over_fieldname(char *name, jboolean slash_okay,
+                    unsigned int len);
+static char *
+skip_over_field_signature(char *name, jboolean void_okay,
+                          unsigned int len);
+
+/*
+ * Return non-zero if the character is a valid in JVM class name, zero
+ * otherwise.  The only characters currently disallowed from JVM class
+ * names are given in the table below:
+ *
+ * Character    Hex     Decimal
+ * '.'          0x2e    46
+ * '/'          0x2f    47
+ * ';'          0x3b    59
+ * '['          0x5b    91
+ *
+ * (Method names have further restrictions dealing with the '<' and
+ * '>' characters.)
+ */
+static int isJvmIdentifier(unicode ch) {
+  if( ch > 91 || ch < 46 )
+    return 1;   /* Lowercase ASCII letters are > 91 */
+  else { /* 46 <= ch <= 91 */
+    if (ch <= 90 && ch >= 60) {
+      return 1; /* Uppercase ASCII recognized here */
+    } else { /* ch == 91 || 46 <= ch <= 59 */
+      if (ch == 91 || ch == 59 || ch <= 47)
+        return 0;
+      else
+        return 1;
+    }
+  }
+}
+
+static unicode
+next_utf2unicode(char **utfstring_ptr, int * valid)
+{
+    unsigned char *ptr = (unsigned char *)(*utfstring_ptr);
+    unsigned char ch, ch2, ch3;
+    int length = 1;             /* default length */
+    unicode result = 0x80;      /* default bad result; */
+    *valid = 1;
+    switch ((ch = ptr[0]) >> 4) {
+        default:
+            result = ch;
+            break;
+
+        case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
+            /* Shouldn't happen. */
+            *valid = 0;
+            break;
+
+        case 0xC: case 0xD:
+            /* 110xxxxx  10xxxxxx */
+            if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
+                unsigned char high_five = ch & 0x1F;
+                unsigned char low_six = ch2 & 0x3F;
+                result = (high_five << 6) + low_six;
+                length = 2;
+            }
+            break;
+
+        case 0xE:
+            /* 1110xxxx 10xxxxxx 10xxxxxx */
+            if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
+                if (((ch3 = ptr[2]) & 0xC0) == 0x80) {
+                    unsigned char high_four = ch & 0x0f;
+                    unsigned char mid_six = ch2 & 0x3f;
+                    unsigned char low_six = ch3 & 0x3f;
+                    result = (((high_four << 6) + mid_six) << 6) + low_six;
+                    length = 3;
+                } else {
+                    length = 2;
+                }
+            }
+            break;
+        } /* end of switch */
+
+    *utfstring_ptr = (char *)(ptr + length);
+    return result;
+}
+
+/* Take pointer to a string.  Skip over the longest part of the string that
+ * could be taken as a fieldname.  Allow '/' if slash_okay is JNI_TRUE.
+ *
+ * Return a pointer to just past the fieldname.  Return NULL if no fieldname
+ * at all was found, or in the case of slash_okay being true, we saw
+ * consecutive slashes (meaning we were looking for a qualified path but
+ * found something that was badly-formed).
+ */
+static char *
+skip_over_fieldname(char *name, jboolean slash_okay,
+                    unsigned int length)
+{
+    char *p;
+    unicode ch;
+    unicode last_ch = 0;
+    int valid = 1;
+    /* last_ch == 0 implies we are looking at the first char. */
+    for (p = name; p != name + length; last_ch = ch) {
+        char *old_p = p;
+        ch = *p;
+        if (ch < 128) {
+            p++;
+            if (isJvmIdentifier(ch)) {
+                continue;
+            }
+        } else {
+            char *tmp_p = p;
+            ch = next_utf2unicode(&tmp_p, &valid);
+            if (valid == 0)
+              return 0;
+            p = tmp_p;
+            if (isJvmIdentifier(ch)) {
+                        continue;
+            }
+        }
+
+        if (slash_okay && ch == '/' && last_ch) {
+            if (last_ch == '/') {
+                return 0;       /* Don't permit consecutive slashes */
+            }
+        } else if (ch == '_' || ch == '$') {
+        } else {
+            return last_ch ? old_p : 0;
+        }
+    }
+    return last_ch ? p : 0;
+}
+
+/* Take pointer to a string.  Skip over the longest part of the string that
+ * could be taken as a field signature.  Allow "void" if void_okay.
+ *
+ * Return a pointer to just past the signature.  Return NULL if no legal
+ * signature is found.
+ */
+
+static char *
+skip_over_field_signature(char *name, jboolean void_okay,
+                          unsigned int length)
+{
+    unsigned int array_dim = 0;
+    for (;length > 0;) {
+        switch (name[0]) {
+            case JVM_SIGNATURE_VOID:
+                if (!void_okay) return 0;
+                /* FALL THROUGH */
+            case JVM_SIGNATURE_BOOLEAN:
+            case JVM_SIGNATURE_BYTE:
+            case JVM_SIGNATURE_CHAR:
+            case JVM_SIGNATURE_SHORT:
+            case JVM_SIGNATURE_INT:
+            case JVM_SIGNATURE_FLOAT:
+            case JVM_SIGNATURE_LONG:
+            case JVM_SIGNATURE_DOUBLE:
+                return name + 1;
+
+            case JVM_SIGNATURE_CLASS: {
+                /* Skip over the classname, if one is there. */
+                char *p =
+                    skip_over_fieldname(name + 1, JNI_TRUE, --length);
+                /* The next character better be a semicolon. */
+                if (p && p - name - 1 > 0 && p[0] == ';')
+                    return p + 1;
+                return 0;
+            }
+
+            case JVM_SIGNATURE_ARRAY:
+                array_dim++;
+                /* JVMS 2nd ed. 4.10 */
+                /*   The number of dimensions in an array is limited to 255 ... */
+                if (array_dim > 255) {
+                    return 0;
+                }
+                /* The rest of what's there better be a legal signature.  */
+                name++;
+                length--;
+                void_okay = JNI_FALSE;
+                break;
+
+            default:
+                return 0;
+        }
+    }
+    return 0;
+}
+
+/* Determine if the specified name is legal
+ * UTF name for a classname.
+ *
+ * Note that this routine expects the internal form of qualified classes:
+ * the dots should have been replaced by slashes.
+ */
+jboolean verifyClassname(char *name, jboolean allowArrayClass)
+{
+    size_t s = strlen(name);
+    assert(s <= UINT_MAX);
+    unsigned int length = (unsigned int)s;
+    char *p;
+
+    if (length > 0 && name[0] == JVM_SIGNATURE_ARRAY) {
+        if (!allowArrayClass) {
+            return JNI_FALSE;
+        } else {
+            /* Everything that's left better be a field signature */
+            p = skip_over_field_signature(name, JNI_FALSE, length);
+        }
+    } else {
+        /* skip over the fieldname.  Slashes are okay */
+        p = skip_over_fieldname(name, JNI_TRUE, length);
+    }
+    return (p != 0 && p - name == (ptrdiff_t)length);
+}
+
+/*
+ * Translates '.' to '/'.  Returns JNI_TRUE if any / were present.
+ */
+jboolean verifyFixClassname(char *name)
+{
+    char *p = name;
+    jboolean slashesFound = JNI_FALSE;
+    int valid = 1;
+
+    while (valid != 0 && *p != '\0') {
+        if (*p == '/') {
+            slashesFound = JNI_TRUE;
+            p++;
+        } else if (*p == '.') {
+            *p++ = '/';
+        } else {
+            next_utf2unicode(&p, &valid);
+        }
+    }
+
+    return slashesFound && valid != 0;
+}
+
+/*
+ * Translates '.' to '/'.
+ */
+void fixClassname(char *name)
+{
+    char *p = name;
+    int valid = 1;
+
+    while (valid != 0 && *p != '\0') {
+        if (*p == '.') {
+            *p++ = '/';
+        } else {
+            next_utf2unicode(&p, &valid);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/native/libjava/check_classname.h	Tue Oct 08 11:57:11 2019 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+
+/*
+ * Class name checking methods
+ */
+
+jboolean verifyClassname(char *name, jboolean allowArrayClass);
+jboolean verifyFixClassname(char *name);
+void fixClassname(char *name);
--- a/src/java.base/share/native/libjava/jdk_util.h	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/jdk_util.h	Tue Oct 08 11:57:11 2019 +0200
@@ -45,20 +45,6 @@
 JNIEXPORT void
 JDK_GetVersionInfo0(jdk_version_info* info, size_t info_size);
 
-
-/*-------------------------------------------------------
- * Internal interface for JDK to use
- *-------------------------------------------------------
- */
-
-/* Init JVM handle for symbol lookup;
- * Return 0 if JVM handle not found.
- */
-int JDK_InitJvmHandle();
-
-/* Find the named JVM entry; returns NULL if not found. */
-void* JDK_FindJvmEntry(const char* name);
-
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* __cplusplus */
--- a/src/java.base/share/native/libjava/jni_util.c	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/jni_util.c	Tue Oct 08 11:57:11 2019 +0200
@@ -77,77 +77,23 @@
 }
 
 JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/IllegalAccessError", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/IllegalAccessException", msg);
-}
-
-JNIEXPORT void JNICALL
 JNU_ThrowInternalError(JNIEnv *env, const char *msg)
 {
     JNU_ThrowByName(env, "java/lang/InternalError", msg);
 }
 
 JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/NoSuchFieldException", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/NoSuchMethodException", msg);
-}
-
-JNIEXPORT void JNICALL
 JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg)
 {
     JNU_ThrowByName(env, "java/lang/ClassNotFoundException", msg);
 }
 
 JNIEXPORT void JNICALL
-JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/NumberFormatException", msg);
-}
-
-JNIEXPORT void JNICALL
 JNU_ThrowIOException(JNIEnv *env, const char *msg)
 {
     JNU_ThrowByName(env, "java/io/IOException", msg);
 }
 
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/NoSuchFieldError", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/NoSuchMethodError", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/StringIndexOutOfBoundsException", msg);
-}
-
-JNIEXPORT void JNICALL
-JNU_ThrowInstantiationException(JNIEnv *env, const char *msg)
-{
-    JNU_ThrowByName(env, "java/lang/InstantiationException", msg);
-}
-
 /*
  * Throw an exception by name, using the string returned by
  * getLastErrorString for the detail string. If the last-error
@@ -845,12 +791,6 @@
     CHECK_NULL(String_value_ID);
 }
 
-JNIEXPORT jstring
-NewStringPlatform(JNIEnv *env, const char *str)
-{
-    return JNU_NewStringPlatform(env, str);
-}
-
 JNIEXPORT jstring JNICALL
 JNU_NewStringPlatform(JNIEnv *env, const char *str)
 {
@@ -1024,54 +964,6 @@
     return cls;
 }
 
-JNIEXPORT jclass JNICALL
-JNU_ClassClass(JNIEnv *env)
-{
-    static jclass cls = 0;
-    if (cls == 0) {
-        jclass c;
-        if ((*env)->EnsureLocalCapacity(env, 1) < 0)
-            return 0;
-        c = (*env)->FindClass(env, "java/lang/Class");
-        CHECK_NULL_RETURN(c, NULL);
-        cls = (*env)->NewGlobalRef(env, c);
-        (*env)->DeleteLocalRef(env, c);
-    }
-    return cls;
-}
-
-JNIEXPORT jclass JNICALL
-JNU_ClassObject(JNIEnv *env)
-{
-    static jclass cls = 0;
-    if (cls == 0) {
-        jclass c;
-        if ((*env)->EnsureLocalCapacity(env, 1) < 0)
-            return 0;
-        c = (*env)->FindClass(env, "java/lang/Object");
-        CHECK_NULL_RETURN(c, NULL);
-        cls = (*env)->NewGlobalRef(env, c);
-        (*env)->DeleteLocalRef(env, c);
-    }
-    return cls;
-}
-
-JNIEXPORT jclass JNICALL
-JNU_ClassThrowable(JNIEnv *env)
-{
-    static jclass cls = 0;
-    if (cls == 0) {
-        jclass c;
-        if ((*env)->EnsureLocalCapacity(env, 1) < 0)
-            return 0;
-        c = (*env)->FindClass(env, "java/lang/Throwable");
-        CHECK_NULL_RETURN(c, NULL);
-        cls = (*env)->NewGlobalRef(env, c);
-        (*env)->DeleteLocalRef(env, c);
-    }
-    return cls;
-}
-
 JNIEXPORT jint JNICALL
 JNU_CopyObjectArray(JNIEnv *env, jobjectArray dst, jobjectArray src,
                          jint count)
@@ -1110,125 +1002,10 @@
     return JNI_ERR;
 }
 
-JNIEXPORT jboolean JNICALL
-JNU_Equals(JNIEnv *env, jobject object1, jobject object2)
-{
-    static jmethodID mid = NULL;
-    if (mid == NULL) {
-        jclass objClazz = JNU_ClassObject(env);
-        CHECK_NULL_RETURN(objClazz, JNI_FALSE);
-        mid = (*env)->GetMethodID(env, objClazz, "equals",
-                                  "(Ljava/lang/Object;)Z");
-        CHECK_NULL_RETURN(mid, JNI_FALSE);
-    }
-    return (*env)->CallBooleanMethod(env, object1, mid, object2);
-}
-
-
-/************************************************************************
- * Thread calls
- */
-
-static jmethodID Object_waitMID;
-static jmethodID Object_notifyMID;
-static jmethodID Object_notifyAllMID;
-
-JNIEXPORT void JNICALL
-JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout)
-{
-    if (object == NULL) {
-        JNU_ThrowNullPointerException(env, "JNU_MonitorWait argument");
-        return;
-    }
-    if (Object_waitMID == NULL) {
-        jclass cls = JNU_ClassObject(env);
-        if (cls == NULL) {
-            return;
-        }
-        Object_waitMID = (*env)->GetMethodID(env, cls, "wait", "(J)V");
-        if (Object_waitMID == NULL) {
-            return;
-        }
-    }
-    (*env)->CallVoidMethod(env, object, Object_waitMID, timeout);
-}
-
-JNIEXPORT void JNICALL
-JNU_Notify(JNIEnv *env, jobject object)
-{
-    if (object == NULL) {
-        JNU_ThrowNullPointerException(env, "JNU_Notify argument");
-        return;
-    }
-    if (Object_notifyMID == NULL) {
-        jclass cls = JNU_ClassObject(env);
-        if (cls == NULL) {
-            return;
-        }
-        Object_notifyMID = (*env)->GetMethodID(env, cls, "notify", "()V");
-        if (Object_notifyMID == NULL) {
-            return;
-        }
-    }
-    (*env)->CallVoidMethod(env, object, Object_notifyMID);
-}
-
-JNIEXPORT void JNICALL
-JNU_NotifyAll(JNIEnv *env, jobject object)
-{
-    if (object == NULL) {
-        JNU_ThrowNullPointerException(env, "JNU_NotifyAll argument");
-        return;
-    }
-    if (Object_notifyAllMID == NULL) {
-        jclass cls = JNU_ClassObject(env);
-        if (cls == NULL) {
-            return;
-        }
-        Object_notifyAllMID = (*env)->GetMethodID(env, cls,"notifyAll", "()V");
-        if (Object_notifyAllMID == NULL) {
-            return;
-        }
-    }
-    (*env)->CallVoidMethod(env, object, Object_notifyAllMID);
-}
-
-
 /************************************************************************
  * Debugging utilities
  */
 
-JNIEXPORT void JNICALL
-JNU_PrintString(JNIEnv *env, char *hdr, jstring string)
-{
-    if (string == NULL) {
-        fprintf(stderr, "%s: is NULL\n", hdr);
-    } else {
-        const char *stringPtr = JNU_GetStringPlatformChars(env, string, 0);
-        if (stringPtr == 0)
-            return;
-        fprintf(stderr, "%s: %s\n", hdr, stringPtr);
-        JNU_ReleaseStringPlatformChars(env, string, stringPtr);
-    }
-}
-
-JNIEXPORT void JNICALL
-JNU_PrintClass(JNIEnv *env, char* hdr, jobject object)
-{
-    if (object == NULL) {
-        fprintf(stderr, "%s: object is NULL\n", hdr);
-        return;
-    } else {
-        jclass cls = (*env)->GetObjectClass(env, object);
-        jstring clsName = JNU_ToString(env, cls);
-        if (clsName == NULL) {
-            JNU_PrintString(env, hdr, clsName);
-        }
-        (*env)->DeleteLocalRef(env, cls);
-        (*env)->DeleteLocalRef(env, clsName);
-    }
-}
-
 JNIEXPORT jstring JNICALL
 JNU_ToString(JNIEnv *env, jobject object)
 {
@@ -1437,70 +1214,3 @@
     }
     return result;
 }
-
-JNIEXPORT void JNICALL
-JNU_SetStaticFieldByName(JNIEnv *env,
-                         jboolean *hasException,
-                         const char *classname,
-                         const char *name,
-                         const char *signature,
-                         ...)
-{
-    jclass cls;
-    jfieldID fid;
-    va_list args;
-
-    if ((*env)->EnsureLocalCapacity(env, 3) < 0)
-        goto done2;
-
-    cls = (*env)->FindClass(env, classname);
-    if (cls == 0)
-        goto done2;
-
-    fid = (*env)->GetStaticFieldID(env, cls, name, signature);
-    if (fid == 0)
-        goto done1;
-
-    va_start(args, signature);
-    switch (*signature) {
-    case '[':
-    case 'L':
-        (*env)->SetStaticObjectField(env, cls, fid, va_arg(args, jobject));
-        break;
-    case 'Z':
-        (*env)->SetStaticBooleanField(env, cls, fid, (jboolean)va_arg(args, int));
-        break;
-    case 'B':
-        (*env)->SetStaticByteField(env, cls, fid, (jbyte)va_arg(args, int));
-        break;
-    case 'C':
-        (*env)->SetStaticCharField(env, cls, fid, (jchar)va_arg(args, int));
-        break;
-    case 'S':
-        (*env)->SetStaticShortField(env, cls, fid, (jshort)va_arg(args, int));
-        break;
-    case 'I':
-        (*env)->SetStaticIntField(env, cls, fid, va_arg(args, jint));
-        break;
-    case 'J':
-        (*env)->SetStaticLongField(env, cls, fid, va_arg(args, jlong));
-        break;
-    case 'F':
-        (*env)->SetStaticFloatField(env, cls, fid, (jfloat)va_arg(args, jdouble));
-        break;
-    case 'D':
-        (*env)->SetStaticDoubleField(env, cls, fid, va_arg(args, jdouble));
-        break;
-
-    default:
-        (*env)->FatalError(env, "JNU_SetStaticFieldByName: illegal signature");
-    }
-    va_end(args);
-
- done1:
-    (*env)->DeleteLocalRef(env, cls);
- done2:
-    if (hasException) {
-        *hasException = (*env)->ExceptionCheck(env);
-    }
-}
--- a/src/java.base/share/native/libjava/jni_util.h	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libjava/jni_util.h	Tue Oct 08 11:57:11 2019 +0200
@@ -62,41 +62,14 @@
 JNU_ThrowIllegalArgumentException(JNIEnv *env, const char *msg);
 
 JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessError(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowIllegalAccessException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
 JNU_ThrowInternalError(JNIEnv *env, const char *msg);
 
 JNIEXPORT void JNICALL
 JNU_ThrowIOException(JNIEnv *env, const char *msg);
 
 JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
 JNU_ThrowClassNotFoundException(JNIEnv *env, const char *msg);
 
-JNIEXPORT void JNICALL
-JNU_ThrowNumberFormatException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchFieldError(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowNoSuchMethodError(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowStringIndexOutOfBoundsException(JNIEnv *env, const char *msg);
-
-JNIEXPORT void JNICALL
-JNU_ThrowInstantiationException(JNIEnv *env, const char *msg);
-
 /* Throw an exception by name, using the string returned by
  * getLastErrorString for the detail string. If the last-error
  * string is NULL, use the given default detail string.
@@ -120,9 +93,6 @@
 JNU_ThrowIOExceptionWithLastError(JNIEnv *env, const char *defaultDetail);
 
 /* Convert between Java strings and i18n C strings */
-JNIEXPORT jstring
-NewStringPlatform(JNIEnv *env, const char *str);
-
 JNIEXPORT const char *
 GetStringPlatformChars(JNIEnv *env, jstring jstr, jboolean *isCopy);
 
@@ -139,15 +109,6 @@
 JNIEXPORT jclass JNICALL
 JNU_ClassString(JNIEnv *env);
 
-JNIEXPORT jclass JNICALL
-JNU_ClassClass(JNIEnv *env);
-
-JNIEXPORT jclass JNICALL
-JNU_ClassObject(JNIEnv *env);
-
-JNIEXPORT jclass JNICALL
-JNU_ClassThrowable(JNIEnv *env);
-
 /* Copy count number of arguments from src to dst. Array bounds
  * and ArrayStoreException are checked.
  */
@@ -246,36 +207,6 @@
                          const char *classname,
                          const char *name,
                          const char *sig);
-JNIEXPORT void JNICALL
-JNU_SetStaticFieldByName(JNIEnv *env,
-                         jboolean *hasException,
-                         const char *classname,
-                         const char *name,
-                         const char *sig,
-                         ...);
-
-
-/*
- * Calls the .equals method.
- */
-JNIEXPORT jboolean JNICALL
-JNU_Equals(JNIEnv *env, jobject object1, jobject object2);
-
-
-/************************************************************************
- * Thread calls
- *
- * Convenience thread-related calls on the java.lang.Object class.
- */
-
-JNIEXPORT void JNICALL
-JNU_MonitorWait(JNIEnv *env, jobject object, jlong timeout);
-
-JNIEXPORT void JNICALL
-JNU_Notify(JNIEnv *env, jobject object);
-
-JNIEXPORT void JNICALL
-JNU_NotifyAll(JNIEnv *env, jobject object);
 
 
 /************************************************************************
@@ -349,19 +280,15 @@
         }                                       \
     } while (0)
 #endif /* __cplusplus */
+
 /************************************************************************
  * Debugging utilities
  */
 
-JNIEXPORT void JNICALL
-JNU_PrintString(JNIEnv *env, char *hdr, jstring string);
-
-JNIEXPORT void JNICALL
-JNU_PrintClass(JNIEnv *env, char *hdr, jobject object);
-
 JNIEXPORT jstring JNICALL
 JNU_ToString(JNIEnv *env, jobject object);
 
+
 /*
  * Package shorthand for use by native libraries
  */
@@ -402,8 +329,6 @@
     FAST_UTF_8
 };
 
-int getFastEncoding();
-
 JNIEXPORT void InitializeEncoding(JNIEnv *env, const char *name);
 
 void* getProcessHandle();
--- a/src/java.base/share/native/libjava/verify_stub.c	Mon Oct 07 20:15:47 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 1999, 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-
-/*
- * The real verifier now lives in libverifier.so/verifier.dll.
- *
- * This dummy exists so that HotSpot will run with the new
- * libjava.so/java.dll which is where is it accustomed to finding the
- * verifier.
- */
-
-#include "jni.h"
-
-struct struct_class_size_info;
-typedef struct struct_class_size_info class_size_info;
-
-
-JNIIMPORT jboolean
-VerifyClass(JNIEnv *env, jclass cb, char *buffer, jint len);
-
-JNIIMPORT jboolean
-VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *buffer, jint len,
-                           jint major_version);
-
-JNIEXPORT jboolean
-VerifyClassCodes(JNIEnv *env, jclass cb, char *buffer, jint len)
-{
-    return VerifyClass(env, cb, buffer, len);
-}
-
-JNIEXPORT jboolean
-VerifyClassCodesForMajorVersion(JNIEnv *env, jclass cb, char *buffer,
-                                jint len, jint major_version)
-{
-    return VerifyClassForMajorVersion(env, cb, buffer, len, major_version);
-}
--- a/src/java.base/share/native/libverify/check_code.c	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/share/native/libverify/check_code.c	Tue Oct 08 11:57:11 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,9 +31,6 @@
    Exported function:
 
    jboolean
-   VerifyClass(JNIEnv *env, jclass cb, char *message_buffer,
-               jint buffer_length)
-   jboolean
    VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *message_buffer,
                               jint buffer_length, jint major_version)
 
@@ -910,20 +907,6 @@
     return result;
 }
 
-#define OLD_FORMAT_MAX_MAJOR_VERSION 48
-
-JNIEXPORT jboolean
-VerifyClass(JNIEnv *env, jclass cb, char *buffer, jint len)
-{
-    static int warned = 0;
-    if (!warned) {
-      jio_fprintf(stdout, "Warning! An old version of jvm is used. This is not supported.\n");
-      warned = 1;
-    }
-    return VerifyClassForMajorVersion(env, cb, buffer, len,
-                                      OLD_FORMAT_MAX_MAJOR_VERSION);
-}
-
 static void
 verify_field(context_type *context, jclass cb, int field_index)
 {
--- a/src/java.base/share/native/libverify/check_format.c	Mon Oct 07 20:15:47 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-/*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <assert.h>
-#include <limits.h>
-#include <setjmp.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "jni.h"
-#include "jvm.h"
-
-typedef unsigned short unicode;
-
-static char *
-skip_over_fieldname(char *name, jboolean slash_okay,
-                    unsigned int len);
-static char *
-skip_over_field_signature(char *name, jboolean void_okay,
-                          unsigned int len);
-
-/*
- * Return non-zero if the character is a valid in JVM class name, zero
- * otherwise.  The only characters currently disallowed from JVM class
- * names are given in the table below:
- *
- * Character    Hex     Decimal
- * '.'          0x2e    46
- * '/'          0x2f    47
- * ';'          0x3b    59
- * '['          0x5b    91
- *
- * (Method names have further restrictions dealing with the '<' and
- * '>' characters.)
- */
-static int isJvmIdentifier(unicode ch) {
-  if( ch > 91 || ch < 46 )
-    return 1;   /* Lowercase ASCII letters are > 91 */
-  else { /* 46 <= ch <= 91 */
-    if (ch <= 90 && ch >= 60) {
-      return 1; /* Uppercase ASCII recognized here */
-    } else { /* ch == 91 || 46 <= ch <= 59 */
-      if (ch == 91 || ch == 59 || ch <= 47)
-        return 0;
-      else
-        return 1;
-    }
-  }
-}
-
-static unicode
-next_utf2unicode(char **utfstring_ptr, int * valid)
-{
-    unsigned char *ptr = (unsigned char *)(*utfstring_ptr);
-    unsigned char ch, ch2, ch3;
-    int length = 1;             /* default length */
-    unicode result = 0x80;      /* default bad result; */
-    *valid = 1;
-    switch ((ch = ptr[0]) >> 4) {
-        default:
-            result = ch;
-            break;
-
-        case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
-            /* Shouldn't happen. */
-            *valid = 0;
-            break;
-
-        case 0xC: case 0xD:
-            /* 110xxxxx  10xxxxxx */
-            if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
-                unsigned char high_five = ch & 0x1F;
-                unsigned char low_six = ch2 & 0x3F;
-                result = (high_five << 6) + low_six;
-                length = 2;
-            }
-            break;
-
-        case 0xE:
-            /* 1110xxxx 10xxxxxx 10xxxxxx */
-            if (((ch2 = ptr[1]) & 0xC0) == 0x80) {
-                if (((ch3 = ptr[2]) & 0xC0) == 0x80) {
-                    unsigned char high_four = ch & 0x0f;
-                    unsigned char mid_six = ch2 & 0x3f;
-                    unsigned char low_six = ch3 & 0x3f;
-                    result = (((high_four << 6) + mid_six) << 6) + low_six;
-                    length = 3;
-                } else {
-                    length = 2;
-                }
-            }
-            break;
-        } /* end of switch */
-
-    *utfstring_ptr = (char *)(ptr + length);
-    return result;
-}
-
-/* Take pointer to a string.  Skip over the longest part of the string that
- * could be taken as a fieldname.  Allow '/' if slash_okay is JNI_TRUE.
- *
- * Return a pointer to just past the fieldname.  Return NULL if no fieldname
- * at all was found, or in the case of slash_okay being true, we saw
- * consecutive slashes (meaning we were looking for a qualified path but
- * found something that was badly-formed).
- */
-static char *
-skip_over_fieldname(char *name, jboolean slash_okay,
-                    unsigned int length)
-{
-    char *p;
-    unicode ch;
-    unicode last_ch = 0;
-    int valid = 1;
-    /* last_ch == 0 implies we are looking at the first char. */
-    for (p = name; p != name + length; last_ch = ch) {
-        char *old_p = p;
-        ch = *p;
-        if (ch < 128) {
-            p++;
-            if (isJvmIdentifier(ch)) {
-                continue;
-            }
-        } else {
-            char *tmp_p = p;
-            ch = next_utf2unicode(&tmp_p, &valid);
-            if (valid == 0)
-              return 0;
-            p = tmp_p;
-            if (isJvmIdentifier(ch)) {
-                        continue;
-            }
-        }
-
-        if (slash_okay && ch == '/' && last_ch) {
-            if (last_ch == '/') {
-                return 0;       /* Don't permit consecutive slashes */
-            }
-        } else if (ch == '_' || ch == '$') {
-        } else {
-            return last_ch ? old_p : 0;
-        }
-    }
-    return last_ch ? p : 0;
-}
-
-/* Take pointer to a string.  Skip over the longest part of the string that
- * could be taken as a field signature.  Allow "void" if void_okay.
- *
- * Return a pointer to just past the signature.  Return NULL if no legal
- * signature is found.
- */
-
-static char *
-skip_over_field_signature(char *name, jboolean void_okay,
-                          unsigned int length)
-{
-    unsigned int array_dim = 0;
-    for (;length > 0;) {
-        switch (name[0]) {
-            case JVM_SIGNATURE_VOID:
-                if (!void_okay) return 0;
-                /* FALL THROUGH */
-            case JVM_SIGNATURE_BOOLEAN:
-            case JVM_SIGNATURE_BYTE:
-            case JVM_SIGNATURE_CHAR:
-            case JVM_SIGNATURE_SHORT:
-            case JVM_SIGNATURE_INT:
-            case JVM_SIGNATURE_FLOAT:
-            case JVM_SIGNATURE_LONG:
-            case JVM_SIGNATURE_DOUBLE:
-                return name + 1;
-
-            case JVM_SIGNATURE_CLASS: {
-                /* Skip over the classname, if one is there. */
-                char *p =
-                    skip_over_fieldname(name + 1, JNI_TRUE, --length);
-                /* The next character better be a semicolon. */
-                if (p && p - name - 1 > 0 && p[0] == ';')
-                    return p + 1;
-                return 0;
-            }
-
-            case JVM_SIGNATURE_ARRAY:
-                array_dim++;
-                /* JVMS 2nd ed. 4.10 */
-                /*   The number of dimensions in an array is limited to 255 ... */
-                if (array_dim > 255) {
-                    return 0;
-                }
-                /* The rest of what's there better be a legal signature.  */
-                name++;
-                length--;
-                void_okay = JNI_FALSE;
-                break;
-
-            default:
-                return 0;
-        }
-    }
-    return 0;
-}
-
-
-/* Used in java/lang/Class.c */
-/* Determine if the specified name is legal
- * UTF name for a classname.
- *
- * Note that this routine expects the internal form of qualified classes:
- * the dots should have been replaced by slashes.
- */
-JNIEXPORT jboolean
-VerifyClassname(char *name, jboolean allowArrayClass)
-{
-    size_t s = strlen(name);
-    assert(s <= UINT_MAX);
-    unsigned int length = (unsigned int)s;
-    char *p;
-
-    if (length > 0 && name[0] == JVM_SIGNATURE_ARRAY) {
-        if (!allowArrayClass) {
-            return JNI_FALSE;
-        } else {
-            /* Everything that's left better be a field signature */
-            p = skip_over_field_signature(name, JNI_FALSE, length);
-        }
-    } else {
-        /* skip over the fieldname.  Slashes are okay */
-        p = skip_over_fieldname(name, JNI_TRUE, length);
-    }
-    return (p != 0 && p - name == (ptrdiff_t)length);
-}
-
-/*
- * Translates '.' to '/'.  Returns JNI_TRUE is any / were present.
- */
-JNIEXPORT jboolean
-VerifyFixClassname(char *name)
-{
-    char *p = name;
-    jboolean slashesFound = JNI_FALSE;
-    int valid = 1;
-
-    while (valid != 0 && *p != '\0') {
-        if (*p == '/') {
-            slashesFound = JNI_TRUE;
-            p++;
-        } else if (*p == '.') {
-            *p++ = '/';
-        } else {
-            next_utf2unicode(&p, &valid);
-        }
-    }
-
-    return slashesFound && valid != 0;
-}
--- a/src/java.base/unix/native/libjava/jdk_util_md.c	Mon Oct 07 20:15:47 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <dlfcn.h>
-#include "jdk_util.h"
-
-int JDK_InitJvmHandle() {
-    /* nop */
-    return 1;
-}
-
-void* JDK_FindJvmEntry(const char* name) {
-    return dlsym(RTLD_DEFAULT, name);
-}
--- a/src/java.base/windows/native/libjava/jdk_util_md.c	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/java.base/windows/native/libjava/jdk_util_md.c	Tue Oct 08 11:57:11 2019 +0200
@@ -28,17 +28,6 @@
 
 #define JVM_DLL "jvm.dll"
 
-static HMODULE jvm_handle = NULL;
-
-int JDK_InitJvmHandle() {
-    jvm_handle = GetModuleHandle(JVM_DLL);
-    return (jvm_handle != NULL);
-}
-
-void* JDK_FindJvmEntry(const char* name) {
-    return (void*) GetProcAddress(jvm_handle, name);
-}
-
 JNIEXPORT HMODULE JDK_LoadSystemLibrary(const char* name) {
     HMODULE handle = NULL;
     char path[MAX_PATH];
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11AEADCipher.java	Tue Oct 08 11:57:11 2019 +0200
@@ -378,9 +378,6 @@
 
         long p11KeyID = p11Key.getKeyID();
         try {
-            if (session == null) {
-                session = token.getOpSession();
-            }
             CK_MECHANISM mechWithParams;
             switch (blockMode) {
                 case MODE_GCM:
@@ -390,6 +387,9 @@
                 default:
                     throw new ProviderException("Unsupported mode: " + blockMode);
             }
+            if (session == null) {
+                session = token.getOpSession();
+            }
             if (encrypt) {
                 token.p11.C_EncryptInit(session.id(), mechWithParams,
                     p11KeyID);
@@ -398,7 +398,6 @@
                     p11KeyID);
             }
         } catch (PKCS11Exception e) {
-            //e.printStackTrace();
             p11Key.releaseKeyID();
             session = token.releaseSession(session);
             throw e;
@@ -718,7 +717,9 @@
                    errorCode == CKR_ENCRYPTED_DATA_LEN_RANGE) {
             throw (IllegalBlockSizeException)
                     (new IllegalBlockSizeException(e.toString()).initCause(e));
-        } else if (errorCode == CKR_ENCRYPTED_DATA_INVALID) {
+        } else if (errorCode == CKR_ENCRYPTED_DATA_INVALID ||
+                // Solaris-specific
+                errorCode == CKR_GENERAL_ERROR) {
             throw (BadPaddingException)
                     (new BadPaddingException(e.toString()).initCause(e));
         }
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Digest.java	Tue Oct 08 11:57:11 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -103,9 +103,11 @@
             digestLength = 20;
             break;
         case (int)CKM_SHA224:
+        case (int)CKM_SHA512_224:
             digestLength = 28;
             break;
         case (int)CKM_SHA256:
+        case (int)CKM_SHA512_256:
             digestLength = 32;
             break;
         case (int)CKM_SHA384:
--- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/P11Mac.java	Tue Oct 08 11:57:11 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -91,9 +91,11 @@
             macLength = 20;
             break;
         case (int)CKM_SHA224_HMAC:
+        case (int)CKM_SHA512_224_HMAC:
             macLength = 28;
             break;
         case (int)CKM_SHA256_HMAC:
+        case (int)CKM_SHA512_256_HMAC:
             macLength = 32;
             break;
         case (int)CKM_SHA384_HMAC:
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_convert.c	Tue Oct 08 11:57:11 2019 +0200
@@ -721,7 +721,7 @@
     }
 
     // populate using java values
-    ckParamPtr->prfMechanism = jLongToCKULong(jPrfMechanism);
+    ckParamPtr->prfHashMechanism = jLongToCKULong(jPrfMechanism);
     ckParamPtr->ulMacLength = jLongToCKULong(jUlMacLength);
     ckParamPtr->ulServerOrClient = jLongToCKULong(jUlServerOrClient);
 
@@ -1014,17 +1014,18 @@
 }
 
 /*
- * converts the Java CK_GCM_PARAMS object to a CK_GCM_PARAMS pointer
+ * converts the Java CK_GCM_PARAMS object to a CK_GCM_PARAMS_NO_IVBITS pointer
+ * Note: Need to try NSS definition first to avoid SIGSEGV.
  *
  * @param env - used to call JNI funktions to get the Java classes and objects
  * @param jParam - the Java CK_GCM_PARAMS object to convert
  * @param pLength - length of the allocated memory of the returned pointer
- * @return pointer to the new CK_GCM_PARAMS structure
+ * @return pointer to the new CK_GCM_PARAMS_NO_IVBITS structure
  */
-CK_GCM_PARAMS_PTR
+CK_GCM_PARAMS_NO_IVBITS_PTR
 jGCMParamsToCKGCMParamPtr(JNIEnv *env, jobject jParam, CK_ULONG *pLength)
 {
-    CK_GCM_PARAMS_PTR ckParamPtr;
+    CK_GCM_PARAMS_NO_IVBITS_PTR ckParamPtr;
     jclass jGcmParamsClass;
     jfieldID fieldID;
     jobject jIv, jAad;
@@ -1052,8 +1053,8 @@
     if (fieldID == NULL) { return NULL; }
     jTagLen = (*env)->GetLongField(env, jParam, fieldID);
 
-    // allocate memory for CK_GCM_PARAMS pointer
-    ckParamPtr = calloc(1, sizeof(CK_GCM_PARAMS));
+    // allocate memory for CK_GCM_PARAMS_NO_IVBITS pointer
+    ckParamPtr = calloc(1, sizeof(CK_GCM_PARAMS_NO_IVBITS));
     if (ckParamPtr == NULL) {
         throwOutOfMemoryError(env, 0);
         return NULL;
@@ -1073,16 +1074,15 @@
     ckParamPtr->ulTagBits = jLongToCKULong(jTagLen);
 
     if (pLength != NULL) {
-        *pLength = sizeof(CK_GCM_PARAMS);
+        *pLength = sizeof(CK_GCM_PARAMS_NO_IVBITS);
     }
-    TRACE1("Created inner GCM_PARAMS PTR %lX\n", ptr_to_jlong(ckParamPtr));
+    TRACE1("Created inner GCM_PARAMS PTR w/o ulIvBits %p\n", ckParamPtr);
     return ckParamPtr;
 cleanup:
     free(ckParamPtr->pIv);
     free(ckParamPtr->pAAD);
     free(ckParamPtr);
     return NULL;
-
 }
 
 /*
@@ -1179,7 +1179,7 @@
         throwOutOfMemoryError(env, 0);
         return NULL;
     }
-    TRACE1("DEBUG jMechanismToCKMechanismPtr: allocated mech %p \n", ckpMech);
+    TRACE1("DEBUG jMechanismToCKMechanismPtr: allocated mech %p\n", ckpMech);
 
     ckpMech->mechanism = jLongToCKULong(jMechType);
 
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_crypt.c	Tue Oct 08 11:57:11 2019 +0200
@@ -72,6 +72,7 @@
 {
     CK_SESSION_HANDLE ckSessionHandle;
     CK_MECHANISM_PTR ckpMechanism = NULL;
+    CK_MECHANISM_PTR ckpTemp;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
@@ -81,15 +82,32 @@
     ckSessionHandle = jLongToCKULong(jSessionHandle);
     ckKeyHandle = jLongToCKULong(jKeyHandle);
     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
+    TRACE1("DEBUG C_EncryptInit: created pMech = %p\n",
+            ckpMechanism);
+
     if ((*env)->ExceptionCheck(env)) { return; }
 
     rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, ckpMechanism,
                                         ckKeyHandle);
 
-    // if OAEP, then cannot free here
+    if (ckpMechanism->mechanism == CKM_AES_GCM) {
+        if (rv == CKR_ARGUMENTS_BAD || rv == CKR_MECHANISM_PARAM_INVALID) {
+            // retry with CKM_GCM_PARAMS structure in pkcs11t.h
+            TRACE0("DEBUG C_EncryptInit: retry with CK_GCM_PARAMS\n");
+            ckpTemp = updateGCMParams(env, ckpMechanism);
+            if (ckpTemp != NULL) { // only re-call if conversion succeeds
+                ckpMechanism = ckpTemp;
+                rv = (*ckpFunctions->C_EncryptInit)(ckSessionHandle, ckpMechanism,
+                        ckKeyHandle);
+            }
+        }
+    }
+
+    TRACE1("DEBUG C_EncryptInit: freed pMech = %p\n", ckpMechanism);
     freeCKMechanismPtr(ckpMechanism);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    TRACE0("FINISHED\n");
 }
 #endif
 
@@ -292,6 +310,7 @@
 {
     CK_SESSION_HANDLE ckSessionHandle;
     CK_MECHANISM_PTR ckpMechanism = NULL;
+    CK_MECHANISM_PTR ckpTemp;
     CK_OBJECT_HANDLE ckKeyHandle;
     CK_RV rv;
 
@@ -301,15 +320,32 @@
     ckSessionHandle = jLongToCKULong(jSessionHandle);
     ckKeyHandle = jLongToCKULong(jKeyHandle);
     ckpMechanism = jMechanismToCKMechanismPtr(env, jMechanism);
+    TRACE1("DEBUG C_DecryptInit: created pMech = %p\n",
+            ckpMechanism);
+
     if ((*env)->ExceptionCheck(env)) { return; }
 
     rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, ckpMechanism,
                                         ckKeyHandle);
 
-    // if OAEP, then cannot free here
+    if (ckpMechanism->mechanism == CKM_AES_GCM) {
+        if (rv == CKR_ARGUMENTS_BAD || rv == CKR_MECHANISM_PARAM_INVALID) {
+            // retry with CKM_GCM_PARAMS structure in pkcs11t.h
+            TRACE0("DEBUG C_DecryptInit: retry with CK_GCM_PARAMS\n");
+            ckpTemp = updateGCMParams(env, ckpMechanism);
+            if (ckpTemp != NULL) { // only re-call if conversion succeeds
+                ckpMechanism = ckpTemp;
+                rv = (*ckpFunctions->C_DecryptInit)(ckSessionHandle, ckpMechanism,
+                        ckKeyHandle);
+            }
+        }
+    }
+
+    TRACE1("DEBUG C_DecryptInit: freed pMech = %p\n", ckpMechanism);
     freeCKMechanismPtr(ckpMechanism);
+    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
 
-    if (ckAssertReturnValueOK(env, rv) != CK_ASSERT_OK) { return; }
+    TRACE0("FINISHED\n");
 }
 #endif
 
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/p11_util.c	Tue Oct 08 11:57:11 2019 +0200
@@ -302,29 +302,30 @@
      CK_TLS12_KEY_MAT_PARAMS* tlsKmTmp;
 
      if (mechPtr != NULL) {
-         TRACE2("DEBUG: free mech %lX (mech id = 0x%lX)\n",
-                 ptr_to_jlong(mechPtr),  mechPtr->mechanism);
+         TRACE2("DEBUG freeCKMechanismPtr: free pMech %p (mech 0x%lX)\n",
+                 mechPtr,  mechPtr->mechanism);
          if (mechPtr->pParameter != NULL) {
+             tmp = mechPtr->pParameter;
              switch (mechPtr->mechanism) {
                  case CKM_AES_GCM:
-                     tmp = mechPtr->pParameter;
-                     TRACE1("\t=> free GCM_PARAMS %lX\n",
-                             ptr_to_jlong(tmp));
-                     free(((CK_GCM_PARAMS*)tmp)->pIv);
-                     free(((CK_GCM_PARAMS*)tmp)->pAAD);
+                     if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS)) {
+                         TRACE0("[ GCM_PARAMS w/o ulIvBits ]\n");
+                         free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pIv);
+                         free(((CK_GCM_PARAMS_NO_IVBITS*)tmp)->pAAD);
+                     } else if (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS)) {
+                         TRACE0("[ GCM_PARAMS ]\n");
+                         free(((CK_GCM_PARAMS*)tmp)->pIv);
+                         free(((CK_GCM_PARAMS*)tmp)->pAAD);
+                     }
                      break;
                  case CKM_AES_CCM:
-                     tmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_CCM_PARAMS %lX\n",
-                             ptr_to_jlong(tmp));
+                     TRACE0("[ CK_CCM_PARAMS ]\n");
                      free(((CK_CCM_PARAMS*)tmp)->pNonce);
                      free(((CK_CCM_PARAMS*)tmp)->pAAD);
                      break;
                  case CKM_TLS_PRF:
                  case CKM_NSS_TLS_PRF_GENERAL:
-                     tmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_TLS_PRF_PARAMS %lX\n",
-                         ptr_to_jlong(tmp));
+                     TRACE0("[ CK_TLS_PRF_PARAMS ]\n");
                      free(((CK_TLS_PRF_PARAMS*)tmp)->pSeed);
                      free(((CK_TLS_PRF_PARAMS*)tmp)->pLabel);
                      free(((CK_TLS_PRF_PARAMS*)tmp)->pulOutputLen);
@@ -334,18 +335,16 @@
                  case CKM_TLS_MASTER_KEY_DERIVE:
                  case CKM_SSL3_MASTER_KEY_DERIVE_DH:
                  case CKM_TLS_MASTER_KEY_DERIVE_DH:
-                     sslMkdTmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_SSL3_MASTER_KEY_DERIVE_PARAMS %lX\n",
-                         ptr_to_jlong(sslMkdTmp));
+                     sslMkdTmp = tmp;
+                     TRACE0("[ CK_SSL3_MASTER_KEY_DERIVE_PARAMS ]\n");
                      free(sslMkdTmp->RandomInfo.pClientRandom);
                      free(sslMkdTmp->RandomInfo.pServerRandom);
                      free(sslMkdTmp->pVersion);
                      break;
                  case CKM_SSL3_KEY_AND_MAC_DERIVE:
                  case CKM_TLS_KEY_AND_MAC_DERIVE:
-                     sslKmTmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_SSL3_KEY_MAT_PARAMS %lX\n",
-                         ptr_to_jlong(sslKmTmp));
+                     sslKmTmp = tmp;
+                     TRACE0("[ CK_SSL3_KEY_MAT_PARAMS ]\n");
                      free(sslKmTmp->RandomInfo.pClientRandom);
                      free(sslKmTmp->RandomInfo.pServerRandom);
                      if (sslKmTmp->pReturnedKeyMaterial != NULL) {
@@ -356,17 +355,15 @@
                      break;
                  case CKM_TLS12_MASTER_KEY_DERIVE:
                  case CKM_TLS12_MASTER_KEY_DERIVE_DH:
-                     tlsMkdTmp = mechPtr->pParameter;
-                     TRACE1("\t=> CK_TLS12_MASTER_KEY_DERIVE_PARAMS %lX\n",
-                         ptr_to_jlong(tlsMkdTmp));
+                     tlsMkdTmp = tmp;
+                     TRACE0("[ CK_TLS12_MASTER_KEY_DERIVE_PARAMS ]\n");
                      free(tlsMkdTmp->RandomInfo.pClientRandom);
                      free(tlsMkdTmp->RandomInfo.pServerRandom);
                      free(tlsMkdTmp->pVersion);
                      break;
                  case CKM_TLS12_KEY_AND_MAC_DERIVE:
-                     tlsKmTmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_TLS12_KEY_MAT_PARAMS %lX\n",
-                         ptr_to_jlong(tlsKmTmp));
+                     tlsKmTmp = tmp;
+                     TRACE0("[ CK_TLS12_KEY_MAT_PARAMS ]\n");
                      free(tlsKmTmp->RandomInfo.pClientRandom);
                      free(tlsKmTmp->RandomInfo.pServerRandom);
                      if (tlsKmTmp->pReturnedKeyMaterial != NULL) {
@@ -377,9 +374,7 @@
                      break;
                  case CKM_ECDH1_DERIVE:
                  case CKM_ECDH1_COFACTOR_DERIVE:
-                     tmp = mechPtr->pParameter;
-                     TRACE1("\t=> free CK_ECDH1_DERIVE_PARAMS %lX\n",
-                         ptr_to_jlong(tmp));
+                     TRACE0("[ CK_ECDH1_DERIVE_PARAMS ]\n");
                      free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pSharedData);
                      free(((CK_ECDH1_DERIVE_PARAMS *)tmp)->pPublicData);
                      break;
@@ -387,7 +382,6 @@
                  case CKM_AES_CTR:
                  case CKM_RSA_PKCS_PSS:
                  case CKM_CAMELLIA_CTR:
-                     TRACE0("\t=> NO OP\n");
                      // params do not contain pointers
                      break;
                  default:
@@ -399,17 +393,59 @@
                      // CKM_EXTRACT_KEY_FROM_KEY, CKM_OTP, CKM_KIP,
                      // CKM_DSA_PARAMETER_GEN?, CKM_GOSTR3410_*
                      // CK_any_CBC_ENCRYPT_DATA?
-                     TRACE0("\t=> ERROR UNSUPPORTED CK PARAMS\n");
+                     TRACE0("ERROR: UNSUPPORTED CK_MECHANISM\n");
                      break;
              }
-             free(mechPtr->pParameter);
+             TRACE1("\t=> freed param %p\n", tmp);
+             free(tmp);
          } else {
-             TRACE0("DEBUG => Parameter NULL\n");
+             TRACE0("\t=> param NULL\n");
          }
          free(mechPtr);
+         TRACE0("FINISHED\n");
      }
 }
 
+/* This function replaces the CK_GCM_PARAMS_NO_IVBITS structure associated
+ * with the specified CK_MECHANISM structure with CK_GCM_PARAMS
+ * structure.
+ *
+ * @param mechPtr pointer to the CK_MECHANISM structure containing
+ * the to-be-converted CK_GCM_PARAMS_NO_IVBITS structure.
+ * @return pointer to the CK_MECHANISM structure containing the
+ * converted CK_GCM_PARAMS structure or NULL if no conversion took place.
+ */
+CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr) {
+    CK_GCM_PARAMS* pGcmParams2 = NULL;
+    CK_GCM_PARAMS_NO_IVBITS* pParams = NULL;
+    if ((mechPtr->mechanism == CKM_AES_GCM) &&
+            (mechPtr->pParameter != NULL_PTR) &&
+            (mechPtr->ulParameterLen == sizeof(CK_GCM_PARAMS_NO_IVBITS))) {
+        pGcmParams2 = calloc(1, sizeof(CK_GCM_PARAMS));
+        if (pGcmParams2 == NULL) {
+            throwOutOfMemoryError(env, 0);
+            return NULL;
+        }
+        pParams = (CK_GCM_PARAMS_NO_IVBITS*) mechPtr->pParameter;
+        pGcmParams2->pIv = pParams->pIv;
+        pGcmParams2->ulIvLen = pParams->ulIvLen;
+        pGcmParams2->ulIvBits = (pGcmParams2->ulIvLen << 3);
+        pGcmParams2->pAAD = pParams->pAAD;
+        pGcmParams2->ulAADLen = pParams->ulAADLen;
+        pGcmParams2->ulTagBits = pParams->ulTagBits;
+        TRACE1("DEBUG updateGCMParams: pMech %p\n", mechPtr);
+        TRACE2("\t=> GCM param w/o ulIvBits %p => GCM param %p\n", pParams,
+                pGcmParams2);
+        free(pParams);
+        mechPtr->pParameter = pGcmParams2;
+        mechPtr->ulParameterLen = sizeof(CK_GCM_PARAMS);
+        return mechPtr;
+    } else {
+        TRACE0("DEBUG updateGCMParams: no conversion done\n");
+    }
+    return NULL;
+}
+
 /*
  * the following functions convert Java arrays to PKCS#11 array pointers and
  * their array length and vice versa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11gcm2.h	Tue Oct 08 11:57:11 2019 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* There is a known incompatibility for CK_GCM_PARAMS structure.
+ * PKCS#11 v2.40 standard mechanisms specification specifies
+ * CK_GCM_PARAMS as
+ *     typedef struct CK_GCM_PARAMS {
+ *         CK_BYTE_PTR       pIv;
+ *         CK_ULONG          ulIvLen;
+ *         CK_BYTE_PTR       pAAD;
+ *         CK_ULONG          ulAADLen;
+ *         CK_ULONG          ulTagBits;
+ *     } CK_GCM_PARAMS;
+ * However, the official header file of PKCS#11 v2.40 defines the
+ * CK_GCM_PARAMS with an extra "ulIvBits" field (type CK_ULONG).
+ * NSS uses the spec version while Solaris and SoftHSM2 use the header
+ * version. In order to work with both sides, SunPKCS11 provider defines
+ * the spec version of CK_GCM_PARAMS as CK_GCM_PARAMS_NO_IVBITS (as in this
+ * file) and uses it first before failing over to the header version.
+ */
+#ifndef _PKCS11GCM2_H_
+#define _PKCS11GCM2_H_ 1
+
+/* include the platform dependent part of the header */
+typedef struct CK_GCM_PARAMS_NO_IVBITS {
+    CK_BYTE_PTR       pIv;
+    CK_ULONG          ulIvLen;
+    CK_BYTE_PTR       pAAD;
+    CK_ULONG          ulAADLen;
+    CK_ULONG          ulTagBits;
+} CK_GCM_PARAMS_NO_IVBITS;
+
+typedef CK_GCM_PARAMS_NO_IVBITS CK_PTR CK_GCM_PARAMS_NO_IVBITS_PTR;
+
+#endif /* _PKCS11GCM2_H_ */
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11t.h	Tue Oct 08 11:57:11 2019 +0200
@@ -1833,6 +1833,7 @@
 typedef struct CK_GCM_PARAMS {
     CK_BYTE_PTR       pIv;
     CK_ULONG          ulIvLen;
+    CK_ULONG          ulIvBits;
     CK_BYTE_PTR       pAAD;
     CK_ULONG          ulAADLen;
     CK_ULONG          ulTagBits;
@@ -1962,7 +1963,7 @@
 typedef CK_TLS_KDF_PARAMS CK_PTR CK_TLS_KDF_PARAMS_PTR;
 
 typedef struct CK_TLS_MAC_PARAMS {
-    CK_MECHANISM_TYPE         prfMechanism;
+    CK_MECHANISM_TYPE         prfHashMechanism;
     CK_ULONG                  ulMacLength;
     CK_ULONG                  ulServerOrClient;
 } CK_TLS_MAC_PARAMS;
@@ -2000,3 +2001,4 @@
 
 #endif /* _PKCS11T_H_ */
 
+
--- a/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/share/native/libj2pkcs11/pkcs11wrapper.h	Tue Oct 08 11:57:11 2019 +0200
@@ -159,7 +159,6 @@
 /* include the platform dependent part of the header */
 #include "p11_md.h"
 
-#include "pkcs11.h"
 #include <jni.h>
 #include <jni_util.h>
 #include <stdarg.h>
@@ -296,6 +295,10 @@
 #define CLASS_TLS_PRF_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_PRF_PARAMS"
 #define CLASS_TLS_MAC_PARAMS "sun/security/pkcs11/wrapper/CK_TLS_MAC_PARAMS"
 
+/* function to update the CK_NSS_GCM_PARAMS in mechanism pointer with
+ * CK_GCM_PARAMS
+ */
+CK_MECHANISM_PTR updateGCMParams(JNIEnv *env, CK_MECHANISM_PTR mechPtr);
 
 /* function to convert a PKCS#11 return value other than CK_OK into a Java Exception
  * or to throw a PKCS11RuntimeException
--- a/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/unix/native/libj2pkcs11/p11_md.h	Tue Oct 08 11:57:11 2019 +0200
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ */
+
 /*
  * reserved comment block
  * DO NOT REMOVE OR ALTER!
@@ -69,6 +73,7 @@
 #endif
 
 #include "pkcs11.h"
+#include "pkcs11gcm2.h"
 
 #include "jni.h"
 
--- a/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.crypto.cryptoki/windows/native/libj2pkcs11/p11_md.h	Tue Oct 08 11:57:11 2019 +0200
@@ -1,3 +1,7 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ */
+
 /*
  * reserved comment block
  * DO NOT REMOVE OR ALTER!
@@ -77,6 +81,7 @@
 #endif /* CreateMutex */
 
 #include "pkcs11.h"
+#include "pkcs11gcm2.h"
 
 /* statement according to PKCS11 docu */
 #pragma pack(pop, cryptoki)
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/PlatformRecording.java	Tue Oct 08 11:57:11 2019 +0200
@@ -370,10 +370,16 @@
 
     public void setDestination(WriteableUserPath userSuppliedPath) throws IOException {
         synchronized (recorder) {
+            checkSetDestination(userSuppliedPath);
+            this.destination = userSuppliedPath;
+        }
+    }
+
+    public void checkSetDestination(WriteableUserPath userSuppliedPath) throws IOException {
+        synchronized (recorder) {
             if (Utils.isState(getState(), RecordingState.STOPPED, RecordingState.CLOSED)) {
                 throw new IllegalStateException("Destination can't be set on a recording that has been stopped/closed");
             }
-            this.destination = userSuppliedPath;
         }
     }
 
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ManagementSupport.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/management/ManagementSupport.java	Tue Oct 08 11:57:11 2019 +0200
@@ -25,6 +25,8 @@
 
 package jdk.jfr.internal.management;
 
+import java.io.IOException;
+import java.nio.file.Paths;
 import java.time.Duration;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -98,4 +100,12 @@
         WriteableUserPath wup = pr.getDestination();
         return wup == null ? null : wup.getOriginalText();
     }
+
+    public static void checkSetDestination(Recording recording, String destination) throws IOException{
+        PlatformRecording pr = PrivateAccess.getInstance().getPlatformRecording(recording);
+        if(destination != null){
+            WriteableUserPath wup = new WriteableUserPath(Paths.get(destination));
+            pr.checkSetDestination(wup);
+        }
+    }
 }
--- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/FlightRecorderMXBeanImpl.java	Tue Oct 08 11:57:11 2019 +0200
@@ -28,6 +28,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.StringReader;
+import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.security.AccessControlContext;
 import java.security.AccessController;
@@ -105,7 +106,8 @@
     private static final String OPTION_DISK = "disk";
     private static final String OPTION_DUMP_ON_EXIT = "dumpOnExit";
     private static final String OPTION_DURATION = "duration";
-    private static final List<String> OPTIONS = Arrays.asList(new String[] { OPTION_DUMP_ON_EXIT, OPTION_DURATION, OPTION_NAME, OPTION_MAX_AGE, OPTION_MAX_SIZE, OPTION_DISK, });
+    private static final String OPTION_DESTINATION = "destination";
+    private static final List<String> OPTIONS = Arrays.asList(new String[] { OPTION_DUMP_ON_EXIT, OPTION_DURATION, OPTION_NAME, OPTION_MAX_AGE, OPTION_MAX_SIZE, OPTION_DISK, OPTION_DESTINATION, });
     private final StreamManager streamHandler = new StreamManager();
     private final Map<Long, Object> changes = new ConcurrentHashMap<>();
     private final AtomicLong sequenceNumber = new AtomicLong();
@@ -283,6 +285,7 @@
         validateOption(ops, OPTION_MAX_AGE, MBeanUtils::duration);
         validateOption(ops, OPTION_MAX_SIZE, MBeanUtils::size);
         validateOption(ops, OPTION_DURATION, MBeanUtils::duration);
+        validateOption(ops, OPTION_DESTINATION, x -> MBeanUtils.destination(r, x));
 
         // All OK, now set them.atomically
         setOption(ops, OPTION_DUMP_ON_EXIT, "false", MBeanUtils::booleanValue, x -> r.setDumpOnExit(x));
@@ -291,6 +294,7 @@
         setOption(ops, OPTION_MAX_AGE, null, MBeanUtils::duration, x -> r.setMaxAge(x));
         setOption(ops, OPTION_MAX_SIZE, "0", MBeanUtils::size, x -> r.setMaxSize(x));
         setOption(ops, OPTION_DURATION, null, MBeanUtils::duration, x -> r.setDuration(x));
+        setOption(ops, OPTION_DESTINATION, null, x -> MBeanUtils.destination(r, x), x -> setOptionDestination(r, x));
     }
 
     @Override
@@ -305,6 +309,7 @@
         Long maxSize = r.getMaxSize();
         options.put(OPTION_MAX_SIZE, String.valueOf(maxSize == null ? "0" : maxSize.toString()));
         options.put(OPTION_DURATION, ManagementSupport.formatTimespan(r.getDuration(), " "));
+        options.put(OPTION_DESTINATION, ManagementSupport.getDestinationOriginalText(r));
         return options;
     }
 
@@ -349,6 +354,20 @@
         }
     }
 
+    private static void setOptionDestination(Recording recording, String destination){
+        try {
+            Path pathDestination = null;
+            if(destination != null){
+                pathDestination = Paths.get(destination);
+            }
+            recording.setDestination(pathDestination);
+        } catch (IOException e) {
+            IllegalArgumentException iae = new IllegalArgumentException("Not a valid destination " + destination);
+            iae.addSuppressed(e);
+            throw iae;
+        }
+    }
+
     private static <T, U> void validateOption(Map<String, String> options, String name, Function<String, U> validator) {
         try {
             String v = options.get(name);
--- a/src/jdk.management.jfr/share/classes/jdk/management/jfr/MBeanUtils.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/src/jdk.management.jfr/share/classes/jdk/management/jfr/MBeanUtils.java	Tue Oct 08 11:57:11 2019 +0200
@@ -24,6 +24,7 @@
  */
 package jdk.management.jfr;
 
+import java.io.IOException;
 import java.lang.management.ManagementPermission;
 import java.security.Permission;
 import java.time.DateTimeException;
@@ -37,6 +38,7 @@
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
+import jdk.jfr.Recording;
 import jdk.jfr.internal.management.ManagementSupport;
 
 final class MBeanUtils {
@@ -126,5 +128,16 @@
         }
         return size;
     }
+
+    public static String destination(Recording recording, String destination) throws IllegalArgumentException{
+        try {
+            ManagementSupport.checkSetDestination(recording, destination);
+            return destination;
+        }catch(IOException e){
+            IllegalArgumentException iae = new IllegalArgumentException("Not a valid destination " + destination);
+            iae.addSuppressed(e);
+            throw iae;
+        }
+    }
 }
 
--- a/test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/test/hotspot/jtreg/gc/shenandoah/TestGCThreadGroups.java	Tue Oct 08 11:57:11 2019 +0200
@@ -32,12 +32,6 @@
  *      -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
  *      -Dtarget=1000
  *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=passive
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=1000
- *      TestGCThreadGroups
  */
 
 /**
@@ -71,46 +65,22 @@
  *      TestGCThreadGroups
  *
  * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=1000
- *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
  *      -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
  *      -Dtarget=1000
  *      TestGCThreadGroups
  *
  * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=static
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=1000
- *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
  *      -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
  *      -Dtarget=100
  *      TestGCThreadGroups
  *
  * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=compact
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=100
- *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
  *      -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
  *      -Dtarget=100
  *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=100
- *      TestGCThreadGroups
  */
 
 /**
@@ -130,18 +100,6 @@
  *      -XX:ConcGCThreads=2 -XX:ParallelGCThreads=4
  *      -Dtarget=1000
  *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=1000
- *      TestGCThreadGroups
- *
- * @run main/othervm -Xmx16m -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
- *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=traversal -XX:ShenandoahGCHeuristics=aggressive
- *      -XX:ConcGCThreads=4 -XX:ParallelGCThreads=2
- *      -Dtarget=1000
- *      TestGCThreadGroups
 */
 
 public class TestGCThreadGroups {
--- a/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCounts.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCounts.java	Tue Oct 08 11:57:11 2019 +0200
@@ -61,7 +61,7 @@
             output.shouldHaveExitValue(1);
         } else if (conc > par) {
             output.shouldContain("Shenandoah expects ConcGCThreads <= ParallelGCThreads");
-            output.shouldHaveExitValue(0);
+            output.shouldHaveExitValue(1);
         } else {
             output.shouldNotContain("Shenandoah expects ConcGCThreads <= ParallelGCThreads");
             output.shouldHaveExitValue(0);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestThreadCountsOverride.java	Tue Oct 08 11:57:11 2019 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2016, 2018, Red Hat, Inc. All rights reserved.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test TestThreadCountsOverride
+ * @summary Test that Shenandoah GC thread counts are overridable
+ * @key gc
+ * @requires vm.gc.Shenandoah & !vm.graal.enabled
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ *          java.management
+ * @run driver TestThreadCountsOverride
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class TestThreadCountsOverride {
+    public static void main(String[] args) throws Exception {
+        {
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+UnlockExperimentalVMOptions",
+                "-XX:+UseShenandoahGC",
+                "-XX:ParallelGCThreads=1",
+                "-XX:+PrintFlagsFinal",
+                "-version");
+            OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+            output.shouldMatch("ParallelGCThreads(.*)= 1 ");
+            output.shouldHaveExitValue(0);
+        }
+
+        {
+            ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+                "-XX:+UnlockDiagnosticVMOptions",
+                "-XX:+UnlockExperimentalVMOptions",
+                "-XX:+UseShenandoahGC",
+                "-XX:ConcGCThreads=1",
+                "-XX:+PrintFlagsFinal",
+                "-version");
+            OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+            output.shouldMatch("ConcGCThreads(.*)= 1 ");
+            output.shouldHaveExitValue(0);
+        }
+    }
+
+}
--- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineDeleteJmethod.java	Mon Oct 07 20:15:47 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
- * @bug 8181171
- * @summary Test deleting static method pointing to by a jmethod
- * @library /test/lib
- * @modules java.base/jdk.internal.misc
- * @modules java.compiler
- *          java.instrument
- *          jdk.jartool/sun.tools.jar
- * @run main RedefineClassHelper
- * @run main/native/othervm -javaagent:redefineagent.jar -XX:+AllowRedefinitionToAddDeleteMethods -Xlog:redefine+class*=trace RedefineDeleteJmethod
- */
-
-class B {
-    private static int deleteMe() { System.out.println("deleteMe called"); return 5; }
-    public static int callDeleteMe() { return deleteMe(); }
-}
-
-public class RedefineDeleteJmethod {
-
-    public static String newB =
-        "class B {" +
-            "public static int callDeleteMe() { return 6; }" +
-        "}";
-
-    public static String newerB =
-        "class B {" +
-            "private static int deleteMe() { System.out.println(\"deleteMe (2) called\"); return 7; }" +
-            "public static int callDeleteMe() { return deleteMe(); }" +
-        "}";
-
-
-    static {
-        System.loadLibrary("RedefineDeleteJmethod");
-    }
-
-    static native int jniCallDeleteMe();
-
-    static void test(int expected, boolean nsme_expected) throws Exception {
-        // Call through static method
-        int res = B.callDeleteMe();
-        System.out.println("Result = " + res);
-        if (res != expected) {
-            throw new Error("returned " + res + " expected " + expected);
-        }
-
-        // Call through jmethodID, saved from first call.
-        try {
-            res = jniCallDeleteMe();
-            if (nsme_expected) {
-                throw new RuntimeException("Failed, NoSuchMethodError expected");
-            }
-            if (res != expected) {
-                throw new Error("returned " + res + " expected " + expected);
-            }
-        } catch (NoSuchMethodError ex) {
-            if (!nsme_expected) {
-                throw new RuntimeException("Failed, NoSuchMethodError not expected");
-            }
-            System.out.println("Passed, NoSuchMethodError expected");
-        }
-    }
-
-    public static void main(String[] args) throws Exception {
-        test(5, false);
-        RedefineClassHelper.redefineClass(B.class, newB);
-        test(6, true);
-        RedefineClassHelper.redefineClass(B.class, newerB);
-        test(7, true);
-    }
-}
--- a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/libRedefineDeleteJmethod.c	Mon Oct 07 20:15:47 2019 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <jni.h>
-
-jmethodID mid;
-jclass cls;
-static int count = 0;
-
-JNIEXPORT jint JNICALL
-Java_RedefineDeleteJmethod_jniCallDeleteMe(JNIEnv* env, jobject obj) {
-
-    if (count == 0) {
-      count++;
-      cls = (*env)->FindClass(env, "B");
-      if (NULL == cls) {
-          (*env)->FatalError(env, "could not find class");
-      }
-
-      mid = (*env)->GetStaticMethodID(env, cls, "deleteMe", "()I");
-      if (NULL == mid) {
-          (*env)->FatalError(env, "could not find method");
-      }
-    }
-
-    return (*env)->CallStaticIntMethod(env, cls, mid);
-}
--- a/test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbPmap.java	Tue Oct 08 11:57:11 2019 +0200
@@ -52,9 +52,8 @@
             List<String> cmds = List.of("pmap");
 
             Map<String, List<String>> expStrMap = new HashMap<>();
-            expStrMap.put("pmap", List.of(
-                    "jvm", "java", "net", "nio",
-                    "jimage", "zip", "verify"));
+            expStrMap.put("pmap",
+                    List.of("jvm", "java", "net", "nio", "jimage", "zip"));
 
             test.run(theApp.getPid(), cmds, expStrMap, null);
         } catch (SkippedException se) {
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorWait/rawmnwait005/rawmnwait005.cpp	Mon Oct 07 20:15:47 2019 +0200
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/RawMonitorWait/rawmnwait005/rawmnwait005.cpp	Tue Oct 08 11:57:11 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,7 @@
 static jvmtiEnv *jvmti = NULL;
 static jvmtiCapabilities caps;
 static jint result = PASSED;
-static jboolean printdump = JNI_FALSE;
+static jboolean printdump = JNI_TRUE;
 static jrawMonitorID monitor;
 static jrawMonitorID wait_lock;
 static jlong wait_time;
@@ -100,6 +100,8 @@
     jvmtiError err;
     const char* const thread_name = "test thread";
 
+    // Once we hold this monitor we know we can't get interrupted
+    // until we have called wait().
     err = jvmti->RawMonitorEnter(monitor);
     if (err != JVMTI_ERROR_NONE) {
         printf("(RawMonitorEnter#test) unexpected error: %s (%d)\n",
@@ -110,6 +112,7 @@
         printf(">>> [%s] acquired lock for 'monitor' ...\n", thread_name);
     }
 
+    // We can't get this monitor until the main thread has called wait() on it.
     err = jvmti->RawMonitorEnter(wait_lock);
     if (err != JVMTI_ERROR_NONE) {
         printf("(RawMonitorEnter#wait) unexpected error: %s (%d)\n",
@@ -156,6 +159,36 @@
         result = STATUS_FAILED;
     }
 
+    // We can't reacquire this monitor until the main thread is waiting for us to
+    // complete.
+    err = jvmti->RawMonitorEnter(wait_lock);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(RawMonitorEnter#wait) unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        result = STATUS_FAILED;
+        return;
+    }
+
+    if (printdump == JNI_TRUE) {
+        printf(">>> [%s] acquired lock for 'wait_lock' ...\n", thread_name);
+        printf(">>> [%s] notifying main thread we are done ...\n", thread_name);
+    }
+
+    err = jvmti->RawMonitorNotify(wait_lock);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(RawMonitorWait#wait) unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        result = STATUS_FAILED;
+        return;
+    }
+    err = jvmti->RawMonitorExit(wait_lock);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(RawMonitorExit#wait) unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        result = STATUS_FAILED;
+        return;
+    }
+
     if (printdump == JNI_TRUE) {
         printf(">>> [%s] all done\n", thread_name);
     }
@@ -223,6 +256,11 @@
     if (printdump == JNI_TRUE) {
         printf(">>> [%s] starting test thread ...\n", thread_name);
     }
+
+    // This starts a daemon thread, so we need to synchronize with it
+    // before we terminate - else the test will end before it checks
+    // it was interrupted!
+
     err = jvmti->RunAgentThread(thr, test_thread, NULL,
                                 JVMTI_THREAD_NORM_PRIORITY);
     if (err != JVMTI_ERROR_NONE) {
@@ -244,12 +282,7 @@
         printf(">>> [%s] got notification from test thread ...\n", thread_name);
     }
 
-    err = jvmti->RawMonitorExit(wait_lock);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(RawMonitorExit#wait) unexpected error: %s (%d)\n",
-               TranslateError(err), err);
-        return STATUS_FAILED;
-    }
+    // Keep the wait_lock so we can wait again at the end.
 
     err = jvmti->RawMonitorEnter(monitor);
     if (err != JVMTI_ERROR_NONE) {
@@ -280,6 +313,26 @@
     }
 
     if (printdump == JNI_TRUE) {
+        printf(">>> [%s] waiting for test thread to complete its wait and notify us ...\n", thread_name);
+    }
+    err = jvmti->RawMonitorWait(wait_lock, (jlong)0);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(RawMonitorWait#wait) unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        return STATUS_FAILED;
+    }
+    if (printdump == JNI_TRUE) {
+        printf(">>> [%s] got final notification from test thread ...\n", thread_name);
+    }
+
+    err = jvmti->RawMonitorExit(wait_lock);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(RawMonitorExit#wait) unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        return STATUS_FAILED;
+    }
+
+    if (printdump == JNI_TRUE) {
         printf(">>> [%s] all done\n", thread_name);
     }
 
--- a/test/jdk/jdk/jfr/jmx/TestRecordingOptions.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/test/jdk/jdk/jfr/jmx/TestRecordingOptions.java	Tue Oct 08 11:57:11 2019 +0200
@@ -25,6 +25,7 @@
 
 package jdk.jfr.jmx;
 
+import java.io.File;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -49,7 +50,7 @@
         options.put("dumpOnExit", "false");
         options.put("disk", "false");
         options.put("duration", "1 h"); // don't want recording to stop
-
+        options.put("destination", "." + File.separator + "dump.jfr");
         FlightRecorderMXBean bean = JmxHelper.getFlighteRecorderMXBean();
         long recId = bean.newRecording();
         Map<String, String> defaults = bean.getRecordingOptions(recId);
@@ -72,6 +73,7 @@
         Asserts.assertEquals(outOptions.get("dumpOnExit"), "false", "Wrong dumpOnExit");
         Asserts.assertEquals(outOptions.get("disk"), "false", "Wrong disk");
         Asserts.assertEquals(outOptions.get("duration"), "1 h", "Wrong duration");
+        Asserts.assertEquals(outOptions.get("destination"), "." + File.separator + "dump.jfr", "Wrong destination");
 
         // try empty map
         bean.setRecordingOptions(recId, new HashMap<>());
@@ -116,6 +118,7 @@
         nullMap.put("dumpOnExit", null);
         nullMap.put("disk", null);
         nullMap.put("duration", null);
+        nullMap.put("destination", null);
         bean.setRecordingOptions(recId, nullMap);
         Asserts.assertEquals(bean.getRecordingOptions(recId), defaults);
 
--- a/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java	Mon Oct 07 20:15:47 2019 +0200
+++ b/test/jdk/sun/security/pkcs11/Cipher/TestGCMKeyAndIvCheck.java	Tue Oct 08 11:57:11 2019 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 8080462
+ * @bug 8080462 8229243
  * @library /test/lib ..
  * @modules jdk.crypto.cryptoki
  * @run main TestGCMKeyAndIvCheck
@@ -81,6 +81,7 @@
                     ", no support for " + mode);
             return;
         }
+        System.out.println("Testing against " + p.getName());
         SecretKey key = new SecretKeySpec(new byte[16], "AES");
         // First try parameter-less init.
         c.init(Cipher.ENCRYPT_MODE, key);
@@ -111,12 +112,11 @@
             throw new Exception("Parameters contains incorrect IV value");
         }
 
-        // Should be ok to use the same key+iv for decryption
         c.init(Cipher.DECRYPT_MODE, key, params);
         c.updateAAD(AAD);
         byte[] recovered = c.doFinal(ctPlusTag);
         if (!Arrays.equals(recovered, PT)) {
-            throw new Exception("decryption result mismatch");
+            throw new Exception("Decryption result mismatch");
         }
 
         // Now try to encrypt again using the same key+iv; should fail also
@@ -125,6 +125,7 @@
             throw new Exception("Should throw exception when same key+iv is used");
         } catch (InvalidAlgorithmParameterException iape) {
             // expected
+            System.out.println("Expected IAPE thrown");
         }
 
         // Now try to encrypt again using parameter-less init; should work
@@ -138,7 +139,8 @@
         }
 
         // Now try to encrypt again using a different parameter; should work
-        AlgorithmParameterSpec spec2 = new GCMParameterSpec(128, new byte[30]);
+        AlgorithmParameterSpec spec2 = new GCMParameterSpec(128,
+            "Solaris PKCS11 lib does not allow all-zero IV".getBytes());
         c.init(Cipher.ENCRYPT_MODE, key, spec2);
         c.updateAAD(AAD);
         c.doFinal(PT);
@@ -154,7 +156,7 @@
         c.updateAAD(AAD);
         recovered = c.doFinal(ctPlusTag);
         if (!Arrays.equals(recovered, PT)) {
-            throw new Exception("decryption result mismatch");
+            throw new Exception("Decryption result mismatch");
         }
 
         // Now try decryption again and re-init using the same parameters