< prev index next >

src/hotspot/share/prims/jvmtiCodeBlobEvents.cpp

Print this page

        

@@ -217,29 +217,31 @@
 }
 
 
 // Generate a COMPILED_METHOD_LOAD event for each nnmethod
 jvmtiError JvmtiCodeBlobEvents::generate_compiled_method_load_events(JvmtiEnv* env) {
-  HandleMark hm;
-
-  // Walk the CodeCache notifying for live nmethods.  The code cache
-  // may be changing while this is happening which is ok since newly
-  // created nmethod will notify normally and nmethods which are freed
-  // can be safely skipped.
+  JavaThread* current_thread = JavaThread::current();
+  {
+    // Walk the CodeCache notifying for live nmethods, don't release the CodeCache_lock
+    // because the sweeper may be running concurrently.
+    // Save events to the queue for posting outside the CodeCache_lock.
   MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   // Iterate over non-profiled and profiled nmethods
   NMethodIterator iter(NMethodIterator::only_alive_and_not_unloading);
   while(iter.next()) {
     nmethod* current = iter.method();
-    // Lock the nmethod so it can't be freed
-    nmethodLocker nml(current);
-
-    // Don't hold the lock over the notify or jmethodID creation
-    MutexUnlocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    current->get_and_cache_jmethod_id();
-    JvmtiExport::post_compiled_method_load(env, current);
+      current->post_compiled_method_load_event(current_thread);
   }
+  }
+
+  // Now post all the events outside the CodeCache_lock.
+  // If there's a safepoint, the queued events will be kept alive.
+  // Adding these events to the service thread to post is something that
+  // should work, but the service thread doesn't keep up in stress scenarios and
+  // the os eventually kills the process with OOM.
+  // We want this thread to wait until the events are all posted.
+  current_thread->post_events(env);
   return JVMTI_ERROR_NONE;
 }
 
 
 // create a C-heap allocated address location map for an nmethod
< prev index next >