< 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 >