1 /* |
1 /* |
2 * Copyright 2003-2009 Sun Microsystems, Inc. All Rights Reserved. |
2 * Copyright 2003-2010 Sun Microsystems, Inc. All Rights Reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
684 const void *_code_data; |
684 const void *_code_data; |
685 jint _map_length; |
685 jint _map_length; |
686 jvmtiAddrLocationMap *_map; |
686 jvmtiAddrLocationMap *_map; |
687 const void *_compile_info; |
687 const void *_compile_info; |
688 public: |
688 public: |
689 JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm) |
689 JvmtiCompiledMethodLoadEventMark(JavaThread *thread, nmethod *nm, void* compile_info_ptr = NULL) |
690 : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) { |
690 : JvmtiMethodEventMark(thread,methodHandle(thread, nm->method())) { |
691 _code_data = nm->code_begin(); |
691 _code_data = nm->code_begin(); |
692 _code_size = nm->code_size(); |
692 _code_size = nm->code_size(); |
693 _compile_info = NULL; /* no info for our VM. */ |
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); |
694 JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length); |
695 } |
695 } |
696 ~JvmtiCompiledMethodLoadEventMark() { |
696 ~JvmtiCompiledMethodLoadEventMark() { |
697 FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map); |
697 FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map); |
698 } |
698 } |
1750 } |
1750 } |
1751 } |
1751 } |
1752 } |
1752 } |
1753 } |
1753 } |
1754 |
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 } |
1755 |
1795 |
1756 void JvmtiExport::post_compiled_method_load(nmethod *nm) { |
1796 void JvmtiExport::post_compiled_method_load(nmethod *nm) { |
1757 // If there are pending CompiledMethodUnload events then these are |
1797 // If there are pending CompiledMethodUnload events then these are |
1758 // posted before this CompiledMethodLoad event. We "lock" the nmethod and |
1798 // posted before this CompiledMethodLoad event. We "lock" the nmethod and |
1759 // maintain a handle to the methodOop to ensure that the nmethod isn't |
1799 // maintain a handle to the methodOop to ensure that the nmethod isn't |
1778 JvmtiTrace::safe_get_thread_name(thread), |
1818 JvmtiTrace::safe_get_thread_name(thread), |
1779 (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(), |
1819 (nm->method() == NULL) ? "NULL" : nm->method()->klass_name()->as_C_string(), |
1780 (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string())); |
1820 (nm->method() == NULL) ? "NULL" : nm->method()->name()->as_C_string())); |
1781 |
1821 |
1782 ResourceMark rm(thread); |
1822 ResourceMark rm(thread); |
1783 JvmtiCompiledMethodLoadEventMark jem(thread, nm); |
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); |
1784 JvmtiJavaThreadEventTransition jet(thread); |
1828 JvmtiJavaThreadEventTransition jet(thread); |
1785 jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad; |
1829 jvmtiEventCompiledMethodLoad callback = env->callbacks()->CompiledMethodLoad; |
1786 if (callback != NULL) { |
1830 if (callback != NULL) { |
1787 (*callback)(env->jvmti_external(), jem.jni_methodID(), |
1831 (*callback)(env->jvmti_external(), jem.jni_methodID(), |
1788 jem.code_size(), jem.code_data(), jem.map_length(), |
1832 jem.code_size(), jem.code_data(), jem.map_length(), |