diff --git a/src/share/vm/asm/codeBuffer.cpp b/src/share/vm/asm/codeBuffer.cpp index 64994a9f4fc78bfb089a6467d64189c957c7122c..bb1ae18fcb57af6596b50801d1ab688594c3eb65 100644 --- a/src/share/vm/asm/codeBuffer.cpp +++ b/src/share/vm/asm/codeBuffer.cpp @@ -1026,25 +1026,30 @@ class CodeComment: public CHeapObj { } return a; } + + // Convenience for add_comment. + CodeComment* find_last(intptr_t offset) { + CodeComment* a = find(offset); + if (a != NULL) { + while ((a->_next != NULL) && (a->_next->_offset == offset)) { + a = a->_next; + } + } + return a; + } }; void CodeComments::add_comment(intptr_t offset, const char * comment) { - CodeComment* c = new CodeComment(offset, comment); - CodeComment* insert = NULL; - if (_comments != NULL) { - CodeComment* c = _comments->find(offset); - insert = c; - while (c && c->offset() == offset) { - insert = c; - c = c->next(); - } - } - if (insert) { - // insert after comments with same offset - c->set_next(insert->next()); - insert->set_next(c); + CodeComment* c = new CodeComment(offset, comment); + CodeComment* inspos = (_comments == NULL) ? NULL : _comments->find_last(offset); + + if (inspos) { + // insert after already existing comments with same offset + c->set_next(inspos->next()); + inspos->set_next(c); } else { + // no comments with such offset, yet. Insert before anything else. c->set_next(_comments); _comments = c; } @@ -1052,12 +1057,11 @@ void CodeComments::add_comment(intptr_t offset, const char * comment) { void CodeComments::assign(CodeComments& other) { - assert(_comments == NULL, "don't overwrite old value"); _comments = other._comments; } -void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) { +void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) const { if (_comments != NULL) { CodeComment* c = _comments->find(offset); while (c && c->offset() == offset) { @@ -1085,6 +1089,7 @@ void CodeComments::free() { void CodeBuffer::decode() { + ttyLocker ttyl; Disassembler::decode(decode_begin(), insts_end()); _decode_begin = insts_end(); } @@ -1096,6 +1101,7 @@ void CodeBuffer::skip_decode() { void CodeBuffer::decode_all() { + ttyLocker ttyl; for (int n = 0; n < (int)SECT_LIMIT; n++) { // dump contents of each section CodeSection* cs = code_section(n); diff --git a/src/share/vm/asm/codeBuffer.hpp b/src/share/vm/asm/codeBuffer.hpp index 0e01a9fbf82bdf2b0092016774d1f26ac21a2a52..63dba2dbb0dcbea9abe567f0a295dd5a3aaf025e 100644 --- a/src/share/vm/asm/codeBuffer.hpp +++ b/src/share/vm/asm/codeBuffer.hpp @@ -253,7 +253,7 @@ public: } void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; - void print_block_comment(outputStream* stream, intptr_t offset) PRODUCT_RETURN; + void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN; void assign(CodeComments& other) PRODUCT_RETURN; void free() PRODUCT_RETURN; }; diff --git a/src/share/vm/code/codeBlob.cpp b/src/share/vm/code/codeBlob.cpp index 425ad7f317c40f7364929f7ccbcd92d66af0dddc..779235f25fe5eee979b029d37770b1c7d7bfd4f6 100644 --- a/src/share/vm/code/codeBlob.cpp +++ b/src/share/vm/code/codeBlob.cpp @@ -162,8 +162,10 @@ void CodeBlob::trace_new_stub(CodeBlob* stub, const char* name1, const char* nam assert(strlen(name1) + strlen(name2) < sizeof(stub_id), ""); jio_snprintf(stub_id, sizeof(stub_id), "%s%s", name1, name2); if (PrintStubCode) { + ttyLocker ttyl; tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, (intptr_t) stub); Disassembler::decode(stub->code_begin(), stub->code_end()); + tty->cr(); } Forte::register_stub(stub_id, stub->code_begin(), stub->code_end()); @@ -548,6 +550,7 @@ void RuntimeStub::verify() { } void RuntimeStub::print_on(outputStream* st) const { + ttyLocker ttyl; CodeBlob::print_on(st); st->print("Runtime Stub (" INTPTR_FORMAT "): ", this); st->print_cr(name()); @@ -563,6 +566,7 @@ void SingletonBlob::verify() { } void SingletonBlob::print_on(outputStream* st) const { + ttyLocker ttyl; CodeBlob::print_on(st); st->print_cr(name()); Disassembler::decode((CodeBlob*)this, st); diff --git a/src/share/vm/code/codeBlob.hpp b/src/share/vm/code/codeBlob.hpp index a8b73ae76019d2246480ab821edc007b7b8b1f61..1d47bd9729ca260b9e97ff7363a4464a4e0b03f0 100644 --- a/src/share/vm/code/codeBlob.hpp +++ b/src/share/vm/code/codeBlob.hpp @@ -184,7 +184,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC { static void trace_new_stub(CodeBlob* blob, const char* name1, const char* name2 = ""); // Print the comment associated with offset on stream, if there is one - virtual void print_block_comment(outputStream* stream, address block_begin) { + virtual void print_block_comment(outputStream* stream, address block_begin) const { intptr_t offset = (intptr_t)(block_begin - code_begin()); _comments.print_block_comment(stream, offset); } diff --git a/src/share/vm/code/icBuffer.hpp b/src/share/vm/code/icBuffer.hpp index 340dbb893e88a477210eed51aea39bd411cd19bd..36d0c761666a2dc8f7d7c6dc866966b0eef33b36 100644 --- a/src/share/vm/code/icBuffer.hpp +++ b/src/share/vm/code/icBuffer.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_VM_CODE_ICBUFFER_HPP #define SHARE_VM_CODE_ICBUFFER_HPP +#include "asm/codeBuffer.hpp" #include "code/stubs.hpp" #include "interpreter/bytecodes.hpp" #include "memory/allocation.hpp" @@ -48,7 +49,8 @@ class ICStub: public Stub { protected: friend class ICStubInterface; // This will be called only by ICStubInterface - void initialize(int size) { _size = size; _ic_site = NULL; } + void initialize(int size, + CodeComments comments) { _size = size; _ic_site = NULL; } void finalize(); // called when a method is removed // General info diff --git a/src/share/vm/code/nmethod.cpp b/src/share/vm/code/nmethod.cpp index ac1b22c692633cd4064b4e2fda1e89650e4dfe09..61cd15037c62f47cc0e559ab33e21a4b3e7ce6e4 100644 --- a/src/share/vm/code/nmethod.cpp +++ b/src/share/vm/code/nmethod.cpp @@ -2672,7 +2672,7 @@ ScopeDesc* nmethod::scope_desc_in(address begin, address end) { return NULL; } -void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) { +void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) const { if (block_begin == entry_point()) stream->print_cr("[Entry Point]"); if (block_begin == verified_entry_point()) stream->print_cr("[Verified Entry Point]"); if (block_begin == exception_begin()) stream->print_cr("[Exception Handler]"); diff --git a/src/share/vm/code/nmethod.hpp b/src/share/vm/code/nmethod.hpp index e7c067c3fa0edc566468442864d9fddefafd09d9..ea39b71e28bcff76f3fb516dea8da99920c2da3b 100644 --- a/src/share/vm/code/nmethod.hpp +++ b/src/share/vm/code/nmethod.hpp @@ -653,11 +653,11 @@ public: void log_state_change() const; // Prints block-level comments, including nmethod specific block labels: - virtual void print_block_comment(outputStream* stream, address block_begin) { + virtual void print_block_comment(outputStream* stream, address block_begin) const { print_nmethod_labels(stream, block_begin); CodeBlob::print_block_comment(stream, block_begin); } - void print_nmethod_labels(outputStream* stream, address block_begin); + void print_nmethod_labels(outputStream* stream, address block_begin) const; // Prints a comment for one native instruction (reloc info, pc desc) void print_code_comment_on(outputStream* st, int column, address begin, address end); diff --git a/src/share/vm/code/stubs.cpp b/src/share/vm/code/stubs.cpp index 124c0a64068836dd81a7f65b2473f3bc0127c044..0d5e61c8e0318e0d8b6fcaac69922ed75bb8bbd6 100644 --- a/src/share/vm/code/stubs.cpp +++ b/src/share/vm/code/stubs.cpp @@ -101,7 +101,8 @@ Stub* StubQueue::stub_containing(address pc) const { Stub* StubQueue::request_committed(int code_size) { Stub* s = request(code_size); - if (s != NULL) commit(code_size); + CodeComments comments; + if (s != NULL) commit(code_size, comments); return s; } @@ -118,7 +119,8 @@ Stub* StubQueue::request(int requested_code_size) { assert(_buffer_limit == _buffer_size, "buffer must be fully usable"); if (_queue_end + requested_size <= _buffer_size) { // code fits in at the end => nothing to do - stub_initialize(s, requested_size); + CodeComments comments; + stub_initialize(s, requested_size, comments); return s; } else { // stub doesn't fit in at the queue end @@ -135,7 +137,8 @@ Stub* StubQueue::request(int requested_code_size) { // Queue: |XXX|.......|XXXXXXX|.......| // ^0 ^end ^begin ^limit ^size s = current_stub(); - stub_initialize(s, requested_size); + CodeComments comments; + stub_initialize(s, requested_size, comments); return s; } // Not enough space left @@ -144,12 +147,12 @@ Stub* StubQueue::request(int requested_code_size) { } -void StubQueue::commit(int committed_code_size) { +void StubQueue::commit(int committed_code_size, CodeComments& comments) { assert(committed_code_size > 0, "committed_code_size must be > 0"); int committed_size = round_to(stub_code_size_to_size(committed_code_size), CodeEntryAlignment); Stub* s = current_stub(); assert(committed_size <= stub_size(s), "committed size must not exceed requested size"); - stub_initialize(s, committed_size); + stub_initialize(s, committed_size, comments); _queue_end += committed_size; _number_of_stubs++; if (_mutex != NULL) _mutex->unlock(); diff --git a/src/share/vm/code/stubs.hpp b/src/share/vm/code/stubs.hpp index afc8f04d46c7852d07979f717ae6dc842d64412f..5701a45a57154d55ecf4c3a6c8b7d2de232cf4c0 100644 --- a/src/share/vm/code/stubs.hpp +++ b/src/share/vm/code/stubs.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_VM_CODE_STUBS_HPP #define SHARE_VM_CODE_STUBS_HPP +#include "asm/codeBuffer.hpp" #include "memory/allocation.hpp" #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" @@ -71,7 +72,8 @@ class Stub VALUE_OBJ_CLASS_SPEC { public: // Initialization/finalization - void initialize(int size) { ShouldNotCallThis(); } // called to initialize/specify the stub's size + void initialize(int size, + CodeComments& comments) { ShouldNotCallThis(); } // called to initialize/specify the stub's size void finalize() { ShouldNotCallThis(); } // called before the stub is deallocated // General info/converters @@ -104,7 +106,8 @@ class Stub VALUE_OBJ_CLASS_SPEC { class StubInterface: public CHeapObj { public: // Initialization/finalization - virtual void initialize(Stub* self, int size) = 0; // called after creation (called twice if allocated via (request, commit)) + virtual void initialize(Stub* self, int size, + CodeComments& comments) = 0; // called after creation (called twice if allocated via (request, commit)) virtual void finalize(Stub* self) = 0; // called before deallocation // General info/converters @@ -132,7 +135,8 @@ class StubInterface: public CHeapObj { \ public: \ /* Initialization/finalization */ \ - virtual void initialize(Stub* self, int size) { cast(self)->initialize(size); } \ + virtual void initialize(Stub* self, int size, \ + CodeComments& comments) { cast(self)->initialize(size, comments); } \ virtual void finalize(Stub* self) { cast(self)->finalize(); } \ \ /* General info */ \ @@ -171,7 +175,8 @@ class StubQueue: public CHeapObj { Stub* current_stub() const { return stub_at(_queue_end); } // Stub functionality accessed via interface - void stub_initialize(Stub* s, int size) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size); } + void stub_initialize(Stub* s, int size, + CodeComments& comments) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, comments); } void stub_finalize(Stub* s) { _stub_interface->finalize(s); } int stub_size(Stub* s) const { return _stub_interface->size(s); } bool stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); } @@ -200,7 +205,8 @@ class StubQueue: public CHeapObj { // Stub allocation (atomic transactions) Stub* request_committed(int code_size); // request a stub that provides exactly code_size space for code Stub* request(int requested_code_size); // request a stub with a (maximum) code space - locks the queue - void commit (int committed_code_size); // commit the previously requested stub - unlocks the queue + void commit (int committed_code_size, + CodeComments& comments); // commit the previously requested stub - unlocks the queue // Stub deallocation void remove_first(); // remove the first stub in the queue diff --git a/src/share/vm/compiler/disassembler.cpp b/src/share/vm/compiler/disassembler.cpp index 9603e863eddc61f733042dde11dc0e52d187f173..3be1533a050bf1b3885c28606f92ceac16b5fa57 100644 --- a/src/share/vm/compiler/disassembler.cpp +++ b/src/share/vm/compiler/disassembler.cpp @@ -148,6 +148,7 @@ class decode_env { private: nmethod* _nm; CodeBlob* _code; + CodeComments _comments; outputStream* _output; address _start, _end; @@ -187,7 +188,7 @@ class decode_env { void print_address(address value); public: - decode_env(CodeBlob* code, outputStream* output); + decode_env(CodeBlob* code, outputStream* output, CodeComments c = CodeComments()); address decode_instructions(address start, address end); @@ -229,12 +230,13 @@ class decode_env { const char* options() { return _option_buf; } }; -decode_env::decode_env(CodeBlob* code, outputStream* output) { +decode_env::decode_env(CodeBlob* code, outputStream* output, CodeComments c) { memset(this, 0, sizeof(*this)); _output = output ? output : tty; _code = code; if (code != NULL && code->is_nmethod()) _nm = (nmethod*) code; + _comments.assign(c); // by default, output pc but not bytes: _print_pc = true; @@ -356,6 +358,7 @@ void decode_env::print_insn_labels() { if (cb != NULL) { cb->print_block_comment(st, p); } + _comments.print_block_comment(st, (intptr_t)(p - _start)); if (_print_pc) { st->print(" " PTR_FORMAT ": ", p); } @@ -467,10 +470,9 @@ void Disassembler::decode(CodeBlob* cb, outputStream* st) { env.decode_instructions(cb->code_begin(), cb->code_end()); } - -void Disassembler::decode(address start, address end, outputStream* st) { +void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) { if (!load_library()) return; - decode_env env(CodeCache::find_blob_unsafe(start), st); + decode_env env(CodeCache::find_blob_unsafe(start), st, c); env.decode_instructions(start, end); } diff --git a/src/share/vm/compiler/disassembler.hpp b/src/share/vm/compiler/disassembler.hpp index a70b8ccd378da6f90611348dc3fd77e77663b546..0d05514a88a15297879a8a332461a49f8d51222a 100644 --- a/src/share/vm/compiler/disassembler.hpp +++ b/src/share/vm/compiler/disassembler.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_VM_COMPILER_DISASSEMBLER_HPP #define SHARE_VM_COMPILER_DISASSEMBLER_HPP +#include "asm/codeBuffer.hpp" #include "runtime/globals.hpp" #ifdef TARGET_OS_FAMILY_linux # include "os_linux.inline.hpp" @@ -87,7 +88,7 @@ class Disassembler { } static void decode(CodeBlob *cb, outputStream* st = NULL); static void decode(nmethod* nm, outputStream* st = NULL); - static void decode(address begin, address end, outputStream* st = NULL); + static void decode(address begin, address end, outputStream* st = NULL, CodeComments c = CodeComments()); }; #endif // SHARE_VM_COMPILER_DISASSEMBLER_HPP diff --git a/src/share/vm/interpreter/interpreter.cpp b/src/share/vm/interpreter/interpreter.cpp index 9e329ebf851ae67a8921a09dd0b113b43aa63943..dad8f9ec7519e343e2fe00082b68ac60ed5f6401 100644 --- a/src/share/vm/interpreter/interpreter.cpp +++ b/src/share/vm/interpreter/interpreter.cpp @@ -60,6 +60,8 @@ void InterpreterCodelet::verify() { void InterpreterCodelet::print_on(outputStream* st) const { + ttyLocker ttyl; + if (PrintInterpreter) { st->cr(); st->print_cr("----------------------------------------------------------------------"); @@ -72,7 +74,7 @@ void InterpreterCodelet::print_on(outputStream* st) const { if (PrintInterpreter) { st->cr(); - Disassembler::decode(code_begin(), code_end(), st); + Disassembler::decode(code_begin(), code_end(), st, DEBUG_ONLY(_comments) NOT_DEBUG(CodeComments())); } } diff --git a/src/share/vm/interpreter/interpreter.hpp b/src/share/vm/interpreter/interpreter.hpp index 0ab0be74770028ab1ef32b6f5c2806f3b99e2a2f..478edb1b3156ae4f936d4e6b37e668615a12661d 100644 --- a/src/share/vm/interpreter/interpreter.hpp +++ b/src/share/vm/interpreter/interpreter.hpp @@ -48,10 +48,12 @@ class InterpreterCodelet: public Stub { int _size; // the size in bytes const char* _description; // a description of the codelet, for debugging & printing Bytecodes::Code _bytecode; // associated bytecode if any + DEBUG_ONLY(CodeComments _comments;) // Comments for annotating assembler output. public: // Initialization/finalization - void initialize(int size) { _size = size; } + void initialize(int size, + CodeComments& comments) { _size = size; DEBUG_ONLY(_comments.assign(comments);) } void finalize() { ShouldNotCallThis(); } // General info/converters @@ -129,7 +131,7 @@ class CodeletMark: ResourceMark { // commit Codelet - AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size()); + AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size(), (*_masm)->code()->comments()); // make sure nobody can use _masm outside a CodeletMark lifespan *_masm = NULL; } diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp index f5a038e2870d031957c77202529d2301ea47315e..a0ef0abc2f9320fe7dc8757663abe89f9aed2f30 100644 --- a/src/share/vm/runtime/sharedRuntime.cpp +++ b/src/share/vm/runtime/sharedRuntime.cpp @@ -2460,6 +2460,7 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) { #ifndef PRODUCT // debugging suppport if (PrintAdapterHandlers || PrintStubCode) { + ttyLocker ttyl; entry->print_adapter_on(tty); tty->print_cr("i2c argument handler #%d for: %s %s (%d bytes generated)", _adapters->number_of_entries(), (method->is_static() ? "static" : "receiver"), @@ -2467,8 +2468,10 @@ AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) { tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry()); if (Verbose || PrintStubCode) { address first_pc = entry->base_address(); - if (first_pc != NULL) + if (first_pc != NULL) { Disassembler::decode(first_pc, first_pc + insts_size); + tty->cr(); + } } } #endif