Merge unixdomainchannels
authormichaelm
Tue, 26 Nov 2019 10:22:13 +0000
branchunixdomainchannels
changeset 59266 bfc8074ea4ef
parent 59256 aa516a7cf95e (current diff)
parent 59265 d9a3bddcffcc (diff)
child 59322 cfe31d2f935c
Merge
--- a/src/hotspot/share/classfile/classLoaderDataGraph.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -186,10 +186,7 @@
 // GC root of class loader data created.
 ClassLoaderData* volatile ClassLoaderDataGraph::_head = NULL;
 ClassLoaderData* ClassLoaderDataGraph::_unloading = NULL;
-ClassLoaderData* ClassLoaderDataGraph::_saved_unloading = NULL;
-ClassLoaderData* ClassLoaderDataGraph::_saved_head = NULL;
 
-bool ClassLoaderDataGraph::_should_purge = false;
 bool ClassLoaderDataGraph::_should_clean_deallocate_lists = false;
 bool ClassLoaderDataGraph::_safepoint_cleanup_needed = false;
 bool ClassLoaderDataGraph::_metaspace_oom = false;
@@ -249,9 +246,7 @@
 
 void ClassLoaderDataGraph::cld_unloading_do(CLDClosure* cl) {
   assert_locked_or_safepoint_weak(ClassLoaderDataGraph_lock);
-  // Only walk the head until any clds not purged from prior unloading
-  // (CMS doesn't purge right away).
-  for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) {
+  for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) {
     assert(cld->is_unloading(), "invariant");
     cl->do_cld(cld);
   }
@@ -381,9 +376,7 @@
 
 void ClassLoaderDataGraph::modules_unloading_do(void f(ModuleEntry*)) {
   assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
-  // Only walk the head until any clds not purged from prior unloading
-  // (CMS doesn't purge right away).
-  for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) {
+  for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) {
     assert(cld->is_unloading(), "invariant");
     cld->modules_do(f);
   }
@@ -399,9 +392,7 @@
 
 void ClassLoaderDataGraph::packages_unloading_do(void f(PackageEntry*)) {
   assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
-  // Only walk the head until any clds not purged from prior unloading
-  // (CMS doesn't purge right away).
-  for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) {
+  for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) {
     assert(cld->is_unloading(), "invariant");
     cld->packages_do(f);
   }
@@ -424,9 +415,7 @@
 
 void ClassLoaderDataGraph::classes_unloading_do(void f(Klass* const)) {
   assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
-  // Only walk the head until any clds not purged from prior unloading
-  // (CMS doesn't purge right away).
-  for (ClassLoaderData* cld = _unloading; cld != _saved_unloading; cld = cld->next()) {
+  for (ClassLoaderData* cld = _unloading; cld != NULL; cld = cld->next()) {
     assert(cld->is_unloading(), "invariant");
     cld->classes_do(f);
   }
@@ -476,32 +465,6 @@
   }
 }
 
