Thu, 06 Feb 2014 20:13:38 -0800
8025841: JVMTI: "vtable stub" dynamic code notification is misplaced
Summary: Generate correct "vtable stub" dynamic code notifications
Reviewed-by: sspitsyn, kvn, coleenp
Contributed-by: oleg.mazurov@oracle.com
1.1 --- a/src/share/vm/code/vtableStubs.cpp Thu Jan 16 10:51:16 2014 -0800 1.2 +++ b/src/share/vm/code/vtableStubs.cpp Thu Feb 06 20:13:38 2014 -0800 1.3 @@ -55,6 +55,9 @@ 1.4 const int chunk_factor = 32; 1.5 if (_chunk == NULL || _chunk + real_size > _chunk_end) { 1.6 const int bytes = chunk_factor * real_size + pd_code_alignment(); 1.7 + 1.8 + // There is a dependency on the name of the blob in src/share/vm/prims/jvmtiCodeBlobEvents.cpp 1.9 + // If changing the name, update the other file accordingly. 1.10 BufferBlob* blob = BufferBlob::create("vtable chunks", bytes); 1.11 if (blob == NULL) { 1.12 return NULL; 1.13 @@ -62,12 +65,6 @@ 1.14 _chunk = blob->content_begin(); 1.15 _chunk_end = _chunk + bytes; 1.16 Forte::register_stub("vtable stub", _chunk, _chunk_end); 1.17 - // Notify JVMTI about this stub. The event will be recorded by the enclosing 1.18 - // JvmtiDynamicCodeEventCollector and posted when this thread has released 1.19 - // all locks. 1.20 - if (JvmtiExport::should_post_dynamic_code_generated()) { 1.21 - JvmtiExport::post_dynamic_code_generated_while_holding_locks("vtable stub", _chunk, _chunk_end); 1.22 - } 1.23 align_chunk(); 1.24 } 1.25 assert(_chunk + real_size <= _chunk_end, "bad allocation"); 1.26 @@ -130,6 +127,13 @@ 1.27 is_vtable_stub? "vtbl": "itbl", vtable_index, VtableStub::receiver_location()); 1.28 Disassembler::decode(s->code_begin(), s->code_end()); 1.29 } 1.30 + // Notify JVMTI about this stub. The event will be recorded by the enclosing 1.31 + // JvmtiDynamicCodeEventCollector and posted when this thread has released 1.32 + // all locks. 1.33 + if (JvmtiExport::should_post_dynamic_code_generated()) { 1.34 + JvmtiExport::post_dynamic_code_generated_while_holding_locks(is_vtable_stub? "vtable stub": "itable stub", 1.35 + s->code_begin(), s->code_end()); 1.36 + } 1.37 } 1.38 return s->entry_point(); 1.39 } 1.40 @@ -195,6 +199,14 @@ 1.41 VtableStubs::initialize(); 1.42 } 1.43 1.44 +void VtableStubs::vtable_stub_do(void f(VtableStub*)) { 1.45 + for (int i = 0; i < N; i++) { 1.46 + for (VtableStub* s = _table[i]; s != NULL; s = s->next()) { 1.47 + f(s); 1.48 + } 1.49 + } 1.50 +} 1.51 + 1.52 1.53 //----------------------------------------------------------------------------------------------------- 1.54 // Non-product code
2.1 --- a/src/share/vm/code/vtableStubs.hpp Thu Jan 16 10:51:16 2014 -0800 2.2 +++ b/src/share/vm/code/vtableStubs.hpp Thu Feb 06 20:13:38 2014 -0800 2.3 @@ -131,6 +131,7 @@ 2.4 static VtableStub* stub_containing(address pc); // stub containing pc or NULL 2.5 static int number_of_vtable_stubs() { return _number_of_vtable_stubs; } 2.6 static void initialize(); 2.7 + static void vtable_stub_do(void f(VtableStub*)); // iterates over all vtable stubs 2.8 }; 2.9 2.10 #endif // SHARE_VM_CODE_VTABLESTUBS_HPP
3.1 --- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Thu Jan 16 10:51:16 2014 -0800 3.2 +++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp Thu Feb 06 20:13:38 2014 -0800 3.3 @@ -26,6 +26,7 @@ 3.4 #include "code/codeBlob.hpp" 3.5 #include "code/codeCache.hpp" 3.6 #include "code/scopeDesc.hpp" 3.7 +#include "code/vtableStubs.hpp" 3.8 #include "memory/resourceArea.hpp" 3.9 #include "oops/oop.inline.hpp" 3.10 #include "prims/jvmtiCodeBlobEvents.hpp" 3.11 @@ -63,6 +64,7 @@ 3.12 // used during a collection 3.13 static GrowableArray<JvmtiCodeBlobDesc*>* _global_code_blobs; 3.14 static void do_blob(CodeBlob* cb); 3.15 + static void do_vtable_stub(VtableStub* vs); 3.16 public: 3.17 CodeBlobCollector() { 3.18 _code_blobs = NULL; 3.19 @@ -119,6 +121,10 @@ 3.20 if (cb->is_nmethod()) { 3.21 return; 3.22 } 3.23 + // exclude VtableStubs, which are processed separately 3.24 + if (cb->is_buffer_blob() && strcmp(cb->name(), "vtable chunks") == 0) { 3.25 + return; 3.26 + } 3.27 3.28 // check if this starting address has been seen already - the 3.29 // assumption is that stubs are inserted into the list before the 3.30 @@ -136,6 +142,13 @@ 3.31 _global_code_blobs->append(scb); 3.32 } 3.33 3.34 +// called for each VtableStub in VtableStubs 3.35 + 3.36 +void CodeBlobCollector::do_vtable_stub(VtableStub* vs) { 3.37 + JvmtiCodeBlobDesc* scb = new JvmtiCodeBlobDesc(vs->is_vtable_stub() ? "vtable stub" : "itable stub", 3.38 + vs->code_begin(), vs->code_end()); 3.39 + _global_code_blobs->append(scb); 3.40 +} 3.41 3.42 // collects a list of CodeBlobs in the CodeCache. 3.43 // 3.44 @@ -166,6 +179,10 @@ 3.45 _global_code_blobs->append(new JvmtiCodeBlobDesc(desc->name(), desc->begin(), desc->end())); 3.46 } 3.47 3.48 + // Vtable stubs are not described with StubCodeDesc, 3.49 + // process them separately 3.50 + VtableStubs::vtable_stub_do(do_vtable_stub); 3.51 + 3.52 // next iterate over all the non-nmethod code blobs and add them to 3.53 // the list - as noted above this will filter out duplicates and 3.54 // enclosing blobs.