提交 7dbd7cfa 编写于 作者: R roland

8008555: Debugging code in compiled method sometimes leaks memory

Summary: support for strings that have same life-time as code that uses them.
Reviewed-by: kvn, twisti
上级 f71c860d
...@@ -1385,13 +1385,13 @@ void MacroAssembler::_verify_oop(Register reg, const char* msg, const char * fil ...@@ -1385,13 +1385,13 @@ void MacroAssembler::_verify_oop(Register reg, const char* msg, const char * fil
} }
#endif #endif
int len = strlen(file) + strlen(msg) + 1 + 4; const char* real_msg = NULL;
sprintf(buffer, "%d", line); {
len += strlen(buffer); ResourceMark rm;
sprintf(buffer, " at offset %d ", offset()); stringStream ss;
len += strlen(buffer); ss.print("%s at offset %d (%s:%d)", msg, offset(), file, line);
char * real_msg = new char[len]; real_msg = code_string(ss.as_string());
sprintf(real_msg, "%s%s(%s:%d)", msg, buffer, file, line); }
// Call indirectly to solve generation ordering problem // Call indirectly to solve generation ordering problem
AddressLiteral a(StubRoutines::verify_oop_subroutine_entry_address()); AddressLiteral a(StubRoutines::verify_oop_subroutine_entry_address());
...@@ -1423,13 +1423,13 @@ void MacroAssembler::_verify_oop_addr(Address addr, const char* msg, const char ...@@ -1423,13 +1423,13 @@ void MacroAssembler::_verify_oop_addr(Address addr, const char* msg, const char
// plausibility check for oops // plausibility check for oops
if (!VerifyOops) return; if (!VerifyOops) return;
char buffer[64]; const char* real_msg = NULL;
sprintf(buffer, "%d", line); {
int len = strlen(file) + strlen(msg) + 1 + 4 + strlen(buffer); ResourceMark rm;
sprintf(buffer, " at SP+%d ", addr.disp()); stringStream ss;
len += strlen(buffer); ss.print("%s at SP+%d (%s:%d)", msg, addr.disp(), file, line);
char * real_msg = new char[len]; real_msg = code_string(ss.as_string());
sprintf(real_msg, "%s at SP+%d (%s:%d)", msg, addr.disp(), file, line); }
// Call indirectly to solve generation ordering problem // Call indirectly to solve generation ordering problem
AddressLiteral a(StubRoutines::verify_oop_subroutine_entry_address()); AddressLiteral a(StubRoutines::verify_oop_subroutine_entry_address());
...@@ -1622,9 +1622,13 @@ void MacroAssembler::untested(const char* what) { ...@@ -1622,9 +1622,13 @@ void MacroAssembler::untested(const char* what) {
// in order to run automated test scripts on the VM // in order to run automated test scripts on the VM
// Use the flag ShowMessageBoxOnError // Use the flag ShowMessageBoxOnError
char* b = new char[1024]; const char* b = NULL;
sprintf(b, "untested: %s", what); {
ResourceMark rm;
stringStream ss;
ss.print("untested: %s", what);
b = code_string(ss.as_string());
}
if (ShowMessageBoxOnError) { STOP(b); } if (ShowMessageBoxOnError) { STOP(b); }
else { warn(b); } else { warn(b); }
} }
......
...@@ -4262,8 +4262,13 @@ void MacroAssembler::verify_oop(Register reg, const char* s) { ...@@ -4262,8 +4262,13 @@ void MacroAssembler::verify_oop(Register reg, const char* s) {
if (!VerifyOops) return; if (!VerifyOops) return;
// Pass register number to verify_oop_subroutine // Pass register number to verify_oop_subroutine
char* b = new char[strlen(s) + 50]; const char* b = NULL;
sprintf(b, "verify_oop: %s: %s", reg->name(), s); {
ResourceMark rm;
stringStream ss;
ss.print("verify_oop: %s: %s", reg->name(), s);
b = code_string(ss.as_string());
}
BLOCK_COMMENT("verify_oop {"); BLOCK_COMMENT("verify_oop {");
#ifdef _LP64 #ifdef _LP64
push(rscratch1); // save r10, trashed by movptr() push(rscratch1); // save r10, trashed by movptr()
...@@ -4297,9 +4302,14 @@ RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_ad ...@@ -4297,9 +4302,14 @@ RegisterOrConstant MacroAssembler::delayed_value_impl(intptr_t* delayed_value_ad
{ Label L; { Label L;
testptr(tmp, tmp); testptr(tmp, tmp);
if (WizardMode) { if (WizardMode) {
const char* buf = NULL;
{
ResourceMark rm;
stringStream ss;
ss.print("DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
buf = code_string(ss.as_string());
}
jcc(Assembler::notZero, L); jcc(Assembler::notZero, L);
char* buf = new char[40];
sprintf(buf, "DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
STOP(buf); STOP(buf);
} else { } else {
jccb(Assembler::notZero, L); jccb(Assembler::notZero, L);
...@@ -4343,9 +4353,13 @@ void MacroAssembler::verify_oop_addr(Address addr, const char* s) { ...@@ -4343,9 +4353,13 @@ void MacroAssembler::verify_oop_addr(Address addr, const char* s) {
// Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord); // Address adjust(addr.base(), addr.index(), addr.scale(), addr.disp() + BytesPerWord);
// Pass register number to verify_oop_subroutine // Pass register number to verify_oop_subroutine
char* b = new char[strlen(s) + 50]; const char* b = NULL;
sprintf(b, "verify_oop_addr: %s", s); {
ResourceMark rm;
stringStream ss;
ss.print("verify_oop_addr: %s", s);
b = code_string(ss.as_string());
}
#ifdef _LP64 #ifdef _LP64
push(rscratch1); // save r10, trashed by movptr() push(rscratch1); // save r10, trashed by movptr()
#endif #endif
......
...@@ -284,15 +284,19 @@ void AbstractAssembler::update_delayed_values() { ...@@ -284,15 +284,19 @@ void AbstractAssembler::update_delayed_values() {
DelayedConstant::update_all(); DelayedConstant::update_all();
} }
void AbstractAssembler::block_comment(const char* comment) { void AbstractAssembler::block_comment(const char* comment) {
if (sect() == CodeBuffer::SECT_INSTS) { if (sect() == CodeBuffer::SECT_INSTS) {
code_section()->outer()->block_comment(offset(), comment); code_section()->outer()->block_comment(offset(), comment);
} }
} }
const char* AbstractAssembler::code_string(const char* str) {
if (sect() == CodeBuffer::SECT_INSTS || sect() == CodeBuffer::SECT_STUBS) {
return code_section()->outer()->code_string(str);
}
return NULL;
}
bool MacroAssembler::needs_explicit_null_check(intptr_t offset) { bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
// Exception handler checks the nmethod's implicit null checks table // Exception handler checks the nmethod's implicit null checks table
// only when this method returns false. // only when this method returns false.
......
...@@ -336,6 +336,8 @@ class AbstractAssembler : public ResourceObj { ...@@ -336,6 +336,8 @@ class AbstractAssembler : public ResourceObj {
// along with the disassembly when printing nmethods. Currently // along with the disassembly when printing nmethods. Currently
// only supported in the instruction section of the code buffer. // only supported in the instruction section of the code buffer.
void block_comment(const char* comment); void block_comment(const char* comment);
// Copy str to a buffer that has the same lifetime as the CodeBuffer
const char* code_string(const char* str);
// Label functions // Label functions
void bind(Label& L); // binds an unbound label L to the current code position void bind(Label& L); // binds an unbound label L to the current code position
......
...@@ -703,8 +703,8 @@ void CodeBuffer::copy_code_to(CodeBlob* dest_blob) { ...@@ -703,8 +703,8 @@ void CodeBuffer::copy_code_to(CodeBlob* dest_blob) {
this->compute_final_layout(&dest); this->compute_final_layout(&dest);
relocate_code_to(&dest); relocate_code_to(&dest);
// transfer comments from buffer to blob // transfer strings and comments from buffer to blob
dest_blob->set_comments(_comments); dest_blob->set_strings(_strings);
// Done moving code bytes; were they the right size? // Done moving code bytes; were they the right size?
assert(round_to(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity"); assert(round_to(dest.total_content_size(), oopSize) == dest_blob->content_size(), "sanity");
...@@ -1003,58 +1003,78 @@ void CodeSection::decode() { ...@@ -1003,58 +1003,78 @@ void CodeSection::decode() {
void CodeBuffer::block_comment(intptr_t offset, const char * comment) { void CodeBuffer::block_comment(intptr_t offset, const char * comment) {
_comments.add_comment(offset, comment); _strings.add_comment(offset, comment);
} }
class CodeComment: public CHeapObj<mtCode> { const char* CodeBuffer::code_string(const char* str) {
return _strings.add_string(str);
}
class CodeString: public CHeapObj<mtCode> {
private: private:
friend class CodeComments; friend class CodeStrings;
const char * _string;
CodeString* _next;
intptr_t _offset; intptr_t _offset;
const char * _comment;
CodeComment* _next;
~CodeComment() { ~CodeString() {
assert(_next == NULL, "wrong interface for freeing list"); assert(_next == NULL, "wrong interface for freeing list");
os::free((void*)_comment, mtCode); os::free((void*)_string, mtCode);
} }
bool is_comment() const { return _offset >= 0; }
public: public:
CodeComment(intptr_t offset, const char * comment) { CodeString(const char * string, intptr_t offset = -1)
_offset = offset; : _next(NULL), _offset(offset) {
_comment = os::strdup(comment, mtCode); _string = os::strdup(string, mtCode);
_next = NULL;
} }
intptr_t offset() const { return _offset; } const char * string() const { return _string; }
const char * comment() const { return _comment; } intptr_t offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset; }
CodeComment* next() { return _next; } CodeString* next() const { return _next; }
void set_next(CodeComment* next) { _next = next; } void set_next(CodeString* next) { _next = next; }
CodeComment* find(intptr_t offset) { CodeString* first_comment() {
CodeComment* a = this; if (is_comment()) {
while (a != NULL && a->_offset != offset) { return this;
a = a->_next; } else {
return next_comment();
} }
return a;
} }
CodeString* next_comment() const {
// Convenience for add_comment. CodeString* s = _next;
CodeComment* find_last(intptr_t offset) { while (s != NULL && !s->is_comment()) {
CodeComment* a = find(offset); s = s->_next;
if (a != NULL) {
while ((a->_next != NULL) && (a->_next->_offset == offset)) {
a = a->_next;
}
} }
return a; return s;
} }
}; };
CodeString* CodeStrings::find(intptr_t offset) const {
CodeString* a = _strings->first_comment();
while (a != NULL && a->offset() != offset) {
a = a->next_comment();
}
return a;
}
// Convenience for add_comment.
CodeString* CodeStrings::find_last(intptr_t offset) const {
CodeString* a = find(offset);
if (a != NULL) {
CodeString* c = NULL;
while (((c = a->next_comment()) != NULL) && (c->offset() == offset)) {
a = c;
}
}
return a;
}
void CodeComments::add_comment(intptr_t offset, const char * comment) { void CodeStrings::add_comment(intptr_t offset, const char * comment) {
CodeComment* c = new CodeComment(offset, comment); CodeString* c = new CodeString(comment, offset);
CodeComment* inspos = (_comments == NULL) ? NULL : _comments->find_last(offset); CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset);
if (inspos) { if (inspos) {
// insert after already existing comments with same offset // insert after already existing comments with same offset
...@@ -1062,43 +1082,47 @@ void CodeComments::add_comment(intptr_t offset, const char * comment) { ...@@ -1062,43 +1082,47 @@ void CodeComments::add_comment(intptr_t offset, const char * comment) {
inspos->set_next(c); inspos->set_next(c);
} else { } else {
// no comments with such offset, yet. Insert before anything else. // no comments with such offset, yet. Insert before anything else.
c->set_next(_comments); c->set_next(_strings);
_comments = c; _strings = c;
} }
} }
void CodeStrings::assign(CodeStrings& other) {
void CodeComments::assign(CodeComments& other) { _strings = other._strings;
_comments = other._comments;
} }
void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) const { if (_strings != NULL) {
if (_comments != NULL) { CodeString* c = find(offset);
CodeComment* c = _comments->find(offset);
while (c && c->offset() == offset) { while (c && c->offset() == offset) {
stream->bol(); stream->bol();
stream->print(" ;; "); stream->print(" ;; ");
stream->print_cr(c->comment()); stream->print_cr(c->string());
c = c->next(); c = c->next_comment();
} }
} }
} }
void CodeComments::free() { void CodeStrings::free() {
CodeComment* n = _comments; 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
CodeComment* p = n->_next; CodeString* p = n->next();
n->_next = NULL; n->set_next(NULL);
delete n; delete n;
n = p; n = p;
} }
_comments = NULL; _strings = NULL;
} }
const char* CodeStrings::add_string(const char * string) {
CodeString* s = new CodeString(string);
s->set_next(_strings);
_strings = s;
assert(s->string() != NULL, "should have a string");
return s->string();
}
void CodeBuffer::decode() { void CodeBuffer::decode() {
ttyLocker ttyl; ttyLocker ttyl;
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "code/oopRecorder.hpp" #include "code/oopRecorder.hpp"
#include "code/relocInfo.hpp" #include "code/relocInfo.hpp"
class CodeComments; class CodeStrings;
class PhaseCFG; class PhaseCFG;
class Compile; class Compile;
class BufferBlob; class BufferBlob;
...@@ -240,27 +240,31 @@ class CodeSection VALUE_OBJ_CLASS_SPEC { ...@@ -240,27 +240,31 @@ class CodeSection VALUE_OBJ_CLASS_SPEC {
#endif //PRODUCT #endif //PRODUCT
}; };
class CodeComment; class CodeString;
class CodeComments VALUE_OBJ_CLASS_SPEC { class CodeStrings VALUE_OBJ_CLASS_SPEC {
private: private:
#ifndef PRODUCT #ifndef PRODUCT
CodeComment* _comments; CodeString* _strings;
#endif #endif
CodeString* find(intptr_t offset) const;
CodeString* find_last(intptr_t offset) const;
public: public:
CodeComments() { CodeStrings() {
#ifndef PRODUCT #ifndef PRODUCT
_comments = NULL; _strings = NULL;
#endif #endif
} }
const char* add_string(const char * string) PRODUCT_RETURN_(return NULL;);
void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN; void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN;
void assign(CodeComments& other) PRODUCT_RETURN; void assign(CodeStrings& other) PRODUCT_RETURN;
void free() PRODUCT_RETURN; void free() PRODUCT_RETURN;
}; };
// A CodeBuffer describes a memory space into which assembly // A CodeBuffer describes a memory space into which assembly
// code is generated. This memory space usually occupies the // code is generated. This memory space usually occupies the
// interior of a single BufferBlob, but in some cases it may be // interior of a single BufferBlob, but in some cases it may be
...@@ -326,7 +330,7 @@ class CodeBuffer: public StackObj { ...@@ -326,7 +330,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;
CodeComments _comments; CodeStrings _strings;
OopRecorder _default_oop_recorder; // override with initialize_oop_recorder OopRecorder _default_oop_recorder; // override with initialize_oop_recorder
Arena* _overflow_arena; Arena* _overflow_arena;
...@@ -527,7 +531,7 @@ class CodeBuffer: public StackObj { ...@@ -527,7 +531,7 @@ 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; }
CodeComments& comments() { return _comments; } CodeStrings& strings() { return _strings; }
// Code generation // Code generation
void relocate(address at, RelocationHolder const& rspec, int format = 0) { void relocate(address at, RelocationHolder const& rspec, int format = 0) {
...@@ -556,6 +560,7 @@ class CodeBuffer: public StackObj { ...@@ -556,6 +560,7 @@ class CodeBuffer: public StackObj {
address transform_address(const CodeBuffer &cb, address addr) const; address transform_address(const CodeBuffer &cb, address addr) const;
void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN; void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
const char* code_string(const char* str) PRODUCT_RETURN_(return NULL;);
// Log a little info about section usage in the CodeBuffer // Log a little info about section usage in the CodeBuffer
void log_section_sizes(const char* name); void log_section_sizes(const char* name);
......
...@@ -186,7 +186,7 @@ void CodeBlob::flush() { ...@@ -186,7 +186,7 @@ void CodeBlob::flush() {
FREE_C_HEAP_ARRAY(unsigned char, _oop_maps, mtCode); FREE_C_HEAP_ARRAY(unsigned char, _oop_maps, mtCode);
_oop_maps = NULL; _oop_maps = NULL;
} }
_comments.free(); _strings.free();
} }
......
...@@ -66,7 +66,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC { ...@@ -66,7 +66,7 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
int _data_offset; // offset to where data region begins int _data_offset; // offset to where data region begins
int _frame_size; // size of stack frame int _frame_size; // size of stack frame
OopMapSet* _oop_maps; // OopMap for this CodeBlob OopMapSet* _oop_maps; // OopMap for this CodeBlob
CodeComments _comments; CodeStrings _strings;
public: public:
// Returns the space needed for CodeBlob // Returns the space needed for CodeBlob
...@@ -186,12 +186,12 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC { ...@@ -186,12 +186,12 @@ class CodeBlob VALUE_OBJ_CLASS_SPEC {
// 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 {
intptr_t offset = (intptr_t)(block_begin - code_begin()); intptr_t offset = (intptr_t)(block_begin - code_begin());
_comments.print_block_comment(stream, offset); _strings.print_block_comment(stream, offset);
} }
// Transfer ownership of comments to this CodeBlob // Transfer ownership of comments to this CodeBlob
void set_comments(CodeComments& comments) { void set_strings(CodeStrings& strings) {
_comments.assign(comments); _strings.assign(strings);
} }
}; };
......
...@@ -50,7 +50,7 @@ class ICStub: public Stub { ...@@ -50,7 +50,7 @@ class ICStub: public Stub {
friend class ICStubInterface; friend class ICStubInterface;
// This will be called only by ICStubInterface // This will be called only by ICStubInterface
void initialize(int size, void initialize(int size,
CodeComments comments) { _size = size; _ic_site = NULL; } CodeStrings strings) { _size = size; _ic_site = NULL; }
void finalize(); // called when a method is removed void finalize(); // called when a method is removed
// General info // General info
......
...@@ -101,8 +101,8 @@ Stub* StubQueue::stub_containing(address pc) const { ...@@ -101,8 +101,8 @@ Stub* StubQueue::stub_containing(address pc) const {
Stub* StubQueue::request_committed(int code_size) { Stub* StubQueue::request_committed(int code_size) {
Stub* s = request(code_size); Stub* s = request(code_size);
CodeComments comments; CodeStrings strings;
if (s != NULL) commit(code_size, comments); if (s != NULL) commit(code_size, strings);
return s; return s;
} }
...@@ -119,8 +119,8 @@ Stub* StubQueue::request(int requested_code_size) { ...@@ -119,8 +119,8 @@ Stub* StubQueue::request(int requested_code_size) {
assert(_buffer_limit == _buffer_size, "buffer must be fully usable"); assert(_buffer_limit == _buffer_size, "buffer must be fully usable");
if (_queue_end + requested_size <= _buffer_size) { if (_queue_end + requested_size <= _buffer_size) {
// code fits in at the end => nothing to do // code fits in at the end => nothing to do
CodeComments comments; CodeStrings strings;
stub_initialize(s, requested_size, comments); stub_initialize(s, requested_size, strings);
return s; return s;
} else { } else {
// stub doesn't fit in at the queue end // stub doesn't fit in at the queue end
...@@ -137,8 +137,8 @@ Stub* StubQueue::request(int requested_code_size) { ...@@ -137,8 +137,8 @@ Stub* StubQueue::request(int requested_code_size) {
// Queue: |XXX|.......|XXXXXXX|.......| // Queue: |XXX|.......|XXXXXXX|.......|
// ^0 ^end ^begin ^limit ^size // ^0 ^end ^begin ^limit ^size
s = current_stub(); s = current_stub();
CodeComments comments; CodeStrings strings;
stub_initialize(s, requested_size, comments); stub_initialize(s, requested_size, strings);
return s; return s;
} }
// Not enough space left // Not enough space left
...@@ -147,12 +147,12 @@ Stub* StubQueue::request(int requested_code_size) { ...@@ -147,12 +147,12 @@ Stub* StubQueue::request(int requested_code_size) {
} }
void StubQueue::commit(int committed_code_size, CodeComments& comments) { void StubQueue::commit(int committed_code_size, CodeStrings& strings) {
assert(committed_code_size > 0, "committed_code_size must be > 0"); 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); int committed_size = round_to(stub_code_size_to_size(committed_code_size), CodeEntryAlignment);
Stub* s = current_stub(); Stub* s = current_stub();
assert(committed_size <= stub_size(s), "committed size must not exceed requested size"); assert(committed_size <= stub_size(s), "committed size must not exceed requested size");
stub_initialize(s, committed_size, comments); stub_initialize(s, committed_size, strings);
_queue_end += committed_size; _queue_end += committed_size;
_number_of_stubs++; _number_of_stubs++;
if (_mutex != NULL) _mutex->unlock(); if (_mutex != NULL) _mutex->unlock();
......
...@@ -73,7 +73,7 @@ class Stub VALUE_OBJ_CLASS_SPEC { ...@@ -73,7 +73,7 @@ class Stub VALUE_OBJ_CLASS_SPEC {
public: public:
// Initialization/finalization // Initialization/finalization
void initialize(int size, void initialize(int size,
CodeComments& comments) { ShouldNotCallThis(); } // called to initialize/specify the stub's size CodeStrings& strings) { ShouldNotCallThis(); } // called to initialize/specify the stub's size
void finalize() { ShouldNotCallThis(); } // called before the stub is deallocated void finalize() { ShouldNotCallThis(); } // called before the stub is deallocated
// General info/converters // General info/converters
...@@ -107,7 +107,7 @@ class StubInterface: public CHeapObj<mtCode> { ...@@ -107,7 +107,7 @@ class StubInterface: public CHeapObj<mtCode> {
public: public:
// Initialization/finalization // Initialization/finalization
virtual void initialize(Stub* self, int size, virtual void initialize(Stub* self, int size,
CodeComments& comments) = 0; // called after creation (called twice if allocated via (request, commit)) CodeStrings& strings) = 0; // called after creation (called twice if allocated via (request, commit))
virtual void finalize(Stub* self) = 0; // called before deallocation virtual void finalize(Stub* self) = 0; // called before deallocation
// General info/converters // General info/converters
...@@ -136,7 +136,7 @@ class StubInterface: public CHeapObj<mtCode> { ...@@ -136,7 +136,7 @@ class StubInterface: public CHeapObj<mtCode> {
public: \ public: \
/* Initialization/finalization */ \ /* Initialization/finalization */ \
virtual void initialize(Stub* self, int size, \ virtual void initialize(Stub* self, int size, \
CodeComments& comments) { cast(self)->initialize(size, comments); } \ CodeStrings& strings) { cast(self)->initialize(size, strings); } \
virtual void finalize(Stub* self) { cast(self)->finalize(); } \ virtual void finalize(Stub* self) { cast(self)->finalize(); } \
\ \
/* General info */ \ /* General info */ \
...@@ -176,7 +176,7 @@ class StubQueue: public CHeapObj<mtCode> { ...@@ -176,7 +176,7 @@ class StubQueue: public CHeapObj<mtCode> {
// Stub functionality accessed via interface // Stub functionality accessed via interface
void stub_initialize(Stub* s, int size, void stub_initialize(Stub* s, int size,
CodeComments& comments) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, comments); } CodeStrings& strings) { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, strings); }
void stub_finalize(Stub* s) { _stub_interface->finalize(s); } void stub_finalize(Stub* s) { _stub_interface->finalize(s); }
int stub_size(Stub* s) const { return _stub_interface->size(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); } bool stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); }
...@@ -206,7 +206,7 @@ class StubQueue: public CHeapObj<mtCode> { ...@@ -206,7 +206,7 @@ class StubQueue: public CHeapObj<mtCode> {
Stub* request_committed(int code_size); // request a stub that provides exactly code_size space for code 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 Stub* request(int requested_code_size); // request a stub with a (maximum) code space - locks the queue
void commit (int committed_code_size, void commit (int committed_code_size,
CodeComments& comments); // commit the previously requested stub - unlocks the queue CodeStrings& strings); // commit the previously requested stub - unlocks the queue
// Stub deallocation // Stub deallocation
void remove_first(); // remove the first stub in the queue void remove_first(); // remove the first stub in the queue
......
...@@ -158,7 +158,7 @@ class decode_env { ...@@ -158,7 +158,7 @@ class decode_env {
private: private:
nmethod* _nm; nmethod* _nm;
CodeBlob* _code; CodeBlob* _code;
CodeComments _comments; CodeStrings _strings;
outputStream* _output; outputStream* _output;
address _start, _end; address _start, _end;
...@@ -198,7 +198,7 @@ class decode_env { ...@@ -198,7 +198,7 @@ class decode_env {
void print_address(address value); void print_address(address value);
public: public:
decode_env(CodeBlob* code, outputStream* output, CodeComments c = CodeComments()); decode_env(CodeBlob* code, outputStream* output, CodeStrings c = CodeStrings());
address decode_instructions(address start, address end); address decode_instructions(address start, address end);
...@@ -242,13 +242,13 @@ class decode_env { ...@@ -242,13 +242,13 @@ class decode_env {
const char* options() { return _option_buf; } const char* options() { return _option_buf; }
}; };
decode_env::decode_env(CodeBlob* code, outputStream* output, CodeComments c) { decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) {
memset(this, 0, sizeof(*this)); memset(this, 0, sizeof(*this));
_output = output ? output : tty; _output = output ? output : tty;
_code = code; _code = code;
if (code != NULL && code->is_nmethod()) if (code != NULL && code->is_nmethod())
_nm = (nmethod*) code; _nm = (nmethod*) code;
_comments.assign(c); _strings.assign(c);
// by default, output pc but not bytes: // by default, output pc but not bytes:
_print_pc = true; _print_pc = true;
...@@ -370,7 +370,7 @@ void decode_env::print_insn_labels() { ...@@ -370,7 +370,7 @@ void decode_env::print_insn_labels() {
if (cb != NULL) { if (cb != NULL) {
cb->print_block_comment(st, p); cb->print_block_comment(st, p);
} }
_comments.print_block_comment(st, (intptr_t)(p - _start)); _strings.print_block_comment(st, (intptr_t)(p - _start));
if (_print_pc) { if (_print_pc) {
st->print(" " PTR_FORMAT ": ", p); st->print(" " PTR_FORMAT ": ", p);
} }
...@@ -498,7 +498,7 @@ void Disassembler::decode(CodeBlob* cb, outputStream* st) { ...@@ -498,7 +498,7 @@ void Disassembler::decode(CodeBlob* cb, outputStream* st) {
env.decode_instructions(cb->code_begin(), cb->code_end()); env.decode_instructions(cb->code_begin(), cb->code_end());
} }
void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) { void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c) {
if (!load_library()) return; if (!load_library()) return;
decode_env env(CodeCache::find_blob_unsafe(start), st, c); decode_env env(CodeCache::find_blob_unsafe(start), st, c);
env.decode_instructions(start, end); env.decode_instructions(start, end);
......
...@@ -100,7 +100,7 @@ class Disassembler { ...@@ -100,7 +100,7 @@ class Disassembler {
} }
static void decode(CodeBlob *cb, outputStream* st = NULL); static void decode(CodeBlob *cb, outputStream* st = NULL);
static void decode(nmethod* nm, outputStream* st = NULL); static void decode(nmethod* nm, outputStream* st = NULL);
static void decode(address begin, address end, outputStream* st = NULL, CodeComments c = CodeComments()); static void decode(address begin, address end, outputStream* st = NULL, CodeStrings c = CodeStrings());
}; };
#endif // SHARE_VM_COMPILER_DISASSEMBLER_HPP #endif // SHARE_VM_COMPILER_DISASSEMBLER_HPP
...@@ -76,7 +76,7 @@ void InterpreterCodelet::print_on(outputStream* st) const { ...@@ -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(_comments) NOT_DEBUG(CodeComments())); Disassembler::decode(code_begin(), code_end(), st, DEBUG_ONLY(_strings) NOT_DEBUG(CodeStrings()));
} }
} }
......
...@@ -48,12 +48,12 @@ class InterpreterCodelet: public Stub { ...@@ -48,12 +48,12 @@ 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(CodeComments _comments;) // Comments for annotating assembler output. DEBUG_ONLY(CodeStrings _strings;) // Comments for annotating assembler output.
public: public:
// Initialization/finalization // Initialization/finalization
void initialize(int size, void initialize(int size,
CodeComments& comments) { _size = size; DEBUG_ONLY(_comments.assign(comments);) } CodeStrings& strings) { _size = size; DEBUG_ONLY(_strings.assign(strings);) }
void finalize() { ShouldNotCallThis(); } void finalize() { ShouldNotCallThis(); }
// General info/converters // General info/converters
...@@ -131,7 +131,7 @@ class CodeletMark: ResourceMark { ...@@ -131,7 +131,7 @@ class CodeletMark: ResourceMark {
// commit Codelet // commit Codelet
AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size(), (*_masm)->code()->comments()); AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size(), (*_masm)->code()->strings());
// make sure nobody can use _masm outside a CodeletMark lifespan // make sure nobody can use _masm outside a CodeletMark lifespan
*_masm = NULL; *_masm = NULL;
} }
......
...@@ -87,7 +87,7 @@ StubCodeGenerator::~StubCodeGenerator() { ...@@ -87,7 +87,7 @@ StubCodeGenerator::~StubCodeGenerator() {
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_comments(cbuf->comments()); blob->set_strings(cbuf->strings());
} }
bool saw_first = false; bool saw_first = false;
StubCodeDesc* toprint[1000]; StubCodeDesc* toprint[1000];
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册