-GrowableArray<ClassLoaderData*>* ClassLoaderDataGraph::new_clds() {
-  assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
-  assert(_head == NULL || _saved_head != NULL, "remember_new_clds(true) not called?");
-
-  GrowableArray<ClassLoaderData*>* array = new GrowableArray<ClassLoaderData*>();
-
-  // The CLDs in [_head, _saved_head] were all added during last call to remember_new_clds(true);
-  ClassLoaderData* curr = _head;
-  while (curr != _saved_head) {
-    if (!curr->claimed(ClassLoaderData::_claim_strong)) {
-      array->push(curr);
-      LogTarget(Debug, class, loader, data) lt;
-      if (lt.is_enabled()) {
-        LogStream ls(lt);
-        ls.print("found new CLD: ");
-        curr->print_value_on(&ls);
-        ls.cr();
-      }
-    }
-
-    curr = curr->_next;
-  }
-
-  return array;
-}
-
 #ifndef PRODUCT
 bool ClassLoaderDataGraph::contains_loader_data(ClassLoaderData* loader_data) {
   assert_locked_or_safepoint(ClassLoaderDataGraph_lock);
@@ -544,10 +507,6 @@
   uint loaders_processed = 0;
   uint loaders_removed = 0;
 
-  // Save previous _unloading pointer for CMS which may add to unloading list before
-  // purging and we don't want to rewalk the previously unloaded class loader data.
-  _saved_unloading = _unloading;
-
   data = _head;
   while (data != NULL) {
     if (data->is_alive()) {
--- a/src/hotspot/share/classfile/classLoaderDataGraph.hpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/classfile/classLoaderDataGraph.hpp	Tue Nov 26 10:22:13 2019 +0000
@@ -43,10 +43,6 @@
   // All CLDs (except the null CLD) can be reached by walking _head->_next->...
   static ClassLoaderData* volatile _head;
   static ClassLoaderData* _unloading;
-  // CMS support.
-  static ClassLoaderData* _saved_head;
-  static ClassLoaderData* _saved_unloading;
-  static bool _should_purge;
 
   // Set if there's anything to purge in the deallocate lists or previous versions
   // during a safepoint after class unloading in a full GC.
@@ -115,18 +111,6 @@
   static void print_dictionary(outputStream* st);
   static void print_table_statistics(outputStream* st);
 
-  // CMS support.
-  static void remember_new_clds(bool remember) { _saved_head = (remember ? _head : NULL); }
-  static GrowableArray<ClassLoaderData*>* new_clds();
-
-  static void set_should_purge(bool b) { _should_purge = b; }
-  static bool should_purge_and_reset() {
-    bool res = _should_purge;
-    // reset for next time.
-    set_should_purge(false);
-    return res;
-  }
-
   static int resize_dictionaries();
 
   static bool has_metaspace_oom()           { return _metaspace_oom; }
--- a/src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,7 +32,9 @@
 #include "jfr/support/jfrEventClass.hpp"
 #include "logging/log.hpp"
 #include "memory/resourceArea.hpp"
+#include "prims/jvmtiEnvBase.hpp"
 #include "prims/jvmtiExport.hpp"
+#include "prims/jvmtiUtil.hpp"
 #include "runtime/interfaceSupport.inline.hpp"
 #include "runtime/thread.inline.hpp"
 #include "utilities/exceptions.hpp"
@@ -52,19 +54,17 @@
   }
 }
 
-static jvmtiError set_event_notification_mode(jvmtiEventMode mode,
-                                              jvmtiEvent event,
-                                              jthread event_thread,
-                                              ...) {
-  if (jfr_jvmti_env == NULL) {
-    return JVMTI_ERROR_NONE;
-  }
+static bool set_event_notification_mode(jvmtiEventMode mode,
+                                        jvmtiEvent event,
+                                        jthread event_thread,
+                                        ...) {
+  assert(jfr_jvmti_env != NULL, "invariant");
   const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventNotificationMode(mode, event, event_thread);
   check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventNotificationMode");
-  return jvmti_ret_code;
+  return jvmti_ret_code == JVMTI_ERROR_NONE;
 }
 
-static jvmtiError update_class_file_load_hook_event(jvmtiEventMode mode) {
+static bool update_class_file_load_hook_event(jvmtiEventMode mode) {
   return set_event_notification_mode(mode, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
 }
 
@@ -117,12 +117,23 @@
   return classes;
 }
 
-static void log_and_throw(TRAPS) {
+// caller needs ResourceMark
+static void log_and_throw(jvmtiError error, TRAPS) {
   if (!HAS_PENDING_EXCEPTION) {
     DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
     ThreadInVMfromNative tvmfn((JavaThread*)THREAD);
-    log_error(jfr, system)("JfrJvmtiAgent::retransformClasses failed");
-    JfrJavaSupport::throw_class_format_error("JfrJvmtiAgent::retransformClasses failed", THREAD);
+    const char base_error_msg[] = "JfrJvmtiAgent::retransformClasses failed: ";
+    size_t length = sizeof base_error_msg; // includes terminating null
+    const char* const jvmti_error_name = JvmtiUtil::error_name(error);
+    assert(jvmti_error_name != NULL, "invariant");
+    length += strlen(jvmti_error_name);
+    char* error_msg = NEW_RESOURCE_ARRAY(char, length);
+    jio_snprintf(error_msg, length, "%s%s", base_error_msg, jvmti_error_name);
+    if (JVMTI_ERROR_INVALID_CLASS_FORMAT == error) {
+      JfrJavaSupport::throw_class_format_error(error_msg, THREAD);
+    } else {
+      JfrJavaSupport::throw_runtime_exception(error_msg, THREAD);
+    }
   }
 }
 
@@ -137,12 +148,15 @@
   }
 }
 
+static bool is_valid_jvmti_phase() {
+  return JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE;
+}
+
 void JfrJvmtiAgent::retransform_classes(JNIEnv* env, jobjectArray classes_array, TRAPS) {
   assert(env != NULL, "invariant");
+  assert(classes_array != NULL, "invariant");
+  assert(is_valid_jvmti_phase(), "invariant");
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
-  if (classes_array == NULL) {
-    return;
-  }
   const jint classes_count = env->GetArrayLength(classes_array);
   if (classes_count <= 0) {
     return;
@@ -153,27 +167,27 @@
   for (jint i = 0; i < classes_count; i++) {
     jclass clz = (jclass)env->GetObjectArrayElement(classes_array, i);
     check_exception_and_log(env, THREAD);
-
+    classes[i] = clz;
+  }
+  {
     // inspecting the oop/klass requires a thread transition
-    {
-      ThreadInVMfromNative transition((JavaThread*)THREAD);
-      if (JdkJfrEvent::is_a(clz)) {
-        // should have been tagged already
-        assert(JdkJfrEvent::is_subklass(clz), "invariant");
-      } else {
+    ThreadInVMfromNative transition((JavaThread*)THREAD);
+    for (jint i = 0; i < classes_count; ++i) {
+      jclass clz = classes[i];
+      if (!JdkJfrEvent::is_a(clz)) {
         // outside the event hierarchy
         JdkJfrEvent::tag_as_host(clz);
       }
     }
-
-    classes[i] = clz;
   }
-  if (jfr_jvmti_env->RetransformClasses(classes_count, classes) != JVMTI_ERROR_NONE) {
-    log_and_throw(THREAD);
+  DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(THREAD));
+  const jvmtiError result = jfr_jvmti_env->RetransformClasses(classes_count, classes);
+  if (result != JVMTI_ERROR_NONE) {
+    log_and_throw(result, THREAD);
   }
 }
 
-static jvmtiError register_callbacks(JavaThread* jt) {
+static bool register_callbacks(JavaThread* jt) {
   assert(jfr_jvmti_env != NULL, "invariant");
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(jt));
   jvmtiEventCallbacks callbacks;
@@ -182,10 +196,10 @@
   callbacks.ClassFileLoadHook = jfr_on_class_file_load_hook;
   const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
   check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventCallbacks");
-  return jvmti_ret_code;
+  return jvmti_ret_code == JVMTI_ERROR_NONE;
 }
 
-static jvmtiError register_capabilities(JavaThread* jt) {
+static bool register_capabilities(JavaThread* jt) {
   assert(jfr_jvmti_env != NULL, "invariant");
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_native(jt));
   jvmtiCapabilities capabilities;
@@ -195,7 +209,7 @@
   capabilities.can_retransform_any_class = 1;
   const jvmtiError jvmti_ret_code = jfr_jvmti_env->AddCapabilities(&capabilities);
   check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "Add Capabilities");
-  return jvmti_ret_code;
+  return jvmti_ret_code == JVMTI_ERROR_NONE;
 }
 
 static jint create_jvmti_env(JavaThread* jt) {
@@ -206,16 +220,14 @@
   return vm->GetEnv((void **)&jfr_jvmti_env, JVMTI_VERSION);
 }
 
-static jvmtiError unregister_callbacks(JavaThread* jt) {
-  if (jfr_jvmti_env == NULL) {
-    return JVMTI_ERROR_NONE;
-  }
+static bool unregister_callbacks(JavaThread* jt) {
+  assert(jfr_jvmti_env != NULL, "invariant");
   jvmtiEventCallbacks callbacks;
   /* Set empty callbacks */
   memset(&callbacks, 0, sizeof(callbacks));
   const jvmtiError jvmti_ret_code = jfr_jvmti_env->SetEventCallbacks(&callbacks, sizeof(callbacks));
   check_jvmti_error(jfr_jvmti_env, jvmti_ret_code, "SetEventCallbacks");
-  return jvmti_ret_code;
+  return jvmti_ret_code == JVMTI_ERROR_NONE;
 }
 
 JfrJvmtiAgent::JfrJvmtiAgent() {}
@@ -223,20 +235,17 @@
 JfrJvmtiAgent::~JfrJvmtiAgent() {
   JavaThread* jt = current_java_thread();
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(jt));
-  ThreadToNativeFromVM transition(jt);
-  update_class_file_load_hook_event(JVMTI_DISABLE);
-  unregister_callbacks(jt);
   if (jfr_jvmti_env != NULL) {
+    ThreadToNativeFromVM transition(jt);
+    update_class_file_load_hook_event(JVMTI_DISABLE);
+    unregister_callbacks(jt);
     jfr_jvmti_env->DisposeEnvironment();
     jfr_jvmti_env = NULL;
   }
-  agent = NULL;
 }
 
-static bool initialize() {
-  JavaThread* const jt = current_java_thread();
+static bool initialize(JavaThread* jt) {
   assert(jt != NULL, "invariant");
-  assert(jt->thread_state() == _thread_in_vm, "invariant");
   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(jt));
   ThreadToNativeFromVM transition(jt);
   if (create_jvmti_env(jt) != JNI_OK) {
@@ -244,25 +253,36 @@
     return false;
   }
   assert(jfr_jvmti_env != NULL, "invariant");
-  if (register_capabilities(jt) != JVMTI_ERROR_NONE) {
+  if (!register_capabilities(jt)) {
+    return false;
+  }
+  if (!register_callbacks(jt)) {
     return false;
   }
-  if (register_callbacks(jt) != JVMTI_ERROR_NONE) {
-    return false;
-  }
-  if (update_class_file_load_hook_event(JVMTI_ENABLE) != JVMTI_ERROR_NONE) {
-    return false;
-  }
-  return true;
+  return update_class_file_load_hook_event(JVMTI_ENABLE);
+}
+
+static void log_and_throw_illegal_state_exception(TRAPS) {
+  DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
+  const char* const illegal_state_msg = "An attempt was made to start JFR too early in the VM initialization sequence.";
+  log_error(jfr, system)(illegal_state_msg);
+  log_error(jfr, system)("JFR uses JVMTI RetransformClasses and requires the JVMTI state to have entered JVMTI_PHASE_LIVE.");
+  log_error(jfr, system)("Please initialize JFR in response to event JVMTI_EVENT_VM_INIT instead of JVMTI_EVENT_VM_START.");
+  JfrJavaSupport::throw_illegal_state_exception(illegal_state_msg, THREAD);
 }
 
 bool JfrJvmtiAgent::create() {
-  assert(jfr_jvmti_env == NULL, "invariant");
+  assert(agent == NULL, "invariant");
+  JavaThread* const jt = current_java_thread();
+  if (!is_valid_jvmti_phase()) {
+    log_and_throw_illegal_state_exception(jt);
+    return false;
+  }
   agent = new JfrJvmtiAgent();
   if (agent == NULL) {
     return false;
   }
-  if (!initialize()) {
+  if (!initialize(jt)) {
     delete agent;
     agent = NULL;
     return false;
@@ -276,4 +296,3 @@
     agent = NULL;
   }
 }
-
--- a/src/hotspot/share/jfr/jfr.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/jfr.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -45,15 +45,21 @@
   return JfrRecorder::is_recording();
 }
 
-void Jfr::on_vm_init() {
-  if (!JfrRecorder::on_vm_init()) {
-    vm_exit_during_initialization("Failure when starting JFR on_vm_init");
+void Jfr::on_create_vm_1() {
+  if (!JfrRecorder::on_create_vm_1()) {
+    vm_exit_during_initialization("Failure when starting JFR on_create_vm_1");
   }
 }
 
-void Jfr::on_vm_start() {
-  if (!JfrRecorder::on_vm_start()) {
-    vm_exit_during_initialization("Failure when starting JFR on_vm_start");
+void Jfr::on_create_vm_2() {
+  if (!JfrRecorder::on_create_vm_2()) {
+    vm_exit_during_initialization("Failure when starting JFR on_create_vm_2");
+  }
+}
+
+void Jfr::on_create_vm_3() {
+  if (!JfrRecorder::on_create_vm_3()) {
+    vm_exit_during_initialization("Failure when starting JFR on_create_vm_3");
   }
 }
 
--- a/src/hotspot/share/jfr/jfr.hpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/jfr.hpp	Tue Nov 26 10:22:13 2019 +0000
@@ -43,8 +43,9 @@
   static bool is_enabled();
   static bool is_disabled();
   static bool is_recording();
-  static void on_vm_init();
-  static void on_vm_start();
+  static void on_create_vm_1();
+  static void on_create_vm_2();
+  static void on_create_vm_3();
   static void on_unloading_classes();
   static void on_thread_start(Thread* thread);
   static void on_thread_exit(Thread* thread);
--- a/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -540,6 +540,10 @@
   create_and_throw(vmSymbols::java_lang_ClassFormatError(), message, THREAD);
 }
 
+void JfrJavaSupport::throw_runtime_exception(const char* message, TRAPS) {
+  create_and_throw(vmSymbols::java_lang_RuntimeException(), message, THREAD);
+}
+
 void JfrJavaSupport::abort(jstring errorMsg, Thread* t) {
   DEBUG_ONLY(check_java_thread_in_vm(t));
 
--- a/src/hotspot/share/jfr/jni/jfrJavaSupport.hpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/jni/jfrJavaSupport.hpp	Tue Nov 26 10:22:13 2019 +0000
@@ -84,6 +84,7 @@
   static void throw_internal_error(const char* message, TRAPS);
   static void throw_out_of_memory_error(const char* message, TRAPS);
   static void throw_class_format_error(const char* message, TRAPS);
+  static void throw_runtime_exception(const char* message, TRAPS);
 
   static bool is_jdk_jfr_module_available();
   static bool is_jdk_jfr_module_available(outputStream* stream, TRAPS);
--- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -192,7 +192,9 @@
     return JNI_TRUE;
   }
   if (!JfrRecorder::create(simulate_failure == JNI_TRUE)) {
-    JfrJavaSupport::throw_illegal_state_exception("Unable to start Jfr", thread);
+    if (!thread->has_pending_exception()) {
+      JfrJavaSupport::throw_illegal_state_exception("Unable to start Jfr", thread);
+    }
     return JNI_FALSE;
   }
   return JNI_TRUE;
--- a/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/recorder/checkpoint/jfrCheckpointManager.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -461,7 +461,6 @@
 }
 
 size_t JfrCheckpointManager::flush_type_set() {
-  assert(!SafepointSynchronize::is_at_safepoint(), "invariant");
   size_t elements = 0;
   {
     JfrCheckpointWriter writer(Thread::current());
--- a/src/hotspot/share/jfr/recorder/jfrRecorder.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/recorder/jfrRecorder.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -46,6 +46,9 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/globals_extension.hpp"
 #include "utilities/growableArray.hpp"
+#ifdef ASSERT
+#include "prims/jvmtiEnvBase.hpp"
+#endif
 
 bool JfrRecorder::is_disabled() {
   // True if -XX:-FlightRecorder has been explicitly set on the
@@ -57,7 +60,9 @@
 
 static bool enable() {
   assert(!_enabled, "invariant");
-  FLAG_SET_MGMT(FlightRecorder, true);
+  if (!FlightRecorder) {
+    FLAG_SET_MGMT(FlightRecorder, true);
+  }
   _enabled = FlightRecorder;
   assert(_enabled, "invariant");
   return _enabled;
@@ -67,7 +72,7 @@
   return _enabled;
 }
 
-bool JfrRecorder::on_vm_init() {
+bool JfrRecorder::on_create_vm_1() {
   if (!is_disabled()) {
     if (FlightRecorder || StartFlightRecording != NULL) {
       enable();
@@ -92,7 +97,7 @@
 
 static void teardown_startup_support() {
   release_recordings();
-  JfrOptionSet::release_startup_recording_options();
+  JfrOptionSet::release_start_flight_recording_options();
 }
 
 // Parsing options here to detect errors as soon as possible
@@ -110,7 +115,7 @@
 }
 
 static bool validate_recording_options(TRAPS) {
-  const GrowableArray<const char*>* options = JfrOptionSet::startup_recording_options();
+  const GrowableArray<const char*>* options = JfrOptionSet::start_flight_recording_options();
   if (options == NULL) {
     return true;
   }
@@ -143,7 +148,7 @@
   return true;
 }
 
-static bool launch_recordings(TRAPS) {
+static bool launch_command_line_recordings(TRAPS) {
   bool result = true;
   if (dcmd_recordings_array != NULL) {
     const int length = dcmd_recordings_array->length();
@@ -168,7 +173,7 @@
 
 static bool is_cds_dump_requested() {
   // we will not be able to launch recordings if a cds dump is being requested
-  if (Arguments::is_dumping_archive() && (JfrOptionSet::startup_recording_options() != NULL)) {
+  if (Arguments::is_dumping_archive() && (JfrOptionSet::start_flight_recording_options() != NULL)) {
     warning("JFR will be disabled during CDS dumping");
     teardown_startup_support();
     return true;
@@ -176,7 +181,7 @@
   return false;
 }
 
-bool JfrRecorder::on_vm_start() {
+bool JfrRecorder::on_create_vm_2() {
   if (is_cds_dump_requested()) {
     return true;
   }
@@ -187,9 +192,7 @@
   if (!register_jfr_dcmds()) {
     return false;
   }
-
   const bool in_graph = JfrJavaSupport::is_jdk_jfr_module_available();
-
   if (in_graph) {
     if (!validate_recording_options(thread)) {
       return false;
@@ -198,17 +201,19 @@
       return false;
     }
   }
-
   if (!is_enabled()) {
     return true;
   }
-
   if (!in_graph) {
     log_jdk_jfr_module_resolution_error(thread);
     return false;
   }
+  return true;
+}
 
-  return launch_recordings(thread);
+bool JfrRecorder::on_create_vm_3() {
+  assert(JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE, "invalid init sequence");
+  return launch_command_line_recordings(Thread::current());
 }
 
 static bool _created = false;
@@ -277,7 +282,6 @@
 }
 
 // subsystems
-static JfrJvmtiAgent* _jvmti_agent = NULL;
 static JfrPostBox* _post_box = NULL;
 static JfrStorage* _storage = NULL;
 static JfrCheckpointManager* _checkpoint_manager = NULL;
--- a/src/hotspot/share/jfr/recorder/jfrRecorder.hpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/recorder/jfrRecorder.hpp	Tue Nov 26 10:22:13 2019 +0000
@@ -38,6 +38,9 @@
   friend class Jfr;
   friend void recorderthread_entry(JavaThread*, Thread*);
  private:
+  static bool on_create_vm_1();
+  static bool on_create_vm_2();
+  static bool on_create_vm_3();
   static bool create_checkpoint_manager();
   static bool create_chunk_repository();
   static bool create_java_event_writer();
@@ -52,8 +55,6 @@
   static bool create_components();
   static void destroy_components();
   static void on_recorder_thread_exit();
-  static bool on_vm_start();
-  static bool on_vm_init();
 
  public:
   static bool is_enabled();
--- a/src/hotspot/share/jfr/recorder/service/jfrOptionSet.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/recorder/service/jfrOptionSet.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -677,7 +677,7 @@
   return false;
 }
 
-static GrowableArray<const char*>* startup_recording_options_array = NULL;
+static GrowableArray<const char*>* start_flight_recording_options_array = NULL;
 
 bool JfrOptionSet::parse_start_flight_recording_option(const JavaVMOption** option, char* delimiter) {
   assert(option != NULL, "invariant");
@@ -700,28 +700,28 @@
   assert(value != NULL, "invariant");
   const size_t value_length = strlen(value);
 
-  if (startup_recording_options_array == NULL) {
-    startup_recording_options_array = new (ResourceObj::C_HEAP, mtTracing) GrowableArray<const char*>(8, true, mtTracing);
+  if (start_flight_recording_options_array == NULL) {
+    start_flight_recording_options_array = new (ResourceObj::C_HEAP, mtTracing) GrowableArray<const char*>(8, true, mtTracing);
   }
-  assert(startup_recording_options_array != NULL, "invariant");
+  assert(start_flight_recording_options_array != NULL, "invariant");
   char* const startup_value = NEW_C_HEAP_ARRAY(char, value_length + 1, mtTracing);
   strncpy(startup_value, value, value_length + 1);
   assert(strncmp(startup_value, value, value_length) == 0, "invariant");
-  startup_recording_options_array->append(startup_value);
+  start_flight_recording_options_array->append(startup_value);
   return false;
 }
 
-const GrowableArray<const char*>* JfrOptionSet::startup_recording_options() {
-  return startup_recording_options_array;
+const GrowableArray<const char*>* JfrOptionSet::start_flight_recording_options() {
+  return start_flight_recording_options_array;
 }
 
-void JfrOptionSet::release_startup_recording_options() {
-  if (startup_recording_options_array != NULL) {
-    const int length = startup_recording_options_array->length();
+void JfrOptionSet::release_start_flight_recording_options() {
+  if (start_flight_recording_options_array != NULL) {
+    const int length = start_flight_recording_options_array->length();
     for (int i = 0; i < length; ++i) {
-      FREE_C_HEAP_ARRAY(char, startup_recording_options_array->at(i));
+      FREE_C_HEAP_ARRAY(char, start_flight_recording_options_array->at(i));
     }
-    delete startup_recording_options_array;
-    startup_recording_options_array = NULL;
+    delete start_flight_recording_options_array;
+    start_flight_recording_options_array = NULL;
   }
 }
--- a/src/hotspot/share/jfr/recorder/service/jfrOptionSet.hpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jfr/recorder/service/jfrOptionSet.hpp	Tue Nov 26 10:22:13 2019 +0000
@@ -80,8 +80,8 @@
 
   static bool parse_flight_recorder_option(const JavaVMOption** option, char* delimiter);
   static bool parse_start_flight_recording_option(const JavaVMOption** option, char* delimiter);
-  static const GrowableArray<const char*>* startup_recording_options();
-  static void release_startup_recording_options();
+  static const GrowableArray<const char*>* start_flight_recording_options();
+  static void release_start_flight_recording_options();
 };
 
 #endif // SHARE_JFR_RECORDER_SERVICE_JFROPTIONSET_HPP
--- a/src/hotspot/share/jvmci/jvmciRuntime.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -702,7 +702,7 @@
 }
 
 void JVMCINMethodData::invalidate_nmethod_mirror(nmethod* nm) {
-  oop nmethod_mirror = get_nmethod_mirror(nm, /* phantom_ref */ true);
+  oop nmethod_mirror = get_nmethod_mirror(nm, /* phantom_ref */ false);
   if (nmethod_mirror == NULL) {
     return;
   }
--- a/src/hotspot/share/runtime/safepoint.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/runtime/safepoint.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -620,19 +620,6 @@
       }
     }
 
-    if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_CLD_PURGE)) {
-      if (ClassLoaderDataGraph::should_purge_and_reset()) {
-        // CMS delays purging the CLDG until the beginning of the next safepoint and to
-        // make sure concurrent sweep is done
-        const char* name = "purging class loader data graph";
-        EventSafepointCleanupTask event;
-        TraceTime timer(name, TRACETIME_LOG(Info, safepoint, cleanup));
-        ClassLoaderDataGraph::purge();
-
-        post_safepoint_cleanup_task_event(event, safepoint_id, name);
-      }
-    }
-
     if (_subtasks.try_claim_task(SafepointSynchronize::SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE)) {
       if (Dictionary::does_any_dictionary_needs_resizing()) {
         const char* name = "resizing system dictionaries";
--- a/src/hotspot/share/runtime/safepoint.hpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/runtime/safepoint.hpp	Tue Nov 26 10:22:13 2019 +0000
@@ -75,7 +75,6 @@
     SAFEPOINT_CLEANUP_COMPILATION_POLICY,
     SAFEPOINT_CLEANUP_SYMBOL_TABLE_REHASH,
     SAFEPOINT_CLEANUP_STRING_TABLE_REHASH,
-    SAFEPOINT_CLEANUP_CLD_PURGE,
     SAFEPOINT_CLEANUP_SYSTEM_DICTIONARY_RESIZE,
     SAFEPOINT_CLEANUP_REQUEST_OOPSTORAGE_CLEANUP,
     // Leave this one last.
--- a/src/hotspot/share/runtime/thread.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/hotspot/share/runtime/thread.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -3887,7 +3887,7 @@
     return status;
   }
 
-  JFR_ONLY(Jfr::on_vm_init();)
+  JFR_ONLY(Jfr::on_create_vm_1();)
 
   // Should be done after the heap is fully created
   main_thread->cache_global_variables();
@@ -4026,6 +4026,8 @@
   // loaded until phase 2 completes
   call_initPhase2(CHECK_JNI_ERR);
 
+  JFR_ONLY(Jfr::on_create_vm_2();)
+
   // Always call even when there are not JVMTI environments yet, since environments
   // may be attached late and JVMTI must track phases of VM execution
   JvmtiExport::enter_start_phase();
@@ -4061,7 +4063,7 @@
   // Notify JVMTI agents that VM initialization is complete - nop if no agents.
   JvmtiExport::post_vm_initialized();
 
-  JFR_ONLY(Jfr::on_vm_start();)
+  JFR_ONLY(Jfr::on_create_vm_3();)
 
 #if INCLUDE_MANAGEMENT
   Management::initialize(THREAD);
--- a/src/java.base/share/classes/java/io/File.java	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/java.base/share/classes/java/io/File.java	Tue Nov 26 10:22:13 2019 +0000
@@ -29,6 +29,7 @@
 import java.net.URL;
 import java.net.MalformedURLException;
 import java.net.URISyntaxException;
+import java.nio.file.FileStore;
 import java.nio.file.FileSystems;
 import java.nio.file.Path;
 import java.security.SecureRandom;
@@ -1798,10 +1799,13 @@
 
     /**
      * Returns the size of the partition <a href="#partName">named</a> by this
-     * abstract pathname.
+     * abstract pathname. If the total number of bytes in the partition is
+     * greater than {@link Long#MAX_VALUE}, then {@code Long.MAX_VALUE} will be
+     * returned.
      *
      * @return  The size, in bytes, of the partition or {@code 0L} if this
-     *          abstract pathname does not name a partition
+     *          abstract pathname does not name a partition or if the size
+     *          cannot be obtained
      *
      * @throws  SecurityException
      *          If a security manager has been installed and it denies
@@ -1810,6 +1814,7 @@
      *          read access to the file named by this abstract pathname
      *
      * @since  1.6
+     * @see FileStore#getTotalSpace
      */
     public long getTotalSpace() {
         SecurityManager sm = System.getSecurityManager();
@@ -1820,12 +1825,15 @@
         if (isInvalid()) {
             return 0L;
         }
-        return fs.getSpace(this, FileSystem.SPACE_TOTAL);
+        long space = fs.getSpace(this, FileSystem.SPACE_TOTAL);
+        return space >= 0L ? space : Long.MAX_VALUE;
     }
 
     /**
      * Returns the number of unallocated bytes in the partition <a
-     * href="#partName">named</a> by this abstract path name.
+     * href="#partName">named</a> by this abstract path name.  If the
+     * number of unallocated bytes in the partition is greater than
+     * {@link Long#MAX_VALUE}, then {@code Long.MAX_VALUE} will be returned.
      *
      * <p> The returned number of unallocated bytes is a hint, but not
      * a guarantee, that it is possible to use most or any of these
@@ -1837,9 +1845,10 @@
      * will succeed.
      *
      * @return  The number of unallocated bytes on the partition or {@code 0L}
-     *          if the abstract pathname does not name a partition.  This
-     *          value will be less than or equal to the total file system size
-     *          returned by {@link #getTotalSpace}.
+     *          if the abstract pathname does not name a partition or if this
+     *          number cannot be obtained.  This value will be less than or
+     *          equal to the total file system size returned by
+     *          {@link #getTotalSpace}.
      *
      * @throws  SecurityException
      *          If a security manager has been installed and it denies
@@ -1848,6 +1857,7 @@
      *          read access to the file named by this abstract pathname
      *
      * @since  1.6
+     * @see FileStore#getUnallocatedSpace
      */
     public long getFreeSpace() {
         SecurityManager sm = System.getSecurityManager();
@@ -1858,16 +1868,19 @@
         if (isInvalid()) {
             return 0L;
         }
-        return fs.getSpace(this, FileSystem.SPACE_FREE);
+        long space = fs.getSpace(this, FileSystem.SPACE_FREE);
+        return space >= 0L ? space : Long.MAX_VALUE;
     }
 
     /**
      * Returns the number of bytes available to this virtual machine on the
-     * partition <a href="#partName">named</a> by this abstract pathname.  When
-     * possible, this method checks for write permissions and other operating
-     * system restrictions and will therefore usually provide a more accurate
-     * estimate of how much new data can actually be written than {@link
-     * #getFreeSpace}.
+     * partition <a href="#partName">named</a> by this abstract pathname.  If
+     * the number of available bytes in the partition is greater than
+     * {@link Long#MAX_VALUE}, then {@code Long.MAX_VALUE} will be returned.
+     * When possible, this method checks for write permissions and other
+     * operating system restrictions and will therefore usually provide a more
+     * accurate estimate of how much new data can actually be written than
+     * {@link #getFreeSpace}.
      *
      * <p> The returned number of available bytes is a hint, but not a
      * guarantee, that it is possible to use most or any of these bytes.  The
@@ -1878,9 +1891,10 @@
      * to this file system will succeed.
      *
      * @return  The number of available bytes on the partition or {@code 0L}
-     *          if the abstract pathname does not name a partition.  On
-     *          systems where this information is not available, this method
-     *          will be equivalent to a call to {@link #getFreeSpace}.
+     *          if the abstract pathname does not name a partition or if this
+     *          number cannot be obtained.  On systems where this information
+     *          is not available, this method will be equivalent to a call to
+     *          {@link #getFreeSpace}.
      *
      * @throws  SecurityException
      *          If a security manager has been installed and it denies
@@ -1889,6 +1903,7 @@
      *          read access to the file named by this abstract pathname
      *
      * @since  1.6
+     * @see FileStore#getUsableSpace
      */
     public long getUsableSpace() {
         SecurityManager sm = System.getSecurityManager();
@@ -1899,7 +1914,8 @@
         if (isInvalid()) {
             return 0L;
         }
-        return fs.getSpace(this, FileSystem.SPACE_USABLE);
+        long space = fs.getSpace(this, FileSystem.SPACE_USABLE);
+        return space >= 0L ? space : Long.MAX_VALUE;
     }
 
     /* -- Temporary files -- */
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java	Tue Nov 26 10:22:13 2019 +0000
@@ -2266,8 +2266,7 @@
 
             boolean isProtectedInSuperClassOfEnclosingClassInOtherPackage() {
                 return ((tree.sym.flags() & PROTECTED) != 0 &&
-                        tree.sym.packge() != owner.packge() &&
-                        !owner.enclClass().isSubClass(tree.sym.owner, types));
+                        tree.sym.packge() != owner.packge());
             }
 
             /**
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.services/src/jdk/vm/ci/services/Services.java	Tue Nov 26 10:22:13 2019 +0000
@@ -37,7 +37,6 @@
 import java.util.Set;
 
 import jdk.internal.misc.VM;
-import jdk.internal.reflect.Reflection;
 
 /**
  * Provides utilities needed by JVMCI clients.
@@ -136,29 +135,6 @@
         }
     }
 
-    private static boolean jvmciEnabled = true;
-
-    /**
-     * When {@code -XX:-UseJVMCIClassLoader} is in use, JVMCI classes are loaded via the boot class
-     * loader. When {@code null} is the second argument to
-     * {@link ServiceLoader#load(Class, ClassLoader)}, service lookup will use the system class
-     * loader and thus find application classes which violates the API of {@link #load} and
-     * {@link #loadSingle}. To avoid this, a class loader that simply delegates to the boot class
-     * loader is used.
-     */
-    static class LazyBootClassPath {
-        static final ClassLoader bootClassPath = new ClassLoader(null) {
-        };
-    }
-
-    private static ClassLoader findBootClassLoaderChild(ClassLoader start) {
-        ClassLoader cl = start;
-        while (cl.getParent() != null) {
-            cl = cl.getParent();
-        }
-        return cl;
-    }
-
     private static final Map<Class<?>, List<?>> servicesCache = IS_BUILDING_NATIVE_IMAGE ? new HashMap<>() : null;
 
     @SuppressWarnings("unchecked")
@@ -173,33 +149,7 @@
             }
         }
 
-        Iterable<S> providers = Collections.emptyList();
-        if (jvmciEnabled) {
-            ClassLoader cl = null;
-            try {
-                cl = getJVMCIClassLoader();
-                if (cl == null) {
-                    cl = LazyBootClassPath.bootClassPath;
-                    // JVMCI classes are loaded via the boot class loader.
-                    // If we use null as the second argument to ServiceLoader.load,
-                    // service loading will use the system class loader
-                    // and find classes on the application class path. Since we
-                    // don't want this, we use a loader that is as close to the
-                    // boot class loader as possible (since it is impossible
-                    // to force service loading to use only the boot class loader).
-                    cl = findBootClassLoaderChild(ClassLoader.getSystemClassLoader());
-                }
-                providers = ServiceLoader.load(service, cl);
-            } catch (UnsatisfiedLinkError e) {
-                jvmciEnabled = false;
-            } catch (InternalError e) {
-                if (e.getMessage().equals("JVMCI is not enabled")) {
-                    jvmciEnabled = false;
-                } else {
-                    throw e;
-                }
-            }
-        }
+        Iterable<S> providers = ServiceLoader.load(service, ClassLoader.getSystemClassLoader());
         if (IS_BUILDING_NATIVE_IMAGE) {
             synchronized (servicesCache) {
                 ArrayList<S> providersList = new ArrayList<>();
@@ -278,23 +228,6 @@
         return singleProvider;
     }
 
-    static {
-        Reflection.registerMethodsToFilter(Services.class, Set.of("getJVMCIClassLoader"));
-    }
-
-    /**
-     * Gets the JVMCI class loader.
-     *
-     * @throws InternalError with the {@linkplain Throwable#getMessage() message}
-     *             {@code "JVMCI is not enabled"} iff JVMCI is not enabled
-     */
-    private static ClassLoader getJVMCIClassLoader() {
-        if (IS_IN_NATIVE_IMAGE) {
-            return null;
-        }
-        return ClassLoader.getSystemClassLoader();
-    }
-
     /**
      * A Java {@code char} has a maximal UTF8 length of 3.
      */
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/JVM.java	Tue Nov 26 10:22:13 2019 +0000
@@ -203,6 +203,8 @@
      * Call to invoke event tagging and retransformation of the passed classes
      *
      * @param classes
+     *
+     * @throws IllegalStateException if wrong JVMTI phase.
      */
     public native synchronized void retransformClasses(Class<?>[] classes);
 
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java	Mon Nov 25 15:16:29 2019 +0000
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/instrument/JDKEvents.java	Tue Nov 26 10:22:13 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -123,6 +123,8 @@
             list.add(java.lang.Error.class);
             Logger.log(LogTag.JFR_SYSTEM, LogLevel.INFO, "Retransformed JDK classes");
             jvm.retransformClasses(list.toArray(new Class<?>[list.size()]));
+        } catch (IllegalStateException ise) {
+            throw ise;
         } catch (Exception e) {
             Logger.log(LogTag.JFR_SYSTEM, LogLevel.WARN, "Could not add instrumentation for JDK events. " + e.getMessage());
         }
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadState/thrstat001/thrstat001.cpp	Mon Nov 25 15:16:29 2019 +0000
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/GetThreadState/thrstat001/thrstat001.cpp	Tue Nov 26 10:22:13 2019 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,63 +39,72 @@
 static jvmtiCapabilities caps;
 static jvmtiEventCallbacks callbacks;
 static jrawMonitorID access_lock;
+static jrawMonitorID wait_lock;
 static jint result = PASSED;
-static jboolean printdump = JNI_FALSE;
 static jthread thr_ptr = NULL;
+
 static jint state[] = {
     JVMTI_THREAD_STATE_RUNNABLE,
     JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER,
     JVMTI_THREAD_STATE_IN_OBJECT_WAIT
 };
 
-static int entry_count = 0;
-static int entry_error_count = 0;
-static int exit_count = 0;
-static int exit_error_count = 0;
+static void
+lock(const char* func_name, jrawMonitorID lock) {
+    jvmtiError err = jvmti->RawMonitorEnter(lock);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("%s: unexpected error in RawMonitorEnter: %s (%d)\n",
+               func_name, TranslateError(err), err);
+        result = STATUS_FAILED;
+    }
+}
 
-void JNICALL VMInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr) {
-    jvmtiError err;
-
-    err = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
-        JVMTI_EVENT_THREAD_START, NULL);
+static void
+unlock(const char* func_name, jrawMonitorID lock) {
+    jvmtiError err = jvmti->RawMonitorExit(lock);
     if (err != JVMTI_ERROR_NONE) {
-        printf("Failed to enable THREAD_START event: %s (%d)\n",
-               TranslateError(err), err);
+        printf("%s: unexpected error in RawMonitorExit: %s (%d)\n",
+               func_name, TranslateError(err), err);
         result = STATUS_FAILED;
     }
+}
 
-    if (caps.can_generate_method_entry_events) {
-        err = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
-            JVMTI_EVENT_METHOD_ENTRY, NULL);
-        if (err != JVMTI_ERROR_NONE) {
-            printf("Failed to enable METHOD_ENTRY event: %s (%d)\n",
-                   TranslateError(err), err);
-            result = STATUS_FAILED;
-        }
+static void
+wait(const char* func_name, jrawMonitorID lock, jint millis) {
+    jvmtiError err = jvmti->RawMonitorWait(lock, (jlong)millis);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("%s: unexpected error in RawMonitorWait: %s (%d)\n",
+               func_name, TranslateError(err), err);
+        result = STATUS_FAILED;
     }
+}
 
-    if (caps.can_generate_method_exit_events) {
-        err = jvmti_env->SetEventNotificationMode(JVMTI_ENABLE,
-            JVMTI_EVENT_METHOD_EXIT, NULL);
-        if (err != JVMTI_ERROR_NONE) {
-            printf("Failed to enable METHOD_EXIT event: %s (%d)\n",
-                   TranslateError(err), err);
-            result = STATUS_FAILED;
-        }
+static void
+set_notification_mode(const char* event_name,
+                      jvmtiEventMode mode,
+                      jvmtiEvent event_type,
+                      jthread event_thread) {
+    const char* action = (mode == JVMTI_ENABLE) ? "enable" : "disable";
+    jvmtiError err = jvmti->SetEventNotificationMode(mode, event_type, event_thread);
+
+    if (err != JVMTI_ERROR_NONE) {
+        printf("Failed to %s %s event: %s (%d)\n",
+               action, event_name, TranslateError(err), err);
+        result = STATUS_FAILED;
     }
 }
 
+void JNICALL VMInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr) {
+    set_notification_mode("JVMTI_EVENT_THREAD_START", JVMTI_ENABLE,
+                          JVMTI_EVENT_THREAD_START, NULL);
+}
+
 void JNICALL
 ThreadStart(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) {
     jvmtiError err;
     jvmtiThreadInfo thrInfo;
 
-    err = jvmti_env->RawMonitorEnter(access_lock);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(RawMonitorEnter#TS) unexpected error: %s (%d)\n",
-               TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
+    lock("ThreadStart", access_lock);
 
     err = jvmti_env->GetThreadInfo(thread, &thrInfo);
     if (err != JVMTI_ERROR_NONE) {
@@ -105,111 +114,12 @@
     }
     if (thrInfo.name != NULL && strcmp(thrInfo.name, "thr1") == 0) {
         thr_ptr = env->NewGlobalRef(thread);
-        if (printdump == JNI_TRUE) {
-            printf(">>> ThreadStart: \"%s\", 0x%p\n", thrInfo.name, thr_ptr);
-        }
-    }
-
-    err = jvmti_env->RawMonitorExit(access_lock);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(RawMonitorExit#TS) unexpected error: %s (%d)\n",
-               TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
-}
-
-void JNICALL MethodEntry(jvmtiEnv *jvmti_env, JNIEnv *env,
-        jthread thread, jmethodID mid) {
-    jvmtiError err;
-    jvmtiThreadInfo thrInfo;
-    jint thrState;
-
-    err = jvmti_env->RawMonitorEnter(access_lock);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(RawMonitorEnter#ME) unexpected error: %s (%d)\n",
-               TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
-
-    entry_count++;
-    err = jvmti_env->GetThreadState(thread, &thrState);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(GetThreadState#ME) unexpected error: %s (%d)\n",
-            TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
-    if ((thrState & JVMTI_THREAD_STATE_RUNNABLE) == 0) {
-        if (entry_error_count == 0) {
-            err = jvmti_env->GetThreadInfo(thread, &thrInfo);
-            if (err != JVMTI_ERROR_NONE) {
-                printf("(GetThreadInfo#ME) unexpected error: %s (%d)\n",
-                       TranslateError(err), err);
-                result = STATUS_FAILED;
-            }
-            printf("Wrong thread \"%s\" state on MethodEntry event:\n",
-                   thrInfo.name);
-            printf("    expected: JVMTI_THREAD_STATE_RUNNABLE\n");
-            printf("    got: %s (%d)\n",
-                   TranslateState(thrState), thrState);
-        }
-        entry_error_count++;
-        result = STATUS_FAILED;
+        printf(">>> ThreadStart: \"%s\", 0x%p\n", thrInfo.name, thr_ptr);
+        set_notification_mode("JVMTI_EVENT_THREAD_START", JVMTI_DISABLE,
+                              JVMTI_EVENT_THREAD_START, NULL);
     }
 
-    err = jvmti_env->RawMonitorExit(access_lock);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(RawMonitorExit#ME) unexpected error: %s (%d)\n",
-               TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
-
-}
-
-void JNICALL MethodExit(jvmtiEnv *jvmti_env, JNIEnv *env,
-        jthread thread, jmethodID mid,
-        jboolean was_poped_by_exception, jvalue return_value) {
-    jvmtiError err;
-    jvmtiThreadInfo thrInfo;
-    jint thrState;
-
-    err = jvmti_env->RawMonitorEnter(access_lock);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(RawMonitorEnter#MX) unexpected error: %s (%d)\n",
-               TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
-
-    exit_count++;
-    err = jvmti_env->GetThreadState(thread, &thrState);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(GetThreadState#MX) unexpected error: %s (%d)\n",
-            TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
-    if ((thrState & JVMTI_THREAD_STATE_RUNNABLE) == 0) {
-        if (exit_error_count == 0) {
-            err = jvmti_env->GetThreadInfo(thread, &thrInfo);
-            if (err != JVMTI_ERROR_NONE) {
-                printf("(GetThreadInfo#MX) unexpected error: %s (%d)\n",
-                       TranslateError(err), err);
-                result = STATUS_FAILED;
-            }
-            printf("Wrong thread \"%s\" state on MethodExit event:\n",
-                   thrInfo.name);
-            printf("    expected: JVMTI_THREAD_STATE_RUNNABLE\n");
-            printf("    got: %s (%d)\n",
-                   TranslateState(thrState), thrState);
-        }
-        exit_error_count++;
-        result = STATUS_FAILED;
-    }
-
-    err = jvmti_env->RawMonitorExit(access_lock);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(RawMonitorExit#MX) unexpected error: %s (%d)\n",
-               TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
+    unlock("ThreadStart", access_lock);
 }
 
 #ifdef STATIC_BUILD
@@ -223,13 +133,12 @@
     return JNI_VERSION_1_8;
 }
 #endif
+
 jint  Agent_Initialize(JavaVM *jvm, char *options, void *reserved) {
     jint res;
     jvmtiError err;
 
-    if (options != NULL && strcmp(options, "printdump") == 0) {
-        printdump = JNI_TRUE;
-    }
+    printf("Agent_Initialize started\n");
 
     res = jvm->GetEnv((void **) &jvmti, JVMTI_VERSION_1_1);
     if (res != JNI_OK || jvmti == NULL) {
@@ -260,23 +169,20 @@
 
     err = jvmti->CreateRawMonitor("_access_lock", &access_lock);
     if (err != JVMTI_ERROR_NONE) {
-        printf("(CreateRawMonitor) unexpected error: %s (%d)\n",
+        printf("(CreateRawMonitor)#access_lock unexpected error: %s (%d)\n",
+               TranslateError(err), err);
+        return JNI_ERR;
+    }
+
+    err = jvmti->CreateRawMonitor("_wait_lock", &wait_lock);
+    if (err != JVMTI_ERROR_NONE) {
+        printf("(CreateRawMonitor#wait_lock) unexpected error: %s (%d)\n",
                TranslateError(err), err);
         return JNI_ERR;
     }
 
     callbacks.VMInit = &VMInit;
     callbacks.ThreadStart = &ThreadStart;
-    if (caps.can_generate_method_entry_events) {
-        callbacks.MethodEntry = &MethodEntry;
-    } else {
-        printf("Warning: MethodEntry event is not implemented\n");
-    }
-    if (caps.can_generate_method_exit_events) {
-        callbacks.MethodExit = &MethodExit;
-    } else {
-        printf("Warning: MethodExit event is not implemented\n");
-    }
     err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
     if (err != JVMTI_ERROR_NONE) {
         printf("(SetEventCallbacks) unexpected error: %s (%d)\n",
@@ -284,14 +190,10 @@
         return JNI_ERR;
     }
 
-    err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
-        JVMTI_EVENT_VM_INIT, NULL);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("Failed to enable VM_INIT event: %s (%d)\n",
-               TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
+    set_notification_mode("JVMTI_EVENT_VM_INIT", JVMTI_ENABLE,
+                          JVMTI_EVENT_VM_INIT, NULL);
 
+    printf("Agent_Initialize finished\n\n");
     return JNI_OK;
 }
 
@@ -299,10 +201,10 @@
 Java_nsk_jvmti_GetThreadState_thrstat001_checkStatus(JNIEnv *env,
         jclass cls, jint statInd) {
     jvmtiError err;
-    jrawMonitorID wait_lock;
     jint thrState;
     jint millis;
 
+    printf("native method checkStatus started\n");
     if (jvmti == NULL) {
         printf("JVMTI client was not properly loaded!\n");
         result = STATUS_FAILED;
@@ -316,12 +218,6 @@
     }
 
     /* wait until thread gets an expected state */
-    err = jvmti->CreateRawMonitor("_wait_lock", &wait_lock);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(CreateRawMonitor) unexpected error: %s (%d)\n",
-               TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
     for (millis = WAIT_START; millis < WAIT_TIME; millis <<= 1) {
         err = jvmti->GetThreadState(thr_ptr, &thrState);
         if (err != JVMTI_ERROR_NONE) {
@@ -332,36 +228,13 @@
         if ((thrState & state[statInd]) != 0) {
             break;
         }
-        err = jvmti->RawMonitorEnter(wait_lock);
-        if (err != JVMTI_ERROR_NONE) {
-            printf("(RawMonitorEnter) unexpected error: %s (%d)\n",
-                   TranslateError(err), err);
-            result = STATUS_FAILED;
-        }
-        err = jvmti->RawMonitorWait(wait_lock, (jlong)millis);
-        if (err != JVMTI_ERROR_NONE) {
-            printf("(RawMonitorWait) unexpected error: %s (%d)\n",
-                   TranslateError(err), err);
-            result = STATUS_FAILED;
-        }
-        err = jvmti->RawMonitorExit(wait_lock);
-        if (err != JVMTI_ERROR_NONE) {
-            printf("(RawMonitorExit) unexpected error: %s (%d)\n",
-                   TranslateError(err), err);
-            result = STATUS_FAILED;
-        }
-    }
-    err = jvmti->DestroyRawMonitor(wait_lock);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("(DestroyRawMonitor) unexpected error: %s (%d)\n",
-               TranslateError(err), err);
-        result = STATUS_FAILED;
+        lock("checkStatus", wait_lock);
+        wait("checkStatus", wait_lock, millis);
+        unlock("checkStatus", wait_lock);
     }
 
-    if (printdump == JNI_TRUE) {
-        printf(">>> thread \"thr1\" (0x%p) state: %s (%d)\n",
+    printf(">>> thread \"thr1\" (0x%p) state: %s (%d)\n",
             thr_ptr, TranslateState(thrState), thrState);
-    }
 
     if ((thrState & state[statInd]) == 0) {
         printf("Wrong thread \"thr1\" (0x%p) state:\n", thr_ptr);
@@ -371,55 +244,12 @@
             TranslateState(thrState), thrState);
         result = STATUS_FAILED;
     }
+    printf("native method checkStatus finished\n\n");
 }
 
 JNIEXPORT jint JNICALL
 Java_nsk_jvmti_GetThreadState_thrstat001_getRes(JNIEnv *env, jclass cls) {
-    jvmtiError err;
-
-    err = jvmti->SetEventNotificationMode(JVMTI_DISABLE,
-        JVMTI_EVENT_THREAD_START, NULL);
-    if (err != JVMTI_ERROR_NONE) {
-        printf("Failed to disable THREAD_START event: %s (%d)\n",
-               TranslateError(err), err);
-        result = STATUS_FAILED;
-    }
-
-    if (caps.can_generate_method_entry_events) {
-        err = jvmti->SetEventNotificationMode(JVMTI_DISABLE,
-            JVMTI_EVENT_METHOD_ENTRY, NULL);
-        if (err != JVMTI_ERROR_NONE) {
-            printf("Failed to disable METHOD_ENTRY event: %s (%d)\n",
-                   TranslateError(err), err);
-            result = STATUS_FAILED;
-        }
-    }
-
-    if (caps.can_generate_method_exit_events) {
-        err = jvmti->SetEventNotificationMode(JVMTI_DISABLE,
-            JVMTI_EVENT_METHOD_EXIT, NULL);
-        if (err != JVMTI_ERROR_NONE) {
-            printf("Failed to disable METHOD_EXIT event: %s (%d)\n",
-                   TranslateError(err), err);
-            result = STATUS_FAILED;
-        }
-    }
-
-    if (printdump == JNI_TRUE) {
-        printf(">>> total number of method entry events = %d\n", entry_count);
-        printf(">>> total number of method exit events = %d\n", exit_count);
-    }
-
-    if (entry_error_count != 0) {
-        printf("Total number of errors on METHOD_ENTRY: %d of %d events\n",
-               entry_error_count, entry_count);
-    }
-
-    if (exit_error_count != 0) {
-        printf("Total number of errors on METHOD_EXIT: %d of %d events\n",
-               exit_error_count, exit_count);
-    }
-
+    printf("native method getRes: result: %d\n\n", result);
     return result;
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/methodReference/ProtectedInaccessibleMethodRefTest2.java	Tue Nov 26 10:22:13 2019 +0000
@@ -0,0 +1,67 @@
+/*
+ * 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 8234729
+ * @summary Javac should eagerly change code generation for method references to avert IllegalAccessError in future.
+ * @run main ProtectedInaccessibleMethodRefTest2
+ */
+
+import pack.I;
+import pack.J;
+
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.function.Function;
+import java.lang.reflect.Method;
+import java.util.concurrent.Callable;
+
+public final class ProtectedInaccessibleMethodRefTest2 extends I {
+
+    public static void main(String... args) {
+        ProtectedInaccessibleMethodRefTest2 m = new ProtectedInaccessibleMethodRefTest2();
+        m.test(Paths.get("test"));
+        // Verify that the method reference has been folded into a lambda.
+        boolean lambdaFound = false;
+        for (Method meth : ProtectedInaccessibleMethodRefTest2.class.getDeclaredMethods()) {
+            if (meth.getName().equals("lambda$test$0")) {
+                lambdaFound = true;
+                break;
+            }
+        }
+        if (!lambdaFound) {
+            throw new AssertionError("Did not find evidence of new code generation");
+        }
+    }
+
+    void test(Path outputDir) {
+        Sub c = new Sub(this::readFile);
+        c.check(outputDir);
+    }
+    public class Sub extends J {
+        Sub(Function<Path,String> fileReader) {
+            super(fileReader);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/methodReference/pack/I.java	Tue Nov 26 10:22:13 2019 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pack;
+
+import java.nio.file.Path;
+
+public class I {
+    protected String readFile(Path file) {
+        return file.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/lambda/methodReference/pack/J.java	Tue Nov 26 10:22:13 2019 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pack;
+
+import java.nio.file.Path;
+import java.util.function.Function;
+
+public class J {
+    protected final Function<Path,String> fileReader;
+
+    public J(Function<Path,String> fileReader) {
+        this.fileReader = fileReader;
+    }
+
+    protected void checkFile(Path file) {
+        fileReader.apply(file);
+    }
+
+    public void check(Path file) {
+        checkFile(file);
+    }
+}