< prev index next >

src/hotspot/share/prims/jvmtiExport.cpp

Print this page

        

*** 1347,1404 **** void JvmtiExport::post_class_unload(Klass* klass) { if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) { return; } - Thread *thread = Thread::current(); - HandleMark hm(thread); ! EVT_TRIG_TRACE(EXT_EVENT_CLASS_UNLOAD, ("[?] Trg Class Unload triggered" )); ! if (JvmtiEventController::is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) { ! assert(thread->is_VM_thread(), "wrong thread"); ! // get JavaThread for whom we are proxy ! Thread *calling_thread = ((VMThread *)thread)->vm_operation()->calling_thread(); ! if (!calling_thread->is_Java_thread()) { ! // cannot post an event to a non-JavaThread return; } ! JavaThread *real_thread = (JavaThread *)calling_thread; JvmtiEnvIterator it; for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { if (env->phase() == JVMTI_PHASE_PRIMORDIAL) { continue; } if (env->is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) { ! EVT_TRACE(EXT_EVENT_CLASS_UNLOAD, ("[?] Evt Class Unload sent %s", ! klass==NULL? "NULL" : klass->external_name() )); ! ! // do everything manually, since this is a proxy - needs special care ! JNIEnv* jni_env = real_thread->jni_environment(); ! jthread jt = (jthread)JNIHandles::make_local(real_thread, real_thread->threadObj()); ! jclass jk = (jclass)JNIHandles::make_local(real_thread, klass->java_mirror()); ! ! // Before we call the JVMTI agent, we have to set the state in the ! // thread for which we are proxying. ! JavaThreadState prev_state = real_thread->thread_state(); ! assert(((Thread *)real_thread)->is_ConcurrentGC_thread() || ! (real_thread->is_Java_thread() && prev_state == _thread_blocked), ! "should be ConcurrentGCThread or JavaThread at safepoint"); ! real_thread->set_thread_state(_thread_in_native); jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload; if (callback != NULL) { ! (*callback)(env->jvmti_external(), jni_env, jt, jk); } - - assert(real_thread->thread_state() == _thread_in_native, - "JavaThread should be in native"); - real_thread->set_thread_state(prev_state); - - JNIHandles::destroy_local(jk); - JNIHandles::destroy_local(jt); } } } } --- 1347,1392 ---- void JvmtiExport::post_class_unload(Klass* klass) { if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) { return; } ! // postings to the service thread so that it can perform them in a safe ! // context and in-order. ! MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); ! ResourceMark rm; ! // JvmtiDeferredEvent copies the string. ! JvmtiDeferredEvent event = JvmtiDeferredEvent::class_unload_event(klass->name()->as_C_string()); ! JvmtiDeferredEventQueue::enqueue(event); ! } ! ! void JvmtiExport::post_class_unload_internal(const char* name) { ! if (JvmtiEnv::get_phase() < JVMTI_PHASE_PRIMORDIAL) { return; } ! assert(Thread::current()->is_Java_thread(), "must be called from ServiceThread"); ! JavaThread *thread = JavaThread::current(); ! HandleMark hm(thread); ! ! EVT_TRIG_TRACE(EXT_EVENT_CLASS_UNLOAD, ("[?] Trg Class Unload triggered" )); ! if (JvmtiEventController::is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) { JvmtiEnvIterator it; for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { if (env->phase() == JVMTI_PHASE_PRIMORDIAL) { continue; } if (env->is_enabled((jvmtiEvent)EXT_EVENT_CLASS_UNLOAD)) { ! EVT_TRACE(EXT_EVENT_CLASS_UNLOAD, ("[?] Evt Class Unload sent %s", name)); + JvmtiEventMark jem(thread); + JvmtiJavaThreadEventTransition jet(thread); jvmtiExtensionEvent callback = env->ext_callbacks()->ClassUnload; if (callback != NULL) { ! (*callback)(env->jvmti_external(), jem.jni_env(), name); } } } } }
< prev index next >