1 /*
2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
669 private:
670 jobject _jobj;
671 jlong _size;
672 public:
673 JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klassOop(obj)) {
674 _jobj = (jobject)to_jobject(obj);
675 _size = obj->size() * wordSize;
676 };
677 jobject jni_jobject() { return _jobj; }
678 jlong size() { return _size; }
679 };
680
681 class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark {
682 private:
683 jint _code_size;
684 const void *_code_data;
685 jint _map_length;
686 jvmtiAddrLocationMap *_map;
687 const void *_compile_info;
688 public:
689 JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm)
690 : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
691 _code_data = nm->code_begin();
692 _code_size = nm->code_size();
693 _compile_info = NULL; /* no info for our VM. */
694 JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
695 }
696 ~JvmtiCompiledMethodLoadEventMark() {
697 FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map);
698 }
699
700 jint code_size() { return _code_size; }
701 const void *code_data() { return _code_data; }
702 jint map_length() { return _map_length; }
703 const jvmtiAddrLocationMap* map() { return _map; }
704 const void *compile_info() { return _compile_info; }
705 };
706
707
708
709 class JvmtiMonitorEventMark : public JvmtiThreadEventMark {
710 private:
711 jobject _jobj;
712 public:
713 JvmtiMonitorEventMark(JavaThread *thread, oop object)
1735 if (JvmtiEventController::is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {
1736 JvmtiEnvIterator it;
1737 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
1738 if (env->is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {
1739 EVT_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("JVMTI [%s] Evt Native Method Bind event sent",
1740 JvmtiTrace::safe_get_thread_name(thread) ));
1741
1742 JvmtiMethodEventMark jem(thread, mh);
1743 JvmtiJavaThreadEventTransition jet(thread);
1744 JNIEnv* jni_env = JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL? NULL : jem.jni_env();
1745 jvmtiEventNativeMethodBind callback = env->callbacks()->NativeMethodBind;
1746 if (callback != NULL) {
1747 (*callback)(env->jvmti_external(), jni_env, jem.jni_thread(),
1748 jem.jni_methodID(), (void*)(*function_ptr), (void**)function_ptr);
1749 }
1750 }
1751 }
1752 }
1753 }
1754
1755
1756 void JvmtiExport::post_compiled_method_load(nmethod *nm) {
1757 // If there are pending CompiledMethodUnload events then these are
1758 // posted before this CompiledMethodLoad event. We "lock" the nmethod and
1759 // maintain a handle to the methodOop to ensure that the nmethod isn't
1760 // flushed or unloaded while posting the events.
1761 JavaThread* thread = JavaThread::current();
1762 if (have_pending_compiled_method_unload_events()) {
1763 methodHandle mh(thread, nm->method());
1764 nmethodLocker nml(nm);
1765 post_pending_compiled_method_unload_events();
1766 }
1767
1768 EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
1769 ("JVMTI [%s] method compile load event triggered",
1770 JvmtiTrace::safe_get_thread_name(thread)));
1771
1772 JvmtiEnvIterator it;
1773 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
1774 if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) {
1775
1776 EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
1777 ("JVMTI [%s] class compile method load event sent %s.%s ",
1778 JvmtiTrace::safe_get_thread_name(thread),
1779 (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(),
1780 (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
1781
1782 ResourceMark rm(thread);
1783 JvmtiCompiledMethodLoadEventMark jem(thread, nm);
1784 JvmtiJavaThreadEventTransition jet(thread);
1785 jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
1786 if (callback != NULL) {
1787 (*callback)(env->jvmti_external(), jem.jni_methodID(),
1788 jem.code_size(), jem.code_data(), jem.map_length(),
1789 jem.map(), jem.compile_info());
1790 }
1791 }
1792 }
1793 }
1794
1795
1796 // post a COMPILED_METHOD_LOAD event for a given environment
1797 void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length,
1798 const void *code_begin, const jint map_length,
1799 const jvmtiAddrLocationMap* map)
1800 {
1801 JavaThread* thread = JavaThread::current();
1802 EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
1803 ("JVMTI [%s] method compile load event triggered (by GenerateEvents)",
|
1 /*
2 * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
669 private:
670 jobject _jobj;
671 jlong _size;
672 public:
673 JvmtiVMObjectAllocEventMark(JavaThread *thread, oop obj) : JvmtiClassEventMark(thread, oop_to_klassOop(obj)) {
674 _jobj = (jobject)to_jobject(obj);
675 _size = obj->size() * wordSize;
676 };
677 jobject jni_jobject() { return _jobj; }
678 jlong size() { return _size; }
679 };
680
681 class JvmtiCompiledMethodLoadEventMark : public JvmtiMethodEventMark {
682 private:
683 jint _code_size;
684 const void *_code_data;
685 jint _map_length;
686 jvmtiAddrLocationMap *_map;
687 const void *_compile_info;
688 public:
689 JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm, void* compile_info_ptr = NULL)
690 : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) {
691 _code_data = nm->code_begin();
692 _code_size = nm->code_size();
693 _compile_info = compile_info_ptr; // Set void pointer of compiledMethodLoad Event. Default value is NULL.
694 JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
695 }
696 ~JvmtiCompiledMethodLoadEventMark() {
697 FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map);
698 }
699
700 jint code_size() { return _code_size; }
701 const void *code_data() { return _code_data; }
702 jint map_length() { return _map_length; }
703 const jvmtiAddrLocationMap* map() { return _map; }
704 const void *compile_info() { return _compile_info; }
705 };
706
707
708
709 class JvmtiMonitorEventMark : public JvmtiThreadEventMark {
710 private:
711 jobject _jobj;
712 public:
713 JvmtiMonitorEventMark(JavaThread *thread, oop object)
1735 if (JvmtiEventController::is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {
1736 JvmtiEnvIterator it;
1737 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
1738 if (env->is_enabled(JVMTI_EVENT_NATIVE_METHOD_BIND)) {
1739 EVT_TRACE(JVMTI_EVENT_NATIVE_METHOD_BIND, ("JVMTI [%s] Evt Native Method Bind event sent",
1740 JvmtiTrace::safe_get_thread_name(thread) ));
1741
1742 JvmtiMethodEventMark jem(thread, mh);
1743 JvmtiJavaThreadEventTransition jet(thread);
1744 JNIEnv* jni_env = JvmtiEnv::get_phase() == JVMTI_PHASE_PRIMORDIAL? NULL : jem.jni_env();
1745 jvmtiEventNativeMethodBind callback = env->callbacks()->NativeMethodBind;
1746 if (callback != NULL) {
1747 (*callback)(env->jvmti_external(), jni_env, jem.jni_thread(),
1748 jem.jni_methodID(), (void*)(*function_ptr), (void**)function_ptr);
1749 }
1750 }
1751 }
1752 }
1753 }
1754
1755 // Returns a record containing inlining information for the given nmethod
1756 jvmtiCompiledMethodLoadInlineRecord* create_inline_record(nmethod* nm) {
1757 jint numstackframes = 0;
1758 jvmtiCompiledMethodLoadInlineRecord* record = (jvmtiCompiledMethodLoadInlineRecord*)NEW_RESOURCE_OBJ(jvmtiCompiledMethodLoadInlineRecord);
1759 record->header.kind = JVMTI_CMLR_INLINE_INFO;
1760 record->header.next = NULL;
1761 record->header.majorinfoversion = JVMTI_CMLR_MAJOR_VERSION_1;
1762 record->header.minorinfoversion = JVMTI_CMLR_MINOR_VERSION_0;
1763 record->numpcs = 0;
1764 for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) {
1765 if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue;
1766 record->numpcs++;
1767 }
1768 record->pcinfo = (PCStackInfo*)(NEW_RESOURCE_ARRAY(PCStackInfo, record->numpcs));
1769 int scope = 0;
1770 for(PcDesc* p = nm->scopes_pcs_begin(); p < nm->scopes_pcs_end(); p++) {
1771 if(p->scope_decode_offset() == DebugInformationRecorder::serialized_null) continue;
1772 void* pc_address = (void*)p->real_pc(nm);
1773 assert(pc_address != NULL, "pc_address must be non-null");
1774 record->pcinfo[scope].pc = pc_address;
1775 numstackframes=0;
1776 for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) {
1777 numstackframes++;
1778 }
1779 assert(numstackframes != 0, "numstackframes must be nonzero.");
1780 record->pcinfo[scope].methods = (jmethodID *)NEW_RESOURCE_ARRAY(jmethodID, numstackframes);
1781 record->pcinfo[scope].bcis = (jint *)NEW_RESOURCE_ARRAY(jint, numstackframes);
1782 record->pcinfo[scope].numstackframes = numstackframes;
1783 int stackframe = 0;
1784 for(ScopeDesc* sd = nm->scope_desc_at(p->real_pc(nm));sd != NULL;sd = sd->sender()) {
1785 // sd->method() can be NULL for stubs but not for nmethods. To be completely robust, include an assert that we should never see a null sd->method()
1786 assert(!sd->method().is_null(), "sd->method() cannot be null.");
1787 record->pcinfo[scope].methods[stackframe] = sd->method()->jmethod_id();
1788 record->pcinfo[scope].bcis[stackframe] = sd->bci();
1789 stackframe++;
1790 }
1791 scope++;
1792 }
1793 return record;
1794 }
1795
1796 void JvmtiExport::post_compiled_method_load(nmethod *nm) {
1797 // If there are pending CompiledMethodUnload events then these are
1798 // posted before this CompiledMethodLoad event. We "lock" the nmethod and
1799 // maintain a handle to the methodOop to ensure that the nmethod isn't
1800 // flushed or unloaded while posting the events.
1801 JavaThread* thread = JavaThread::current();
1802 if (have_pending_compiled_method_unload_events()) {
1803 methodHandle mh(thread, nm->method());
1804 nmethodLocker nml(nm);
1805 post_pending_compiled_method_unload_events();
1806 }
1807
1808 EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
1809 ("JVMTI [%s] method compile load event triggered",
1810 JvmtiTrace::safe_get_thread_name(thread)));
1811
1812 JvmtiEnvIterator it;
1813 for (JvmtiEnv* env = it.first(); env != NULL; env = it.next(env)) {
1814 if (env->is_enabled(JVMTI_EVENT_COMPILED_METHOD_LOAD)) {
1815
1816 EVT_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
1817 ("JVMTI [%s] class compile method load event sent %s.%s ",
1818 JvmtiTrace::safe_get_thread_name(thread),
1819 (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(),
1820 (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string()));
1821
1822 ResourceMark rm(thread);
1823
1824 // Add inlining information
1825 jvmtiCompiledMethodLoadInlineRecord* inlinerecord = create_inline_record(nm);
1826 // Pass inlining information through the void pointer
1827 JvmtiCompiledMethodLoadEventMark jem(thread, nm, inlinerecord);
1828 JvmtiJavaThreadEventTransition jet(thread);
1829 jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad;
1830 if (callback != NULL) {
1831 (*callback)(env->jvmti_external(), jem.jni_methodID(),
1832 jem.code_size(), jem.code_data(), jem.map_length(),
1833 jem.map(), jem.compile_info());
1834 }
1835 }
1836 }
1837 }
1838
1839
1840 // post a COMPILED_METHOD_LOAD event for a given environment
1841 void JvmtiExport::post_compiled_method_load(JvmtiEnv* env, const jmethodID method, const jint length,
1842 const void *code_begin, const jint map_length,
1843 const jvmtiAddrLocationMap* map)
1844 {
1845 JavaThread* thread = JavaThread::current();
1846 EVT_TRIG_TRACE(JVMTI_EVENT_COMPILED_METHOD_LOAD,
1847 ("JVMTI [%s] method compile load event triggered (by GenerateEvents)",
|