724 bool JvmtiExport::_have_pending_compiled_method_unload_events; |
724 bool JvmtiExport::_have_pending_compiled_method_unload_events; |
725 GrowableArray<jmethodID>* JvmtiExport::_pending_compiled_method_unload_method_ids; |
725 GrowableArray<jmethodID>* JvmtiExport::_pending_compiled_method_unload_method_ids; |
726 GrowableArray<const void *>* JvmtiExport::_pending_compiled_method_unload_code_begins; |
726 GrowableArray<const void *>* JvmtiExport::_pending_compiled_method_unload_code_begins; |
727 JavaThread* JvmtiExport::_current_poster; |
727 JavaThread* JvmtiExport::_current_poster; |
728 |
728 |
|
729 void JvmtiExport::post_compiled_method_unload_internal(JavaThread* self, jmethodID method, const void *code_begin) { |
|
730 EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, |
|
731 ("JVMTI [%s] method compile unload event triggered", |
|
732 JvmtiTrace::safe_get_thread_name(self))); |
|
733 |
|
734 // post the event for each environment that has this event enabled. |
|
735 JvmtiEnvIterator it; |
|
736 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { |
|
737 if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) { |
|
738 |
|
739 EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, |
|
740 ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT, |
|
741 JvmtiTrace::safe_get_thread_name(self), method)); |
|
742 |
|
743 ResourceMark rm(self); |
|
744 |
|
745 JvmtiEventMark jem(self); |
|
746 JvmtiJavaThreadEventTransition jet(self); |
|
747 jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload; |
|
748 if (callback != NULL) { |
|
749 (*callback)(env->jvmti_external(), method, code_begin); |
|
750 } |
|
751 } |
|
752 } |
|
753 } |
|
754 |
729 // post any pending CompiledMethodUnload events |
755 // post any pending CompiledMethodUnload events |
730 |
756 |
731 void JvmtiExport::post_pending_compiled_method_unload_events() { |
757 void JvmtiExport::post_pending_compiled_method_unload_events() { |
732 JavaThread* self = JavaThread::current(); |
758 JavaThread* self = JavaThread::current(); |
733 assert(!self->owns_locks(), "can't hold locks"); |
759 assert(!self->owns_locks(), "can't hold locks"); |
786 // re-grabs the monitor and checks the list again. If the list is empty then and this |
812 // re-grabs the monitor and checks the list again. If the list is empty then and this |
787 // is the first activation of the function then we reset the _have_pending_events |
813 // is the first activation of the function then we reset the _have_pending_events |
788 // flag, cleanup _current_poster to indicate that no thread is now servicing the |
814 // flag, cleanup _current_poster to indicate that no thread is now servicing the |
789 // pending events list, and finally notify any thread that might be waiting. |
815 // pending events list, and finally notify any thread that might be waiting. |
790 for (;;) { |
816 for (;;) { |
791 EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, |
817 post_compiled_method_unload_internal(self, method, code_begin); |
792 ("JVMTI [%s] method compile unload event triggered", |
|
793 JvmtiTrace::safe_get_thread_name(self))); |
|
794 |
|
795 // post the event for each environment that has this event enabled. |
|
796 JvmtiEnvIterator it; |
|
797 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) { |
|
798 if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_UNLOAD)) { |
|
799 EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_UNLOAD, |
|
800 ("JVMTI [%s] class compile method unload event sent jmethodID " PTR_FORMAT, |
|
801 JvmtiTrace::safe_get_thread_name(self), method)); |
|
802 |
|
803 JvmtiEventMark jem(self); |
|
804 JvmtiJavaThreadEventTransition jet(self); |
|
805 jvmtiEventCompiledMethodUnload callback = env->callbacks()->CompiledMethodUnload; |
|
806 if (callback != NULL) { |
|
807 (*callback)(env->jvmti_external(), method, code_begin); |
|
808 } |
|
809 } |
|
810 } |
|
811 |
818 |
812 // event posted, now re-grab monitor and get the next event |
819 // event posted, now re-grab monitor and get the next event |
813 // If there's no next event then we are done. If this is the first |
820 // If there's no next event then we are done. If this is the first |
814 // activiation of this function by this thread notify any waiters |
821 // activiation of this function by this thread notify any waiters |
815 // so that they can post. |
822 // so that they can post. |
1862 } |
1869 } |
1863 } |
1870 } |
1864 } |
1871 } |
1865 |
1872 |
1866 // used at a safepoint to post a CompiledMethodUnload event |
1873 // used at a safepoint to post a CompiledMethodUnload event |
1867 void JvmtiExport::post_compiled_method_unload_at_safepoint(jmethodID mid, const void *code_begin) { |
1874 void JvmtiExport::post_compiled_method_unload(jmethodID mid, const void *code_begin) { |
1868 assert(SafepointSynchronize::is_at_safepoint(), "must be executed at a safepoint"); |
1875 if (SafepointSynchronize::is_at_safepoint()) { |
1869 |
1876 // Class unloading can cause nmethod unloading which is reported |
1870 // create list lazily |
1877 // by the VMThread. These must be batched to be processed later. |
1871 if (_pending_compiled_method_unload_method_ids == NULL) { |
1878 if (_pending_compiled_method_unload_method_ids == NULL) { |
1872 _pending_compiled_method_unload_method_ids = new (ResourceObj::C_HEAP) GrowableArray<jmethodID>(10,true); |
1879 // create list lazily |
1873 _pending_compiled_method_unload_code_begins = new (ResourceObj::C_HEAP) GrowableArray<const void *>(10,true); |
1880 _pending_compiled_method_unload_method_ids = new (ResourceObj::C_HEAP) GrowableArray<jmethodID>(10,true); |
1874 } |
1881 _pending_compiled_method_unload_code_begins = new (ResourceObj::C_HEAP) GrowableArray<const void *>(10,true); |
1875 _pending_compiled_method_unload_method_ids->append(mid); |
1882 } |
1876 _pending_compiled_method_unload_code_begins->append(code_begin); |
1883 _pending_compiled_method_unload_method_ids->append(mid); |
1877 _have_pending_compiled_method_unload_events = true; |
1884 _pending_compiled_method_unload_code_begins->append(code_begin); |
|
1885 _have_pending_compiled_method_unload_events = true; |
|
1886 } else { |
|
1887 // Unloading caused by the sweeper can be reported synchronously. |
|
1888 if (have_pending_compiled_method_unload_events()) { |
|
1889 post_pending_compiled_method_unload_events(); |
|
1890 } |
|
1891 post_compiled_method_unload_internal(JavaThread::current(), mid, code_begin); |
|
1892 } |
1878 } |
1893 } |
1879 |
1894 |
1880 void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) { |
1895 void JvmtiExport::post_dynamic_code_generated_internal(const char *name, const void *code_begin, const void *code_end) { |
1881 JavaThread* thread = JavaThread::current(); |
1896 JavaThread* thread = JavaThread::current(); |
1882 EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, |
1897 EVT_TRIG_TRACE(JVMTI_EVENT_DYNAMIC_CODE_GENERATED, |