--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp Wed Jun 02 12:02:49 2010 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp Wed Jun 02 14:23:23 2010 -0700
@@ -726,6 +726,32 @@
GrowableArray<const void *>* JvmtiExport::_pending_compiled_method_unload_code_begins;
JavaThread* JvmtiExport::_current_poster;
+void JvmtiExport::post_compiled_method_unload_internal(JavaThread* self, jmethodID method, const void *code_begin) {
+ EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
+ ("JVMTI [%s] method compile unload event triggered",
+ JvmtiTrace::safe_get_thread_name(self)));
+
+ // post the event for each environment that has this event enabled.
+ JvmtiEnvIterator it;
+ for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
+ if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {
+
+ EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
+ ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT,
+ JvmtiTrace::safe_get_thread_name(self), method));
+
+ ResourceMark rm(self);
+
+ JvmtiEventMark jem(self);
+ JvmtiJavaThreadEventTransition jet(self);
+ jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;
+ if (callback != NULL) {
+ (*callback)(env->jvmti_external(), method, code_begin);
+ }
+ }
+ }
+}
+
// post any pending CompiledMethodUnload events
void JvmtiExport::post_pending_compiled_method_unload_events() {
@@ -788,26 +814,7 @@
// flag, cleanup _current_poster to indicate that no thread is now servicing the
// pending events list, and finally notify any thread that might be waiting.
for (;;) {
- EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
- ("JVMTI [%s] method compile unload event triggered",
- JvmtiTrace::safe_get_thread_name(self)));
-
- // post the event for each environment that has this event enabled.
- JvmtiEnvIterator it;
- for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
- if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) {
- EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD,
- ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT,
- JvmtiTrace::safe_get_thread_name(self), method));
-
- JvmtiEventMark jem(self);
- JvmtiJavaThreadEventTransition jet(self);
- jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload;
- if (callback != NULL) {
- (*callback)(env->jvmti_external(), method, code_begin);
- }
- }
- }
+ post_compiled_method_unload_internal(self, method, code_begin);
// event posted, now re-grab monitor and get the next event
// If there's no next event then we are done. If this is the first
@@ -1864,17 +1871,25 @@
}
// used at a safepoint to post a CompiledMethodUnload event
-void JvmtiExport::post_compiled_method_unload_at_safepoint(jmethodID mid, const void *code_begin) {
- assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint");
-
- // create list lazily
- if (_pending_compiled_method_unload_method_ids == NULL) {
- _pending_compiled_method_unload_method_ids = new (ResourceObj::C_HEAP) GrowableArray<jmethodID>(10,true);
- _pending_compiled_method_unload_code_begins = new (ResourceObj::C_HEAP) GrowableArray<const void *>(10,true);
+void JvmtiExport::post_compiled_method_unload(jmethodID mid, const void *code_begin) {
+ if (SafepointSynchronize::is_at_safepoint()) {
+ // Class unloading can cause nmethod unloading which is reported
+ // by the VMThread. These must be batched to be processed later.
+ if (_pending_compiled_method_unload_method_ids == NULL) {
+ // create list lazily
+ _pending_compiled_method_unload_method_ids = new (ResourceObj::C_HEAP) GrowableArray<jmethodID>(10,true);
+ _pending_compiled_method_unload_code_begins = new (ResourceObj::C_HEAP) GrowableArray<const void *>(10,true);
+ }
+ _pending_compiled_method_unload_method_ids->append(mid);
+ _pending_compiled_method_unload_code_begins->append(code_begin);
+ _have_pending_compiled_method_unload_events = true;
+ } else {
+ // Unloading caused by the sweeper can be reported synchronously.
+ if (have_pending_compiled_method_unload_events()) {
+ post_pending_compiled_method_unload_events();
+ }
+ post_compiled_method_unload_internal(JavaThread::current(), mid, code_begin);
}
- _pending_compiled_method_unload_method_ids->append(mid);
- _pending_compiled_method_unload_code_begins->append(code_begin);
- _have_pending_compiled_method_unload_events = true;
}
void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) {