提交 a8131d7e 编写于 作者: K kvn

7200163: add CodeComments functionality to assember stubs

Summary: Pass the codeBuffer to the Stub constructor, and adapts the disassembler to print the comments.
Reviewed-by: jrose, kvn, twisti
Contributed-by: goetz.lindenmaier@sap.com
上级 e7f0e6f3
......@@ -1026,25 +1026,30 @@ class CodeComment: public CHeapObj<mtCode> {
}
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);
......
......@@ -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;
};
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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
......
......@@ -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]");
......
......@@ -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);
......
......@@ -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();
......
......@@ -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<mtCode> {
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<mtCode> {
\
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<mtCode> {
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<mtCode> {
// 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
......
......@@ -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);
}
......
......@@ -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
......@@ -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()));
}
}
......
......@@ -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;
}
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册