Skip to content

Commit c1524c5

Browse files
committed
8255208: CodeStrings passed to Disassembler::decode are ignored
Reviewed-by: kvn, iklam
1 parent 8e5dff0 commit c1524c5

File tree

11 files changed

+118
-204
lines changed

11 files changed

+118
-204
lines changed

src/hotspot/share/asm/codeBuffer.cpp

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ CodeBuffer::~CodeBuffer() {
140140

141141
// Claim is that stack allocation ensures resources are cleaned up.
142142
// This is resource clean up, let's hope that all were properly copied out.
143-
free_strings();
143+
NOT_PRODUCT(free_strings();)
144144

145145
#ifdef ASSERT
146146
// Save allocation type to execute assert in ~ResourceObj()
@@ -267,13 +267,14 @@ bool CodeBuffer::is_backward_branch(Label& L) {
267267
return L.is_bound() && insts_end() <= locator_address(L.loc());
268268
}
269269

270+
#ifndef PRODUCT
270271
address CodeBuffer::decode_begin() {
271272
address begin = _insts.start();
272273
if (_decode_begin != NULL && _decode_begin > begin)
273274
begin = _decode_begin;
274275
return begin;
275276
}
276-
277+
#endif // !PRODUCT
277278

278279
GrowableArray<int>* CodeBuffer::create_patch_overflow() {
279280
if (_overflow_arena == NULL) {
@@ -752,7 +753,7 @@ void CodeBuffer::copy_code_to(CodeBlob* dest_blob) {
752753
relocate_code_to(&dest);
753754

754755
// transfer strings and comments from buffer to blob
755-
dest_blob->set_strings(_code_strings);
756+
NOT_PRODUCT(dest_blob->set_strings(_code_strings);)
756757

757758
// Done moving code bytes; were they the right size?
758759
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) {
957958
debug_only(Copy::fill_to_bytes(bxp->_total_start, bxp->_total_size,
958959
badCodeHeapFreeVal));
959960

960-
_decode_begin = NULL; // sanity
961-
962961
// Make certain that the new sections are all snugly inside the new blob.
963962
verify_section_allocation();
964963

965964
#ifndef PRODUCT
965+
_decode_begin = NULL; // sanity
966966
if (PrintNMethods && (WizardMode || Verbose)) {
967967
tty->print("expanded CodeBuffer:");
968968
this->print();
@@ -1032,10 +1032,6 @@ void CodeBuffer::log_section_sizes(const char* name) {
10321032

10331033
#ifndef PRODUCT
10341034

1035-
void CodeSection::decode() {
1036-
Disassembler::decode(start(), end());
1037-
}
1038-
10391035
void CodeBuffer::block_comment(intptr_t offset, const char * comment) {
10401036
if (_collect_comments) {
10411037
_code_strings.add_comment(offset, comment);
@@ -1054,8 +1050,12 @@ class CodeString: public CHeapObj<mtCode> {
10541050
CodeString* _prev;
10551051
intptr_t _offset;
10561052

1053+
static long allocated_code_strings;
1054+
10571055
~CodeString() {
10581056
assert(_next == NULL && _prev == NULL, "wrong interface for freeing list");
1057+
allocated_code_strings--;
1058+
log_trace(codestrings)("Freeing CodeString [%s] (%p)", _string, (void*)_string);
10591059
os::free((void*)_string);
10601060
}
10611061

@@ -1064,12 +1064,14 @@ class CodeString: public CHeapObj<mtCode> {
10641064
public:
10651065
CodeString(const char * string, intptr_t offset = -1)
10661066
: _next(NULL), _prev(NULL), _offset(offset) {
1067+
allocated_code_strings++;
10671068
_string = os::strdup(string, mtCode);
1069+
log_trace(codestrings)("Created CodeString [%s] (%p)", _string, (void*)_string);
10681070
}
10691071

10701072
const char * string() const { return _string; }
10711073
intptr_t offset() const { assert(_offset >= 0, "offset for non comment?"); return _offset; }
1072-
CodeString* next() const { return _next; }
1074+
CodeString* next() const { return _next; }
10731075

10741076
void set_next(CodeString* next) {
10751077
_next = next;
@@ -1094,6 +1096,10 @@ class CodeString: public CHeapObj<mtCode> {
10941096
}
10951097
};
10961098

1099+
// For tracing statistics. Will use raw increment/decrement, so it might not be
1100+
// exact
1101+
long CodeString::allocated_code_strings = 0;
1102+
10971103
CodeString* CodeStrings::find(intptr_t offset) const {
10981104
CodeString* a = _strings->first_comment();
10991105
while (a != NULL && a->offset() != offset) {
@@ -1116,7 +1122,7 @@ void CodeStrings::add_comment(intptr_t offset, const char * comment) {
11161122
CodeString* c = new CodeString(comment, offset);
11171123
CodeString* inspos = (_strings == NULL) ? NULL : find_last(offset);
11181124

1119-
if (inspos) {
1125+
if (inspos != NULL) {
11201126
// insert after already existing comments with same offset
11211127
c->set_next(inspos->next());
11221128
inspos->set_next(c);
@@ -1130,29 +1136,22 @@ void CodeStrings::add_comment(intptr_t offset, const char * comment) {
11301136
}
11311137
}
11321138

1133-
void CodeStrings::assign(CodeStrings& other) {
1134-
other.check_valid();
1135-
assert(is_null(), "Cannot assign onto non-empty CodeStrings");
1136-
_strings = other._strings;
1137-
_strings_last = other._strings_last;
1138-
#ifdef ASSERT
1139-
_defunct = false;
1140-
#endif
1141-
other.set_null_and_invalidate();
1142-
}
1143-
11441139
// Deep copy of CodeStrings for consistent memory management.
1145-
// Only used for actual disassembly so this is cheaper than reference counting
1146-
// for the "normal" fastdebug case.
11471140
void CodeStrings::copy(CodeStrings& other) {
1141+
log_debug(codestrings)("Copying %d Codestring(s)", other.count());
1142+
11481143
other.check_valid();
11491144
check_valid();
11501145
assert(is_null(), "Cannot copy onto non-empty CodeStrings");
11511146
CodeString* n = other._strings;
11521147
CodeString** ps = &_strings;
11531148
CodeString* prev = NULL;
11541149
while (n != NULL) {
1155-
*ps = new CodeString(n->string(),n->offset());
1150+
if (n->is_comment()) {
1151+
*ps = new CodeString(n->string(), n->offset());
1152+
} else {
1153+
*ps = new CodeString(n->string());
1154+
}
11561155
(*ps)->_prev = prev;
11571156
prev = *ps;
11581157
ps = &((*ps)->_next);
@@ -1162,13 +1161,6 @@ void CodeStrings::copy(CodeStrings& other) {
11621161

11631162
const char* CodeStrings::_prefix = " ;; "; // default: can be changed via set_prefix
11641163

1165-
// Check if any block comments are pending for the given offset.
1166-
bool CodeStrings::has_block_comment(intptr_t offset) const {
1167-
if (_strings == NULL) return false;
1168-
CodeString* c = find(offset);
1169-
return c != NULL;
1170-
}
1171-
11721164
void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) const {
11731165
check_valid();
11741166
if (_strings != NULL) {
@@ -1184,8 +1176,19 @@ void CodeStrings::print_block_comment(outputStream* stream, intptr_t offset) con
11841176
}
11851177
}
11861178

1187-
// Also sets isNull()
1179+
int CodeStrings::count() const {
1180+
int i = 0;
1181+
CodeString* s = _strings;
1182+
while (s != NULL) {
1183+
i++;
1184+
s = s->_next;
1185+
}
1186+
return i;
1187+
}
1188+
1189+
// Also sets is_null()
11881190
void CodeStrings::free() {
1191+
log_debug(codestrings)("Freeing %d out of approx. %ld CodeString(s), ", count(), CodeString::allocated_code_strings);
11891192
CodeString* n = _strings;
11901193
while (n) {
11911194
// unlink the node from the list saving a pointer to the next
@@ -1215,7 +1218,7 @@ const char* CodeStrings::add_string(const char * string) {
12151218

12161219
void CodeBuffer::decode() {
12171220
ttyLocker ttyl;
1218-
Disassembler::decode(decode_begin(), insts_end(), tty);
1221+
Disassembler::decode(decode_begin(), insts_end(), tty NOT_PRODUCT(COMMA &strings()));
12191222
_decode_begin = insts_end();
12201223
}
12211224

@@ -1246,10 +1249,4 @@ void CodeBuffer::print() {
12461249
}
12471250
}
12481251

1249-
// Directly disassemble code buffer.
1250-
void CodeBuffer::decode(address start, address end) {
1251-
ttyLocker ttyl;
1252-
Disassembler::decode(this, start, end, tty);
1253-
}
1254-
12551252
#endif // PRODUCT

src/hotspot/share/asm/codeBuffer.hpp

Lines changed: 23 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -284,20 +284,18 @@ class CodeStrings {
284284
bool _defunct; // Zero bit pattern is "valid", see memset call in decode_env::decode_env
285285
#endif
286286
static const char* _prefix; // defaults to " ;; "
287-
#endif
288287

289288
CodeString* find(intptr_t offset) const;
290289
CodeString* find_last(intptr_t offset) const;
291290

292291
void set_null_and_invalidate() {
293-
#ifndef PRODUCT
294292
_strings = NULL;
295293
_strings_last = NULL;
296294
#ifdef ASSERT
297295
_defunct = true;
298-
#endif
299296
#endif
300297
}
298+
#endif
301299

302300
public:
303301
CodeStrings() {
@@ -310,6 +308,7 @@ class CodeStrings {
310308
#endif
311309
}
312310

311+
#ifndef PRODUCT
313312
bool is_null() {
314313
#ifdef ASSERT
315314
return _strings == NULL;
@@ -318,30 +317,25 @@ class CodeStrings {
318317
#endif
319318
}
320319

321-
const char* add_string(const char * string) PRODUCT_RETURN_(return NULL;);
320+
const char* add_string(const char * string);
322321

323-
void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
324-
bool has_block_comment(intptr_t offset) const;
325-
void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN;
326-
// MOVE strings from other to this; invalidate other.
327-
void assign(CodeStrings& other) PRODUCT_RETURN;
322+
void add_comment(intptr_t offset, const char * comment);
323+
void print_block_comment(outputStream* stream, intptr_t offset) const;
324+
int count() const;
328325
// COPY strings from other to this; leave other valid.
329-
void copy(CodeStrings& other) PRODUCT_RETURN;
326+
void copy(CodeStrings& other);
330327
// FREE strings; invalidate this.
331-
void free() PRODUCT_RETURN;
328+
void free();
332329

333330
// Guarantee that _strings are used at most once; assign and free invalidate a buffer.
334331
inline void check_valid() const {
335-
#ifdef ASSERT
336332
assert(!_defunct, "Use of invalid CodeStrings");
337-
#endif
338333
}
339334

340335
static void set_prefix(const char *prefix) {
341-
#ifndef PRODUCT
342336
_prefix = prefix;
343-
#endif
344337
}
338+
#endif // !PRODUCT
345339
};
346340

347341
// A CodeBuffer describes a memory space into which assembly
@@ -410,8 +404,7 @@ class CodeBuffer: public StackObj {
410404
csize_t _total_size; // size in bytes of combined memory buffer
411405

412406
OopRecorder* _oop_recorder;
413-
CodeStrings _code_strings;
414-
bool _collect_comments; // Indicate if we need to collect block comments at all.
407+
415408
OopRecorder _default_oop_recorder; // override with initialize_oop_recorder
416409
Arena* _overflow_arena;
417410

@@ -421,8 +414,12 @@ class CodeBuffer: public StackObj {
421414
bool _immutable_PIC;
422415
#endif
423416

424-
address _decode_begin; // start address for decode
417+
#ifndef PRODUCT
418+
CodeStrings _code_strings;
419+
bool _collect_comments; // Indicate if we need to collect block comments at all.
420+
address _decode_begin; // start address for decode
425421
address decode_begin();
422+
#endif
426423

427424
void initialize_misc(const char * name) {
428425
// all pointers other than code_start/end and those inside the sections
@@ -431,14 +428,15 @@ class CodeBuffer: public StackObj {
431428
_before_expand = NULL;
432429
_blob = NULL;
433430
_oop_recorder = NULL;
434-
_decode_begin = NULL;
435431
_overflow_arena = NULL;
436-
_code_strings = CodeStrings();
437432
_last_insn = NULL;
438433
#if INCLUDE_AOT
439434
_immutable_PIC = false;
440435
#endif
441436

437+
#ifndef PRODUCT
438+
_decode_begin = NULL;
439+
_code_strings = CodeStrings();
442440
// Collect block comments, but restrict collection to cases where a disassembly is output.
443441
_collect_comments = ( PrintAssembly
444442
|| PrintStubCode
@@ -447,6 +445,7 @@ class CodeBuffer: public StackObj {
447445
|| PrintSignatureHandlers
448446
|| UnlockDiagnosticVMOptions
449447
);
448+
#endif
450449
}
451450

452451
void initialize(address code_start, csize_t code_size) {
@@ -635,35 +634,27 @@ class CodeBuffer: public StackObj {
635634
// Override default oop recorder.
636635
void initialize_oop_recorder(OopRecorder* r);
637636

638-
OopRecorder* oop_recorder() const { return _oop_recorder; }
639-
CodeStrings& strings() { return _code_strings; }
637+
OopRecorder* oop_recorder() const { return _oop_recorder; }
640638

641639
address last_insn() const { return _last_insn; }
642640
void set_last_insn(address a) { _last_insn = a; }
643641
void clear_last_insn() { set_last_insn(NULL); }
644642

643+
#ifndef PRODUCT
644+
CodeStrings& strings() { return _code_strings; }
645+
645646
void free_strings() {
646647
if (!_code_strings.is_null()) {
647648
_code_strings.free(); // sets _strings Null as a side-effect.
648649
}
649650
}
650651

651-
// Directly disassemble code buffer.
652652
// Print the comment associated with offset on stream, if there is one.
653653
virtual void print_block_comment(outputStream* stream, address block_begin) {
654-
#ifndef PRODUCT
655654
intptr_t offset = (intptr_t)(block_begin - _total_start); // I assume total_start is not correct for all code sections.
656655
_code_strings.print_block_comment(stream, offset);
657-
#endif
658656
}
659-
bool has_block_comment(address block_begin) {
660-
#ifndef PRODUCT
661-
intptr_t offset = (intptr_t)(block_begin - _total_start); // I assume total_start is not correct for all code sections.
662-
return _code_strings.has_block_comment(offset);
663-
#else
664-
return false;
665657
#endif
666-
}
667658

668659
// Code generation
669660
void relocate(address at, RelocationHolder const& rspec, int format = 0) {

src/hotspot/share/code/codeBlob.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& la
8787
_relocation_end(layout.relocation_end()),
8888
_oop_maps(oop_maps),
8989
_caller_must_gc_arguments(caller_must_gc_arguments),
90-
_strings(CodeStrings()),
9190
_name(name)
91+
NOT_PRODUCT(COMMA _strings(CodeStrings()))
9292
{
9393
assert(is_aligned(layout.size(), oopSize), "unaligned size");
9494
assert(is_aligned(layout.header_size(), oopSize), "unaligned size");
@@ -115,8 +115,8 @@ CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& la
115115
_relocation_begin(layout.relocation_begin()),
116116
_relocation_end(layout.relocation_end()),
117117
_caller_must_gc_arguments(caller_must_gc_arguments),
118-
_strings(CodeStrings()),
119118
_name(name)
119+
NOT_PRODUCT(COMMA _strings(CodeStrings()))
120120
{
121121
assert(is_aligned(_size, oopSize), "unaligned size");
122122
assert(is_aligned(_header_size, oopSize), "unaligned size");
@@ -158,7 +158,7 @@ RuntimeBlob::RuntimeBlob(
158158
void CodeBlob::flush() {
159159
FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);
160160
_oop_maps = NULL;
161-
_strings.free();
161+
NOT_PRODUCT(_strings.free();)
162162
}
163163

164164
void CodeBlob::set_oop_maps(OopMapSet* p) {

0 commit comments

Comments
 (0)