mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 14:24:46 +02:00
8255208: CodeStrings passed to Disassembler::decode are ignored
Reviewed-by: kvn, iklam
This commit is contained in:
parent
8e5dff08fa
commit
c1524c59ad
11 changed files with 118 additions and 204 deletions
|
@ -140,7 +140,7 @@ CodeBuffer::~CodeBuffer() {
|
||||||
|
|
||||||
// Claim is that stack allocation ensures resources are cleaned up.
|
// Claim is that stack allocation ensures resources are cleaned up.
|
||||||
// This is resource clean up, let's hope that all were properly copied out.
|
// This is resource clean up, let's hope that all were properly copied out.
|
||||||
free_strings();
|
NOT_PRODUCT(free_strings();)
|
||||||
|
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
// Save allocation type to execute assert in ~ResourceObj()
|
// Save allocation type to execute assert in ~ResourceObj()
|
||||||
|
@ -267,13 +267,14 @@ bool CodeBuffer::is_backward_branch(Label& L) {
|
||||||
return L.is_bound() && insts_end() <= locator_address(L.loc());
|
return L.is_bound() && insts_end() <= locator_address(L.loc());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
address CodeBuffer::decode_begin() {
|
address CodeBuffer::decode_begin() {
|
||||||
address begin = _insts.start();
|
address begin = _insts.start();
|
||||||
if (_decode_begin != NULL && _decode_begin > begin)
|
if (_decode_begin != NULL && _decode_begin > begin)
|
||||||
begin = _decode_begin;
|
begin = _decode_begin;
|
||||||
return begin;
|
return begin;
|
||||||
}
|
}
|
||||||
|
#endif // !PRODUCT
|
||||||
|
|
||||||
GrowableArray<int>* CodeBuffer::create_patch_overflow() {
|
GrowableArray<int>* CodeBuffer::create_patch_overflow() {
|
||||||
if (_overflow_arena == NULL) {
|
if (_overflow_arena == NULL) {
|
||||||
|
@ -752,7 +753,7 @@ void CodeBuffer::copy_code_to(CodeBlob* dest_blob) {
|
||||||
relocate_code_to(&dest);
|
relocate_code_to(&dest);
|
||||||
|
|
||||||
// transfer strings and comments from buffer to blob
|
// transfer strings and comments from buffer to blob
|
||||||
dest_blob->set_strings(_code_strings);
|
NOT_PRODUCT(dest_blob->set_strings(_code_strings);)
|
||||||
|
|
||||||
// Done moving code bytes; were they the right size?
|
// Done moving code bytes; were they the right size?
|
||||||
assert((int)align_up(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity");
|
assert((int)align_up(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity");
|
||||||
|
@ -957,12 +958,11 @@ void CodeBuffer::expand(CodeSection* which_cs, csize_t amount) {
|
||||||
debug_only(Copy::fill_to_bytes(bxp->_total_start, bxp->_total_size,
|
debug_only(Copy::fill_to_bytes(bxp->_total_start, bxp->_total_size,
|
||||||
badCodeHeapFreeVal));
|
badCodeHeapFreeVal));
|
||||||
|
|
||||||
_decode_begin = NULL; // sanity
|
|
||||||
|
|
||||||
// Make certain that the new sections are all snugly inside the new blob.
|
// Make certain that the new sections are all snugly inside the new blob.
|
||||||
verify_section_allocation();
|
verify_section_allocation();
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
_decode_begin = NULL; // sanity
|
||||||
if (PrintNMethods && (WizardMode || Verbose)) {
|
if (PrintNMethods && (WizardMode || Verbose)) {
|
||||||
tty->print("expanded CodeBuffer:");
|
tty->print("expanded CodeBuffer:");
|
||||||
this->print();
|
this->print();
|
||||||
|
@ -1032,10 +1032,6 @@ void CodeBuffer::log_section_sizes(const char* name) {
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
|
||||||
void CodeSection::decode() {
|
|
||||||
Disassembler::decode(start(), end());
|
|
||||||
}
|
|
||||||
|
|
||||||
void CodeBuffer::block_comment(intptr_t offset, const char * comment) {
|
void CodeBuffer::block_comment(intptr_t offset, const char * comment) {
|
||||||
if (_collect_comments) {
|
if (_collect_comments) {
|
||||||
_code_strings.add_comment(offset, comment);
|
_code_strings.add_comment(offset, comment);
|
||||||
|
@ -1054,8 +1050,12 @@ class CodeString: public CHeapObj<mtCode> {
|
||||||
CodeString* _prev;
|
CodeString* _prev;
|
||||||
intptr_t _offset;
|
intptr_t _offset;
|
||||||
|
|
||||||
|
static long allocated_code_strings;
|
||||||
|
|
||||||
~CodeString() {
|
~CodeString() {
|
||||||
assert(_next == NULL && _prev == NULL, "wrong interface for freeing list");
|
assert(_next == NULL && _prev == NULL, "wrong interface for freeing list");
|
||||||
|
allocated_code_strings--;
|
||||||
|
log_trace(codestrings)("Freeing CodeString [%s] (%p)", _string, (void*)_string);
|
||||||
os::free((void*)_string);
|
os::free((void*)_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1064,7 +1064,9 @@ class CodeString: public CHeapObj<mtCode> {
|
||||||
public:
|
public:
|
||||||
CodeString(const char * string, intptr_t offset = -1)
|
CodeString(const char * string, intptr_t offset = -1)
|
||||||
: _next(NULL), _prev(NULL), _offset(offset) {
|
: _next(NULL), _prev(NULL), _offset(offset) {
|
||||||
|
allocated_code_strings++;
|
||||||
_string = os::strdup(string, mtCode);
|
_string = os::strdup(string, mtCode);
|
||||||
|
log_trace(codestrings)("Created CodeString [%s] (%p)", _string, (void*)_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * string() const { return _string; }
|
const char * string() const { return _string; }
|
||||||
|
@ -1094,6 +1096,10 @@ class CodeString: public CHeapObj<mtCode> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// For tracing statistics. Will use raw increment/decrement, so it might not be
|
||||||
|
// exact
|
||||||
|
long CodeString::allocated_code_strings = 0;
|
||||||
|
|
||||||
CodeString* CodeStrings::find(intptr_t offset) const {
|
CodeString* CodeStrings::find(intptr_t offset) const {
|
||||||
CodeString* a = _strings->first_comment();
|
CodeString* a = _strings->first_comment();
|
||||||
while (a != NULL && a->offset() != offset) {
|
while (a != NULL && a->offset() != offset) {
|
||||||
|
@ -1116,7 +1122,7 @@ void CodeStrings::add_comment(intptr_t offset, const char * comment) {
|
||||||
CodeString* c = new CodeString(comment, offset);
|
CodeString* c = new CodeString(comment, offset);
|
||||||
CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset);
|
CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset);
|
||||||
|
|
||||||
if (inspos) {
|
if (inspos != NULL) {
|
||||||
// insert after already existing comments with same offset
|
// insert after already existing comments with same offset
|
||||||
c->set_next(inspos->next());
|
c->set_next(inspos->next());
|
||||||
inspos->set_next(c);
|
inspos->set_next(c);
|
||||||
|
@ -1130,21 +1136,10 @@ void CodeStrings::add_comment(intptr_t offset, const char * comment) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeStrings::assign(CodeStrings& other) {
|
|
||||||
other.check_valid();
|
|
||||||
assert(is_null(), "Cannot assign onto non-empty CodeStrings");
|
|
||||||
_strings = other._strings;
|
|
||||||
_strings_last = other._strings_last;
|
|
||||||
#ifdef ASSERT
|
|
||||||
_defunct = false;
|
|
||||||
#endif
|
|
||||||
other.set_null_and_invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deep copy of CodeStrings for consistent memory management.
|
// Deep copy of CodeStrings for consistent memory management.
|
||||||
// Only used for actual disassembly so this is cheaper than reference counting
|
|
||||||
// for the "normal" fastdebug case.
|
|
||||||
void CodeStrings::copy(CodeStrings& other) {
|
void CodeStrings::copy(CodeStrings& other) {
|
||||||
|
log_debug(codestrings)("Copying %d Codestring(s)", other.count());
|
||||||
|
|
||||||
other.check_valid();
|
other.check_valid();
|
||||||
check_valid();
|
check_valid();
|
||||||
assert(is_null(), "Cannot copy onto non-empty CodeStrings");
|
assert(is_null(), "Cannot copy onto non-empty CodeStrings");
|
||||||
|
@ -1152,7 +1147,11 @@ void CodeStrings::copy(CodeStrings& other) {
|
||||||
CodeString** ps = &_strings;
|
CodeString** ps = &_strings;
|
||||||
CodeString* prev = NULL;
|
CodeString* prev = NULL;
|
||||||
while (n != NULL) {
|
while (n != NULL) {
|
||||||
|
if (n->is_comment()) {
|
||||||
*ps = new CodeString(n->string(), n->offset());
|
*ps = new CodeString(n->string(), n->offset());
|
||||||
|
} else {
|
||||||
|
*ps = new CodeString(n->string());
|
||||||
|
}
|
||||||
(*ps)->_prev = prev;
|
(*ps)->_prev = prev;
|
||||||
prev = *ps;
|
prev = *ps;
|
||||||
ps = &((*ps)->_next);
|
ps = &((*ps)->_next);
|
||||||
|
@ -1162,13 +1161,6 @@ void CodeStrings::copy(CodeStrings& other) {
|
||||||
|
|
||||||
const char* CodeStrings::_prefix = " ;; "; // default: can be changed via set_prefix
|
const char* CodeStrings::_prefix = " ;; "; // default: can be changed via set_prefix
|
||||||
|
|
||||||
// Check if any block comments are pending for the given offset.
|
|
||||||
bool CodeStrings::has_block_comment(intptr_t offset) const {
|
|
||||||
if (_strings == NULL) return false;
|
|
||||||
CodeString* c = find(offset);
|
|
||||||
return c != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
|
void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
|
||||||
check_valid();
|
check_valid();
|
||||||
if (_strings != NULL) {
|
if (_strings != NULL) {
|
||||||
|
@ -1184,8 +1176,19 @@ void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) con
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also sets isNull()
|
int CodeStrings::count() const {
|
||||||
|
int i = 0;
|
||||||
|
CodeString* s = _strings;
|
||||||
|
while (s != NULL) {
|
||||||
|
i++;
|
||||||
|
s = s->_next;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Also sets is_null()
|
||||||
void CodeStrings::free() {
|
void CodeStrings::free() {
|
||||||
|
log_debug(codestrings)("Freeing %d out of approx. %ld CodeString(s), ", count(), CodeString::allocated_code_strings);
|
||||||
CodeString* n = _strings;
|
CodeString* n = _strings;
|
||||||
while (n) {
|
while (n) {
|
||||||
// unlink the node from the list saving a pointer to the next
|
// unlink the node from the list saving a pointer to the next
|
||||||
|
@ -1215,7 +1218,7 @@ const char* CodeStrings::add_string(const char * string) {
|
||||||
|
|
||||||
void CodeBuffer::decode() {
|
void CodeBuffer::decode() {
|
||||||
ttyLocker ttyl;
|
ttyLocker ttyl;
|
||||||
Disassembler::decode(decode_begin(), insts_end(), tty);
|
Disassembler::decode(decode_begin(), insts_end(), tty NOT_PRODUCT(COMMA &strings()));
|
||||||
_decode_begin = insts_end();
|
_decode_begin = insts_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,10 +1249,4 @@ void CodeBuffer::print() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directly disassemble code buffer.
|
|
||||||
void CodeBuffer::decode(address start, address end) {
|
|
||||||
ttyLocker ttyl;
|
|
||||||
Disassembler::decode(this, start, end, tty);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PRODUCT
|
#endif // PRODUCT
|
||||||
|
|
|
@ -284,20 +284,18 @@ private:
|
||||||
bool _defunct; // Zero bit pattern is "valid", see memset call in decode_env::decode_env
|
bool _defunct; // Zero bit pattern is "valid", see memset call in decode_env::decode_env
|
||||||
#endif
|
#endif
|
||||||
static const char* _prefix; // defaults to " ;; "
|
static const char* _prefix; // defaults to " ;; "
|
||||||
#endif
|
|
||||||
|
|
||||||
CodeString* find(intptr_t offset) const;
|
CodeString* find(intptr_t offset) const;
|
||||||
CodeString* find_last(intptr_t offset) const;
|
CodeString* find_last(intptr_t offset) const;
|
||||||
|
|
||||||
void set_null_and_invalidate() {
|
void set_null_and_invalidate() {
|
||||||
#ifndef PRODUCT
|
|
||||||
_strings = NULL;
|
_strings = NULL;
|
||||||
_strings_last = NULL;
|
_strings_last = NULL;
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
_defunct = true;
|
_defunct = true;
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CodeStrings() {
|
CodeStrings() {
|
||||||
|
@ -310,6 +308,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
bool is_null() {
|
bool is_null() {
|
||||||
#ifdef ASSERT
|
#ifdef ASSERT
|
||||||
return _strings == NULL;
|
return _strings == NULL;
|
||||||
|
@ -318,30 +317,25 @@ public:
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* add_string(const char * string) PRODUCT_RETURN_(return NULL;);
|
const char* add_string(const char * string);
|
||||||
|
|
||||||
void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
|
void add_comment(intptr_t offset, const char * comment);
|
||||||
bool has_block_comment(intptr_t offset) const;
|
void print_block_comment(outputStream* stream, intptr_t offset) const;
|
||||||
void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN;
|
int count() const;
|
||||||
// MOVE strings from other to this; invalidate other.
|
|
||||||
void assign(CodeStrings& other) PRODUCT_RETURN;
|
|
||||||
// COPY strings from other to this; leave other valid.
|
// COPY strings from other to this; leave other valid.
|
||||||
void copy(CodeStrings& other) PRODUCT_RETURN;
|
void copy(CodeStrings& other);
|
||||||
// FREE strings; invalidate this.
|
// FREE strings; invalidate this.
|
||||||
void free() PRODUCT_RETURN;
|
void free();
|
||||||
|
|
||||||
// Guarantee that _strings are used at most once; assign and free invalidate a buffer.
|
// Guarantee that _strings are used at most once; assign and free invalidate a buffer.
|
||||||
inline void check_valid() const {
|
inline void check_valid() const {
|
||||||
#ifdef ASSERT
|
|
||||||
assert(!_defunct, "Use of invalid CodeStrings");
|
assert(!_defunct, "Use of invalid CodeStrings");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void set_prefix(const char *prefix) {
|
static void set_prefix(const char *prefix) {
|
||||||
#ifndef PRODUCT
|
|
||||||
_prefix = prefix;
|
_prefix = prefix;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif // !PRODUCT
|
||||||
};
|
};
|
||||||
|
|
||||||
// A CodeBuffer describes a memory space into which assembly
|
// A CodeBuffer describes a memory space into which assembly
|
||||||
|
@ -410,8 +404,7 @@ class CodeBuffer: public StackObj {
|
||||||
csize_t _total_size; // size in bytes of combined memory buffer
|
csize_t _total_size; // size in bytes of combined memory buffer
|
||||||
|
|
||||||
OopRecorder* _oop_recorder;
|
OopRecorder* _oop_recorder;
|
||||||
CodeStrings _code_strings;
|
|
||||||
bool _collect_comments; // Indicate if we need to collect block comments at all.
|
|
||||||
OopRecorder _default_oop_recorder; // override with initialize_oop_recorder
|
OopRecorder _default_oop_recorder; // override with initialize_oop_recorder
|
||||||
Arena* _overflow_arena;
|
Arena* _overflow_arena;
|
||||||
|
|
||||||
|
@ -421,8 +414,12 @@ class CodeBuffer: public StackObj {
|
||||||
bool _immutable_PIC;
|
bool _immutable_PIC;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
CodeStrings _code_strings;
|
||||||
|
bool _collect_comments; // Indicate if we need to collect block comments at all.
|
||||||
address _decode_begin; // start address for decode
|
address _decode_begin; // start address for decode
|
||||||
address decode_begin();
|
address decode_begin();
|
||||||
|
#endif
|
||||||
|
|
||||||
void initialize_misc(const char * name) {
|
void initialize_misc(const char * name) {
|
||||||
// all pointers other than code_start/end and those inside the sections
|
// all pointers other than code_start/end and those inside the sections
|
||||||
|
@ -431,14 +428,15 @@ class CodeBuffer: public StackObj {
|
||||||
_before_expand = NULL;
|
_before_expand = NULL;
|
||||||
_blob = NULL;
|
_blob = NULL;
|
||||||
_oop_recorder = NULL;
|
_oop_recorder = NULL;
|
||||||
_decode_begin = NULL;
|
|
||||||
_overflow_arena = NULL;
|
_overflow_arena = NULL;
|
||||||
_code_strings = CodeStrings();
|
|
||||||
_last_insn = NULL;
|
_last_insn = NULL;
|
||||||
#if INCLUDE_AOT
|
#if INCLUDE_AOT
|
||||||
_immutable_PIC = false;
|
_immutable_PIC = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
_decode_begin = NULL;
|
||||||
|
_code_strings = CodeStrings();
|
||||||
// Collect block comments, but restrict collection to cases where a disassembly is output.
|
// Collect block comments, but restrict collection to cases where a disassembly is output.
|
||||||
_collect_comments = ( PrintAssembly
|
_collect_comments = ( PrintAssembly
|
||||||
|| PrintStubCode
|
|| PrintStubCode
|
||||||
|
@ -447,6 +445,7 @@ class CodeBuffer: public StackObj {
|
||||||
|| PrintSignatureHandlers
|
|| PrintSignatureHandlers
|
||||||
|| UnlockDiagnosticVMOptions
|
|| UnlockDiagnosticVMOptions
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void initialize(address code_start, csize_t code_size) {
|
void initialize(address code_start, csize_t code_size) {
|
||||||
|
@ -636,34 +635,26 @@ class CodeBuffer: public StackObj {
|
||||||
void initialize_oop_recorder(OopRecorder* r);
|
void initialize_oop_recorder(OopRecorder* r);
|
||||||
|
|
||||||
OopRecorder* oop_recorder() const { return _oop_recorder; }
|
OopRecorder* oop_recorder() const { return _oop_recorder; }
|
||||||
CodeStrings& strings() { return _code_strings; }
|
|
||||||
|
|
||||||
address last_insn() const { return _last_insn; }
|
address last_insn() const { return _last_insn; }
|
||||||
void set_last_insn(address a) { _last_insn = a; }
|
void set_last_insn(address a) { _last_insn = a; }
|
||||||
void clear_last_insn() { set_last_insn(NULL); }
|
void clear_last_insn() { set_last_insn(NULL); }
|
||||||
|
|
||||||
|
#ifndef PRODUCT
|
||||||
|
CodeStrings& strings() { return _code_strings; }
|
||||||
|
|
||||||
void free_strings() {
|
void free_strings() {
|
||||||
if (!_code_strings.is_null()) {
|
if (!_code_strings.is_null()) {
|
||||||
_code_strings.free(); // sets _strings Null as a side-effect.
|
_code_strings.free(); // sets _strings Null as a side-effect.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directly disassemble code buffer.
|
|
||||||
// Print the comment associated with offset on stream, if there is one.
|
// 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) {
|
||||||
#ifndef PRODUCT
|
|
||||||
intptr_t offset = (intptr_t)(block_begin - _total_start); // I assume total_start is not correct for all code sections.
|
intptr_t offset = (intptr_t)(block_begin - _total_start); // I assume total_start is not correct for all code sections.
|
||||||
_code_strings.print_block_comment(stream, offset);
|
_code_strings.print_block_comment(stream, offset);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
bool has_block_comment(address block_begin) {
|
|
||||||
#ifndef PRODUCT
|
|
||||||
intptr_t offset = (intptr_t)(block_begin - _total_start); // I assume total_start is not correct for all code sections.
|
|
||||||
return _code_strings.has_block_comment(offset);
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
// Code generation
|
// Code generation
|
||||||
void relocate(address at, RelocationHolder const& rspec, int format = 0) {
|
void relocate(address at, RelocationHolder const& rspec, int format = 0) {
|
||||||
|
|
|
@ -87,8 +87,8 @@ CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& la
|
||||||
_relocation_end(layout.relocation_end()),
|
_relocation_end(layout.relocation_end()),
|
||||||
_oop_maps(oop_maps),
|
_oop_maps(oop_maps),
|
||||||
_caller_must_gc_arguments(caller_must_gc_arguments),
|
_caller_must_gc_arguments(caller_must_gc_arguments),
|
||||||
_strings(CodeStrings()),
|
|
||||||
_name(name)
|
_name(name)
|
||||||
|
NOT_PRODUCT(COMMA _strings(CodeStrings()))
|
||||||
{
|
{
|
||||||
assert(is_aligned(layout.size(), oopSize), "unaligned size");
|
assert(is_aligned(layout.size(), oopSize), "unaligned size");
|
||||||
assert(is_aligned(layout.header_size(), oopSize), "unaligned size");
|
assert(is_aligned(layout.header_size(), oopSize), "unaligned size");
|
||||||
|
@ -115,8 +115,8 @@ CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& la
|
||||||
_relocation_begin(layout.relocation_begin()),
|
_relocation_begin(layout.relocation_begin()),
|
||||||
_relocation_end(layout.relocation_end()),
|
_relocation_end(layout.relocation_end()),
|
||||||
_caller_must_gc_arguments(caller_must_gc_arguments),
|
_caller_must_gc_arguments(caller_must_gc_arguments),
|
||||||
_strings(CodeStrings()),
|
|
||||||
_name(name)
|
_name(name)
|
||||||
|
NOT_PRODUCT(COMMA _strings(CodeStrings()))
|
||||||
{
|
{
|
||||||
assert(is_aligned(_size, oopSize), "unaligned size");
|
assert(is_aligned(_size, oopSize), "unaligned size");
|
||||||
assert(is_aligned(_header_size, oopSize), "unaligned size");
|
assert(is_aligned(_header_size, oopSize), "unaligned size");
|
||||||
|
@ -158,7 +158,7 @@ RuntimeBlob::RuntimeBlob(
|
||||||
void CodeBlob::flush() {
|
void CodeBlob::flush() {
|
||||||
FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);
|
FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);
|
||||||
_oop_maps = NULL;
|
_oop_maps = NULL;
|
||||||
_strings.free();
|
NOT_PRODUCT(_strings.free();)
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeBlob::set_oop_maps(OopMapSet* p) {
|
void CodeBlob::set_oop_maps(OopMapSet* p) {
|
||||||
|
|
|
@ -110,10 +110,12 @@ protected:
|
||||||
|
|
||||||
ImmutableOopMapSet* _oop_maps; // OopMap for this CodeBlob
|
ImmutableOopMapSet* _oop_maps; // OopMap for this CodeBlob
|
||||||
bool _caller_must_gc_arguments;
|
bool _caller_must_gc_arguments;
|
||||||
CodeStrings _strings;
|
|
||||||
const char* _name;
|
const char* _name;
|
||||||
S390_ONLY(int _ctable_offset;)
|
S390_ONLY(int _ctable_offset;)
|
||||||
|
|
||||||
|
NOT_PRODUCT(CodeStrings _strings;)
|
||||||
|
|
||||||
CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
|
CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
|
||||||
CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
|
CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments);
|
||||||
|
|
||||||
|
@ -231,29 +233,20 @@ public:
|
||||||
void dump_for_addr(address addr, outputStream* st, bool verbose) const;
|
void dump_for_addr(address addr, outputStream* st, bool verbose) const;
|
||||||
void print_code();
|
void print_code();
|
||||||
|
|
||||||
bool has_block_comment(address block_begin) const {
|
|
||||||
intptr_t offset = (intptr_t)(block_begin - code_begin());
|
|
||||||
return _strings.has_block_comment(offset);
|
|
||||||
}
|
|
||||||
// Print the comment associated with offset on stream, if there is one
|
// Print the comment associated with offset on stream, if there is one
|
||||||
virtual void print_block_comment(outputStream* stream, address block_begin) const {
|
virtual void print_block_comment(outputStream* stream, address block_begin) const {
|
||||||
|
#ifndef PRODUCT
|
||||||
intptr_t offset = (intptr_t)(block_begin - code_begin());
|
intptr_t offset = (intptr_t)(block_begin - code_begin());
|
||||||
_strings.print_block_comment(stream, offset);
|
_strings.print_block_comment(stream, offset);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer ownership of comments to this CodeBlob
|
#ifndef PRODUCT
|
||||||
void set_strings(CodeStrings& strings) {
|
void set_strings(CodeStrings& strings) {
|
||||||
assert(!is_aot(), "invalid on aot");
|
assert(!is_aot(), "invalid on aot");
|
||||||
_strings.assign(strings);
|
_strings.copy(strings);
|
||||||
}
|
|
||||||
|
|
||||||
static ByteSize name_field_offset() {
|
|
||||||
return byte_offset_of(CodeBlob, _name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ByteSize oop_maps_field_offset() {
|
|
||||||
return byte_offset_of(CodeBlob, _oop_maps);
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
class CodeBlobLayout : public StackObj {
|
class CodeBlobLayout : public StackObj {
|
||||||
|
|
|
@ -695,9 +695,7 @@ public:
|
||||||
CodeBlob::print_block_comment(stream, block_begin);
|
CodeBlob::print_block_comment(stream, block_begin);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
bool has_block_comment(address block_begin) {
|
|
||||||
return CodeBlob::has_block_comment(block_begin);
|
|
||||||
}
|
|
||||||
void print_nmethod_labels(outputStream* stream, address block_begin, bool print_section_labels=true) const;
|
void print_nmethod_labels(outputStream* stream, address block_begin, bool print_section_labels=true) const;
|
||||||
const char* nmethod_section_label(address pos) const;
|
const char* nmethod_section_label(address pos) const;
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@ class decode_env {
|
||||||
CodeBuffer* _codeBuffer; // != NULL only when decoding a CodeBuffer
|
CodeBuffer* _codeBuffer; // != NULL only when decoding a CodeBuffer
|
||||||
CodeBlob* _codeBlob; // != NULL only when decoding a CodeBlob
|
CodeBlob* _codeBlob; // != NULL only when decoding a CodeBlob
|
||||||
nmethod* _nm; // != NULL only when decoding a nmethod
|
nmethod* _nm; // != NULL only when decoding a nmethod
|
||||||
CodeStrings _strings;
|
|
||||||
address _start; // != NULL when decoding a range of unknown type
|
address _start; // != NULL when decoding a range of unknown type
|
||||||
address _end; // != NULL when decoding a range of unknown type
|
address _end; // != NULL when decoding a range of unknown type
|
||||||
|
|
||||||
|
@ -77,6 +77,7 @@ class decode_env {
|
||||||
bool _print_help;
|
bool _print_help;
|
||||||
bool _helpPrinted;
|
bool _helpPrinted;
|
||||||
static bool _optionsParsed;
|
static bool _optionsParsed;
|
||||||
|
NOT_PRODUCT(const CodeStrings* _strings;)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
tabspacing = 8
|
tabspacing = 8
|
||||||
|
@ -214,12 +215,11 @@ class decode_env {
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
decode_env(CodeBuffer* code, outputStream* output);
|
decode_env(CodeBlob* code, outputStream* output);
|
||||||
decode_env(CodeBlob* code, outputStream* output, CodeStrings c = CodeStrings() /* , ptrdiff_t offset */);
|
decode_env(nmethod* code, outputStream* output);
|
||||||
decode_env(nmethod* code, outputStream* output, CodeStrings c = CodeStrings());
|
|
||||||
// Constructor for a 'decode_env' to decode an arbitrary
|
// Constructor for a 'decode_env' to decode an arbitrary
|
||||||
// piece of memory, hopefully containing code.
|
// piece of memory, hopefully containing code.
|
||||||
decode_env(address start, address end, outputStream* output);
|
decode_env(address start, address end, outputStream* output, const CodeStrings* strings = NULL);
|
||||||
|
|
||||||
// Add 'original_start' argument which is the the original address
|
// Add 'original_start' argument which is the the original address
|
||||||
// the instructions were located at (if this is not equal to 'start').
|
// the instructions were located at (if this is not equal to 'start').
|
||||||
|
@ -322,34 +322,10 @@ void decode_env::print_hook_comments(address pc, bool newline) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
decode_env::decode_env(CodeBuffer* code, outputStream* output) :
|
decode_env::decode_env(CodeBlob* code, outputStream* output) :
|
||||||
_output(output ? output : tty),
|
_output(output ? output : tty),
|
||||||
_codeBuffer(code),
|
|
||||||
_codeBlob(NULL),
|
|
||||||
_nm(NULL),
|
|
||||||
_strings(),
|
|
||||||
_start(NULL),
|
|
||||||
_end(NULL),
|
|
||||||
_option_buf(),
|
|
||||||
_print_raw(0),
|
|
||||||
_cur_insn(NULL),
|
|
||||||
_bytes_per_line(0),
|
|
||||||
_pre_decode_alignment(0),
|
|
||||||
_post_decode_alignment(0),
|
|
||||||
_print_file_name(false),
|
|
||||||
_print_help(false),
|
|
||||||
_helpPrinted(false) {
|
|
||||||
|
|
||||||
memset(_option_buf, 0, sizeof(_option_buf));
|
|
||||||
process_options(_output);
|
|
||||||
}
|
|
||||||
|
|
||||||
decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) :
|
|
||||||
_output(output ? output : tty),
|
|
||||||
_codeBuffer(NULL),
|
|
||||||
_codeBlob(code),
|
_codeBlob(code),
|
||||||
_nm(_codeBlob != NULL && _codeBlob->is_nmethod() ? (nmethod*) code : NULL),
|
_nm(_codeBlob != NULL && _codeBlob->is_nmethod() ? (nmethod*) code : NULL),
|
||||||
_strings(),
|
|
||||||
_start(NULL),
|
_start(NULL),
|
||||||
_end(NULL),
|
_end(NULL),
|
||||||
_option_buf(),
|
_option_buf(),
|
||||||
|
@ -360,19 +336,18 @@ decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) :
|
||||||
_post_decode_alignment(0),
|
_post_decode_alignment(0),
|
||||||
_print_file_name(false),
|
_print_file_name(false),
|
||||||
_print_help(false),
|
_print_help(false),
|
||||||
_helpPrinted(false) {
|
_helpPrinted(false)
|
||||||
|
NOT_PRODUCT(COMMA _strings(NULL)) {
|
||||||
|
|
||||||
memset(_option_buf, 0, sizeof(_option_buf));
|
memset(_option_buf, 0, sizeof(_option_buf));
|
||||||
_strings.copy(c);
|
|
||||||
process_options(_output);
|
process_options(_output);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
decode_env::decode_env(nmethod* code, outputStream* output, CodeStrings c) :
|
decode_env::decode_env(nmethod* code, outputStream* output) :
|
||||||
_output(output ? output : tty),
|
_output(output ? output : tty),
|
||||||
_codeBuffer(NULL),
|
|
||||||
_codeBlob(NULL),
|
_codeBlob(NULL),
|
||||||
_nm(code),
|
_nm(code),
|
||||||
_strings(),
|
|
||||||
_start(_nm->code_begin()),
|
_start(_nm->code_begin()),
|
||||||
_end(_nm->code_end()),
|
_end(_nm->code_end()),
|
||||||
_option_buf(),
|
_option_buf(),
|
||||||
|
@ -383,21 +358,19 @@ decode_env::decode_env(nmethod* code, outputStream* output, CodeStrings c) :
|
||||||
_post_decode_alignment(0),
|
_post_decode_alignment(0),
|
||||||
_print_file_name(false),
|
_print_file_name(false),
|
||||||
_print_help(false),
|
_print_help(false),
|
||||||
_helpPrinted(false) {
|
_helpPrinted(false)
|
||||||
|
NOT_PRODUCT(COMMA _strings(NULL)) {
|
||||||
|
|
||||||
memset(_option_buf, 0, sizeof(_option_buf));
|
memset(_option_buf, 0, sizeof(_option_buf));
|
||||||
_strings.copy(c);
|
|
||||||
process_options(_output);
|
process_options(_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructor for a 'decode_env' to decode a memory range [start, end)
|
// Constructor for a 'decode_env' to decode a memory range [start, end)
|
||||||
// of unknown origin, assuming it contains code.
|
// of unknown origin, assuming it contains code.
|
||||||
decode_env::decode_env(address start, address end, outputStream* output) :
|
decode_env::decode_env(address start, address end, outputStream* output, const CodeStrings* c) :
|
||||||
_output(output ? output : tty),
|
_output(output ? output : tty),
|
||||||
_codeBuffer(NULL),
|
|
||||||
_codeBlob(NULL),
|
_codeBlob(NULL),
|
||||||
_nm(NULL),
|
_nm(NULL),
|
||||||
_strings(),
|
|
||||||
_start(start),
|
_start(start),
|
||||||
_end(end),
|
_end(end),
|
||||||
_option_buf(),
|
_option_buf(),
|
||||||
|
@ -408,7 +381,8 @@ decode_env::decode_env(address start, address end, outputStream* output) :
|
||||||
_post_decode_alignment(0),
|
_post_decode_alignment(0),
|
||||||
_print_file_name(false),
|
_print_file_name(false),
|
||||||
_print_help(false),
|
_print_help(false),
|
||||||
_helpPrinted(false) {
|
_helpPrinted(false)
|
||||||
|
NOT_PRODUCT(COMMA _strings(c)) {
|
||||||
|
|
||||||
assert(start < end, "Range must have a positive size, [" PTR_FORMAT ".." PTR_FORMAT ").", p2i(start), p2i(end));
|
assert(start < end, "Range must have a positive size, [" PTR_FORMAT ".." PTR_FORMAT ").", p2i(start), p2i(end));
|
||||||
memset(_option_buf, 0, sizeof(_option_buf));
|
memset(_option_buf, 0, sizeof(_option_buf));
|
||||||
|
@ -682,10 +656,11 @@ void decode_env::print_insn_labels() {
|
||||||
if (_codeBlob != NULL) {
|
if (_codeBlob != NULL) {
|
||||||
_codeBlob->print_block_comment(st, p);
|
_codeBlob->print_block_comment(st, p);
|
||||||
}
|
}
|
||||||
if (_codeBuffer != NULL) {
|
#ifndef PRODUCT
|
||||||
_codeBuffer->print_block_comment(st, p);
|
if (_strings != NULL) {
|
||||||
|
_strings->print_block_comment(st, (intptr_t)(p - _start));
|
||||||
}
|
}
|
||||||
_strings.print_block_comment(st, (intptr_t)(p - _start));
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,49 +894,13 @@ bool Disassembler::load_library(outputStream* st) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Directly disassemble code buffer.
|
|
||||||
void Disassembler::decode(CodeBuffer* cb, address start, address end, outputStream* st) {
|
|
||||||
#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
|
|
||||||
//---< Test memory before decoding >---
|
|
||||||
if (!(cb->contains(start) && cb->contains(end))) {
|
|
||||||
//---< Allow output suppression, but prevent writing to a NULL stream. Could happen with +PrintStubCode. >---
|
|
||||||
if (st != NULL) {
|
|
||||||
st->print("Memory range [" PTR_FORMAT ".." PTR_FORMAT "] not contained in CodeBuffer", p2i(start), p2i(end));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!os::is_readable_range(start, end)) {
|
|
||||||
//---< Allow output suppression, but prevent writing to a NULL stream. Could happen with +PrintStubCode. >---
|
|
||||||
if (st != NULL) {
|
|
||||||
st->print("Memory range [" PTR_FORMAT ".." PTR_FORMAT "] not readable", p2i(start), p2i(end));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
decode_env env(cb, st);
|
|
||||||
env.output()->print_cr("--------------------------------------------------------------------------------");
|
|
||||||
env.output()->print("Decoding CodeBuffer (" PTR_FORMAT ")", p2i(cb));
|
|
||||||
if (cb->name() != NULL) {
|
|
||||||
env.output()->print(", name: %s,", cb->name());
|
|
||||||
}
|
|
||||||
env.output()->print_cr(" at [" PTR_FORMAT ", " PTR_FORMAT "] " JLONG_FORMAT " bytes", p2i(start), p2i(end), ((jlong)(end - start)));
|
|
||||||
|
|
||||||
if (is_abstract()) {
|
|
||||||
AbstractDisassembler::decode_abstract(start, end, env.output(), Assembler::instr_maxlen());
|
|
||||||
} else {
|
|
||||||
env.decode_instructions(start, end);
|
|
||||||
}
|
|
||||||
env.output()->print_cr("--------------------------------------------------------------------------------");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Directly disassemble code blob.
|
// Directly disassemble code blob.
|
||||||
void Disassembler::decode(CodeBlob* cb, outputStream* st, CodeStrings c) {
|
void Disassembler::decode(CodeBlob* cb, outputStream* st) {
|
||||||
#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
|
#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
|
||||||
if (cb->is_nmethod()) {
|
if (cb->is_nmethod()) {
|
||||||
// If we have an nmethod at hand,
|
// If we have an nmethod at hand,
|
||||||
// call the specialized decoder directly.
|
// call the specialized decoder directly.
|
||||||
decode((nmethod*)cb, st, c);
|
decode((nmethod*)cb, st);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -999,7 +938,7 @@ void Disassembler::decode(CodeBlob* cb, outputStream* st, CodeStrings c) {
|
||||||
// Decode a nmethod.
|
// Decode a nmethod.
|
||||||
// This includes printing the constant pool and all code segments.
|
// This includes printing the constant pool and all code segments.
|
||||||
// The nmethod data structures (oop maps, relocations and the like) are not printed.
|
// The nmethod data structures (oop maps, relocations and the like) are not printed.
|
||||||
void Disassembler::decode(nmethod* nm, outputStream* st, CodeStrings c) {
|
void Disassembler::decode(nmethod* nm, outputStream* st) {
|
||||||
#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
|
#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
|
||||||
ttyLocker ttyl;
|
ttyLocker ttyl;
|
||||||
|
|
||||||
|
@ -1018,7 +957,7 @@ void Disassembler::decode(nmethod* nm, outputStream* st, CodeStrings c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decode a range, given as [start address, end address)
|
// Decode a range, given as [start address, end address)
|
||||||
void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c /*, ptrdiff_t offset */) {
|
void Disassembler::decode(address start, address end, outputStream* st, const CodeStrings* c) {
|
||||||
#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
|
#if defined(SUPPORT_ASSEMBLY) || defined(SUPPORT_ABSTRACT_ASSEMBLY)
|
||||||
//---< Test memory before decoding >---
|
//---< Test memory before decoding >---
|
||||||
if (!os::is_readable_range(start, end)) {
|
if (!os::is_readable_range(start, end)) {
|
||||||
|
@ -1046,7 +985,7 @@ void Disassembler::decode(address start, address end, outputStream* st, CodeStri
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
// This seems to be just a chunk of memory.
|
// This seems to be just a chunk of memory.
|
||||||
decode_env env(start, end, st);
|
decode_env env(start, end, st, c);
|
||||||
env.output()->print_cr("--------------------------------------------------------------------------------");
|
env.output()->print_cr("--------------------------------------------------------------------------------");
|
||||||
env.decode_instructions(start, end);
|
env.decode_instructions(start, end);
|
||||||
env.output()->print_cr("--------------------------------------------------------------------------------");
|
env.output()->print_cr("--------------------------------------------------------------------------------");
|
||||||
|
|
|
@ -28,7 +28,8 @@
|
||||||
#include "utilities/globalDefinitions.hpp"
|
#include "utilities/globalDefinitions.hpp"
|
||||||
|
|
||||||
#include "asm/assembler.hpp"
|
#include "asm/assembler.hpp"
|
||||||
#include "asm/codeBuffer.hpp"
|
#include "code/codeBlob.hpp"
|
||||||
|
#include "code/nmethod.hpp"
|
||||||
#include "compiler/abstractDisassembler.hpp"
|
#include "compiler/abstractDisassembler.hpp"
|
||||||
#include "runtime/globals.hpp"
|
#include "runtime/globals.hpp"
|
||||||
#include "utilities/macros.hpp"
|
#include "utilities/macros.hpp"
|
||||||
|
@ -88,10 +89,10 @@ class Disassembler : public AbstractDisassembler {
|
||||||
// about which decoding format is used.
|
// about which decoding format is used.
|
||||||
// We can also enforce using the abstract disassembler.
|
// We can also enforce using the abstract disassembler.
|
||||||
static bool is_abstract() {
|
static bool is_abstract() {
|
||||||
if (!_tried_to_load_library /* && !UseAbstractDisassembler */) {
|
if (!_tried_to_load_library) {
|
||||||
load_library();
|
load_library();
|
||||||
}
|
}
|
||||||
return ! _library_usable /* || UseAbstractDisassembler */; // Not available until DecodeErrorFile is supported.
|
return ! _library_usable;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check out if we are doing a live disassembly or a post-mortem
|
// Check out if we are doing a live disassembly or a post-mortem
|
||||||
|
@ -105,14 +106,12 @@ class Disassembler : public AbstractDisassembler {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Directly disassemble code buffer.
|
|
||||||
static void decode(CodeBuffer* cb, address start, address end, outputStream* st = NULL);
|
|
||||||
// Directly disassemble code blob.
|
// Directly disassemble code blob.
|
||||||
static void decode(CodeBlob *cb, outputStream* st = NULL, CodeStrings c = CodeStrings());
|
static void decode(CodeBlob *cb, outputStream* st = NULL);
|
||||||
// Directly disassemble nmethod.
|
// Directly disassemble nmethod.
|
||||||
static void decode(nmethod* nm, outputStream* st = NULL, CodeStrings c = CodeStrings());
|
static void decode(nmethod* nm, outputStream* st = NULL);
|
||||||
// Disassemble an arbitrary memory range.
|
// Disassemble an arbitrary memory range.
|
||||||
static void decode(address start, address end, outputStream* st = NULL, CodeStrings c = CodeStrings() /* , ptrdiff_t offset */);
|
static void decode(address start, address end, outputStream* st = NULL, const CodeStrings* = NULL);
|
||||||
|
|
||||||
static void _hook(const char* file, int line, class MacroAssembler* masm);
|
static void _hook(const char* file, int line, class MacroAssembler* masm);
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ void InterpreterCodelet::print_on(outputStream* st) const {
|
||||||
|
|
||||||
if (PrintInterpreter) {
|
if (PrintInterpreter) {
|
||||||
st->cr();
|
st->cr();
|
||||||
Disassembler::decode(code_begin(), code_end(), st, DEBUG_ONLY(_strings) NOT_DEBUG(CodeStrings()));
|
Disassembler::decode(code_begin(), code_end(), st DEBUG_ONLY(COMMA &_strings));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,8 @@ CodeletMark::~CodeletMark() {
|
||||||
// Commit Codelet.
|
// Commit Codelet.
|
||||||
int committed_code_size = (*_masm)->code()->pure_insts_size();
|
int committed_code_size = (*_masm)->code()->pure_insts_size();
|
||||||
if (committed_code_size) {
|
if (committed_code_size) {
|
||||||
AbstractInterpreter::code()->commit(committed_code_size, (*_masm)->code()->strings());
|
CodeStrings cs NOT_PRODUCT(= (*_masm)->code()->strings());
|
||||||
|
AbstractInterpreter::code()->commit(committed_code_size, cs);
|
||||||
}
|
}
|
||||||
// Make sure nobody can use _masm outside a CodeletMark lifespan.
|
// Make sure nobody can use _masm outside a CodeletMark lifespan.
|
||||||
*_masm = NULL;
|
*_masm = NULL;
|
||||||
|
|
|
@ -49,14 +49,14 @@ class InterpreterCodelet: public Stub {
|
||||||
int _size; // the size in bytes
|
int _size; // the size in bytes
|
||||||
const char* _description; // a description of the codelet, for debugging & printing
|
const char* _description; // a description of the codelet, for debugging & printing
|
||||||
Bytecodes::Code _bytecode; // associated bytecode if any
|
Bytecodes::Code _bytecode; // associated bytecode if any
|
||||||
DEBUG_ONLY(CodeStrings _strings;) // Comments for annotating assembler output.
|
NOT_PRODUCT(CodeStrings _strings;) // Comments for annotating assembler output.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Initialization/finalization
|
// Initialization/finalization
|
||||||
void initialize(int size,
|
void initialize(int size,
|
||||||
CodeStrings& strings) { _size = size;
|
CodeStrings& strings) { _size = size;
|
||||||
DEBUG_ONLY(::new(&_strings) CodeStrings();)
|
NOT_PRODUCT(_strings = CodeStrings();)
|
||||||
DEBUG_ONLY(_strings.assign(strings);) }
|
NOT_PRODUCT(_strings.copy(strings);) }
|
||||||
void finalize() { ShouldNotCallThis(); }
|
void finalize() { ShouldNotCallThis(); }
|
||||||
|
|
||||||
// General info/converters
|
// General info/converters
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
LOG_TAG(classhisto) \
|
LOG_TAG(classhisto) \
|
||||||
LOG_TAG(cleanup) \
|
LOG_TAG(cleanup) \
|
||||||
LOG_TAG(codecache) \
|
LOG_TAG(codecache) \
|
||||||
|
NOT_PRODUCT(LOG_TAG(codestrings)) \
|
||||||
LOG_TAG(compaction) \
|
LOG_TAG(compaction) \
|
||||||
LOG_TAG(compilation) \
|
LOG_TAG(compilation) \
|
||||||
LOG_TAG(condy) \
|
LOG_TAG(condy) \
|
||||||
|
|
|
@ -73,13 +73,13 @@ StubCodeGenerator::StubCodeGenerator(CodeBuffer* code, bool print_code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
StubCodeGenerator::~StubCodeGenerator() {
|
StubCodeGenerator::~StubCodeGenerator() {
|
||||||
if (PRODUCT_ONLY(_print_code) NOT_PRODUCT(true)) {
|
#ifndef PRODUCT
|
||||||
CodeBuffer* cbuf = _masm->code();
|
CodeBuffer* cbuf = _masm->code();
|
||||||
CodeBlob* blob = CodeCache::find_blob_unsafe(cbuf->insts()->start());
|
CodeBlob* blob = CodeCache::find_blob_unsafe(cbuf->insts()->start());
|
||||||
if (blob != NULL) {
|
if (blob != NULL) {
|
||||||
blob->set_strings(cbuf->strings());
|
blob->set_strings(cbuf->strings());
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void StubCodeGenerator::stub_prolog(StubCodeDesc* cdesc) {
|
void StubCodeGenerator::stub_prolog(StubCodeDesc* cdesc) {
|
||||||
|
@ -88,21 +88,16 @@ void StubCodeGenerator::stub_prolog(StubCodeDesc* cdesc) {
|
||||||
|
|
||||||
void StubCodeGenerator::stub_epilog(StubCodeDesc* cdesc) {
|
void StubCodeGenerator::stub_epilog(StubCodeDesc* cdesc) {
|
||||||
if (_print_code) {
|
if (_print_code) {
|
||||||
CodeStrings cs;
|
|
||||||
ptrdiff_t offset = 0;
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
// Find the code strings in the outer CodeBuffer.
|
// Find the code strings in the outer CodeBuffer.
|
||||||
CodeBuffer *outer_cbuf = _masm->code_section()->outer();
|
CodeBuffer *outer_cbuf = _masm->code_section()->outer();
|
||||||
cs = outer_cbuf->strings();
|
CodeStrings* cs = &outer_cbuf->strings();
|
||||||
// The offset from the start of the outer CodeBuffer to the start
|
|
||||||
// of this stub.
|
|
||||||
offset = cdesc->begin() - outer_cbuf->insts()->start();
|
|
||||||
#endif
|
#endif
|
||||||
ttyLocker ttyl;
|
ttyLocker ttyl;
|
||||||
tty->print_cr("- - - [BEGIN] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
tty->print_cr("- - - [BEGIN] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||||
cdesc->print_on(tty);
|
cdesc->print_on(tty);
|
||||||
tty->cr();
|
tty->cr();
|
||||||
Disassembler::decode(cdesc->begin(), cdesc->end(), tty, cs /*, offset */);
|
Disassembler::decode(cdesc->begin(), cdesc->end(), tty NOT_PRODUCT(COMMA cs));
|
||||||
tty->print_cr("- - - [END] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
tty->print_cr("- - - [END] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
|
||||||
tty->cr();
|
tty->cr();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue