Skip to content

Commit 7bd4f49

Browse files
author
Patric Hedlin
committed
8264207: CodeStrings does not honour fixed address assumption.
Reviewed-by: redestad, neliasso
1 parent 2cabec8 commit 7bd4f49

File tree

16 files changed

+763
-355
lines changed

16 files changed

+763
-355
lines changed

src/hotspot/share/asm/codeBuffer.cpp

Lines changed: 293 additions & 182 deletions
Large diffs are not rendered by default.

src/hotspot/share/asm/codeBuffer.hpp

Lines changed: 76 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
#include "utilities/debug.hpp"
3232
#include "utilities/macros.hpp"
3333

34-
class CodeStrings;
3534
class PhaseCFG;
3635
class Compile;
3736
class BufferBlob;
@@ -273,70 +272,75 @@ class CodeSection {
273272
#endif //PRODUCT
274273
};
275274

276-
class CodeString;
277-
class CodeStrings {
278-
private:
275+
279276
#ifndef PRODUCT
280-
CodeString* _strings;
281-
CodeString* _strings_last;
282-
#ifdef ASSERT
283-
// Becomes true after copy-out, forbids further use.
284-
bool _defunct; // Zero bit pattern is "valid", see memset call in decode_env::decode_env
285-
#endif
286-
static const char* _prefix; // defaults to " ;; "
287277

288-
CodeString* find(intptr_t offset) const;
289-
CodeString* find_last(intptr_t offset) const;
278+
class AsmRemarkCollection;
279+
class DbgStringCollection;
290280

291-
void set_null_and_invalidate() {
292-
_strings = NULL;
293-
_strings_last = NULL;
294-
#ifdef ASSERT
295-
_defunct = true;
296-
#endif
297-
}
298-
#endif
281+
// The assumption made here is that most code remarks (or comments) added to
282+
// the generated assembly code are unique, i.e. there is very little gain in
283+
// trying to share the strings between the different offsets tracked in a
284+
// buffer (or blob).
299285

300-
public:
301-
CodeStrings() {
302-
#ifndef PRODUCT
303-
_strings = NULL;
304-
_strings_last = NULL;
305-
#ifdef ASSERT
306-
_defunct = false;
307-
#endif
308-
#endif
309-
}
286+
class AsmRemarks {
287+
public:
288+
AsmRemarks();
289+
~AsmRemarks();
310290

311-
#ifndef PRODUCT
312-
bool is_null() {
313-
#ifdef ASSERT
314-
return _strings == NULL;
315-
#else
316-
return true;
317-
#endif
318-
}
291+
const char* insert(uint offset, const char* remstr);
319292

320-
const char* add_string(const char * string);
293+
bool is_empty() const;
321294

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;
325-
// COPY strings from other to this; leave other valid.
326-
void copy(CodeStrings& other);
327-
// FREE strings; invalidate this.
328-
void free();
295+
void share(const AsmRemarks &src);
296+
void clear();
297+
uint print(uint offset, outputStream* strm = tty) const;
329298

330-
// Guarantee that _strings are used at most once; assign and free invalidate a buffer.
331-
inline void check_valid() const {
332-
assert(!_defunct, "Use of invalid CodeStrings");
333-
}
299+
// For testing purposes only.
300+
const AsmRemarkCollection* ref() const { return _remarks; }
334301

335-
static void set_prefix(const char *prefix) {
336-
_prefix = prefix;
302+
private:
303+
AsmRemarkCollection* _remarks;
304+
};
305+
306+
// The assumption made here is that the number of debug strings (with a fixed
307+
// address requirement) is a rather small set per compilation unit.
308+
309+
class DbgStrings {
310+
public:
311+
DbgStrings();
312+
~DbgStrings();
313+
314+
const char* insert(const char* dbgstr);
315+
316+
bool is_empty() const;
317+
318+
void share(const DbgStrings &src);
319+
void clear();
320+
321+
// For testing purposes only.
322+
const DbgStringCollection* ref() const { return _strings; }
323+
324+
private:
325+
DbgStringCollection* _strings;
326+
};
327+
#endif // not PRODUCT
328+
329+
330+
#ifdef ASSERT
331+
#include "utilities/copy.hpp"
332+
333+
class Scrubber {
334+
public:
335+
Scrubber(void* addr, size_t size) : _addr(addr), _size(size) {}
336+
~Scrubber() {
337+
Copy::fill_to_bytes(_addr, _size, badResourceValue);
337338
}
338-
#endif // !PRODUCT
339+
private:
340+
void* _addr;
341+
size_t _size;
339342
};
343+
#endif // ASSERT
340344

341345
// A CodeBuffer describes a memory space into which assembly
342346
// code is generated. This memory space usually occupies the
@@ -362,7 +366,7 @@ class CodeStrings {
362366
// Instructions and data in one section can contain relocatable references to
363367
// addresses in a sibling section.
364368

365-
class CodeBuffer: public StackObj {
369+
class CodeBuffer: public StackObj DEBUG_ONLY(COMMA private Scrubber) {
366370
friend class CodeSection;
367371
friend class StubCodeGenerator;
368372

@@ -411,7 +415,8 @@ class CodeBuffer: public StackObj {
411415
address _last_insn; // used to merge consecutive memory barriers, loads or stores.
412416

413417
#ifndef PRODUCT
414-
CodeStrings _code_strings;
418+
AsmRemarks _asm_remarks;
419+
DbgStrings _dbg_strings;
415420
bool _collect_comments; // Indicate if we need to collect block comments at all.
416421
address _decode_begin; // start address for decode
417422
address decode_begin();
@@ -429,7 +434,6 @@ class CodeBuffer: public StackObj {
429434

430435
#ifndef PRODUCT
431436
_decode_begin = NULL;
432-
_code_strings = CodeStrings();
433437
// Collect block comments, but restrict collection to cases where a disassembly is output.
434438
_collect_comments = ( PrintAssembly
435439
|| PrintStubCode
@@ -484,7 +488,9 @@ class CodeBuffer: public StackObj {
484488

485489
public:
486490
// (1) code buffer referring to pre-allocated instruction memory
487-
CodeBuffer(address code_start, csize_t code_size) {
491+
CodeBuffer(address code_start, csize_t code_size)
492+
DEBUG_ONLY(: Scrubber(this, sizeof(*this)))
493+
{
488494
assert(code_start != NULL, "sanity");
489495
initialize_misc("static buffer");
490496
initialize(code_start, code_size);
@@ -497,14 +503,18 @@ class CodeBuffer: public StackObj {
497503
// (3) code buffer allocating codeBlob memory for code & relocation
498504
// info but with lazy initialization. The name must be something
499505
// informative.
500-
CodeBuffer(const char* name) {
506+
CodeBuffer(const char* name)
507+
DEBUG_ONLY(: Scrubber(this, sizeof(*this)))
508+
{
501509
initialize_misc(name);
502510
}
503511

504512
// (4) code buffer allocating codeBlob memory for code & relocation
505513
// info. The name must be something informative and code_size must
506514
// include both code and stubs sizes.
507-
CodeBuffer(const char* name, csize_t code_size, csize_t locs_size) {
515+
CodeBuffer(const char* name, csize_t code_size, csize_t locs_size)
516+
DEBUG_ONLY(: Scrubber(this, sizeof(*this)))
517+
{
508518
initialize_misc(name);
509519
initialize(code_size, locs_size);
510520
}
@@ -634,12 +644,12 @@ class CodeBuffer: public StackObj {
634644
void clear_last_insn() { set_last_insn(NULL); }
635645

636646
#ifndef PRODUCT
637-
CodeStrings& strings() { return _code_strings; }
647+
AsmRemarks &asm_remarks() { return _asm_remarks; }
648+
DbgStrings &dbg_strings() { return _dbg_strings; }
638649

639-
void free_strings() {
640-
if (!_code_strings.is_null()) {
641-
_code_strings.free(); // sets _strings Null as a side-effect.
642-
}
650+
void clear_strings() {
651+
_asm_remarks.clear();
652+
_dbg_strings.clear();
643653
}
644654
#endif
645655

@@ -666,7 +676,7 @@ class CodeBuffer: public StackObj {
666676
}
667677
}
668678

669-
void block_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
679+
void block_comment(ptrdiff_t offset, const char* comment) PRODUCT_RETURN;
670680
const char* code_string(const char* str) PRODUCT_RETURN_(return NULL;);
671681

672682
// Log a little info about section usage in the CodeBuffer

src/hotspot/share/code/codeBlob.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& la
9494
_oop_maps(oop_maps),
9595
_caller_must_gc_arguments(caller_must_gc_arguments),
9696
_name(name)
97-
NOT_PRODUCT(COMMA _strings(CodeStrings()))
9897
{
9998
assert(is_aligned(layout.size(), oopSize), "unaligned size");
10099
assert(is_aligned(layout.header_size(), oopSize), "unaligned size");
@@ -107,7 +106,7 @@ CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& la
107106
S390_ONLY(_ctable_offset = 0;) // avoid uninitialized fields
108107
}
109108

110-
CodeBlob::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) :
109+
CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, CodeBuffer* cb /*UNUSED*/, int frame_complete_offset, int frame_size, OopMapSet* oop_maps, bool caller_must_gc_arguments) :
111110
_type(type),
112111
_size(layout.size()),
113112
_header_size(layout.header_size()),
@@ -122,7 +121,6 @@ CodeBlob::CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& la
122121
_relocation_end(layout.relocation_end()),
123122
_caller_must_gc_arguments(caller_must_gc_arguments),
124123
_name(name)
125-
NOT_PRODUCT(COMMA _strings(CodeStrings()))
126124
{
127125
assert(is_aligned(_size, oopSize), "unaligned size");
128126
assert(is_aligned(_header_size, oopSize), "unaligned size");
@@ -164,7 +162,8 @@ RuntimeBlob::RuntimeBlob(
164162
void CodeBlob::flush() {
165163
FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);
166164
_oop_maps = NULL;
167-
NOT_PRODUCT(_strings.free();)
165+
NOT_PRODUCT(_asm_remarks.clear());
166+
NOT_PRODUCT(_dbg_strings.clear());
168167
}
169168

170169
void CodeBlob::set_oop_maps(OopMapSet* p) {
@@ -190,7 +189,8 @@ void RuntimeBlob::trace_new_stub(RuntimeBlob* stub, const char* name1, const cha
190189
ttyLocker ttyl;
191190
tty->print_cr("- - - [BEGIN] - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
192191
tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, (intptr_t) stub);
193-
Disassembler::decode(stub->code_begin(), stub->code_end(), tty);
192+
Disassembler::decode(stub->code_begin(), stub->code_end(), tty
193+
NOT_PRODUCT(COMMA &stub->asm_remarks()));
194194
if ((stub->oop_maps() != NULL) && AbstractDisassembler::show_structs()) {
195195
tty->print_cr("- - - [OOP MAPS]- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -");
196196
stub->oop_maps()->print();

src/hotspot/share/code/codeBlob.hpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,22 @@ class CodeBlob {
112112
const char* _name;
113113
S390_ONLY(int _ctable_offset;)
114114

115-
NOT_PRODUCT(CodeStrings _strings;)
115+
#ifndef PRODUCT
116+
AsmRemarks _asm_remarks;
117+
DbgStrings _dbg_strings;
118+
119+
~CodeBlob() {
120+
_asm_remarks.clear();
121+
_dbg_strings.clear();
122+
}
123+
#endif // not PRODUCT
116124

117125
CodeBlob(const char* name, CompilerType type, const CodeBlobLayout& layout, int frame_complete_offset, int frame_size, ImmutableOopMapSet* oop_maps, bool caller_must_gc_arguments);
118126
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);
119127

120128
public:
121129
// Only used by unit test.
122-
CodeBlob()
123-
: _type(compiler_none) {}
130+
CodeBlob() : _type(compiler_none) {}
124131

125132
// Returns the space needed for CodeBlob
126133
static unsigned int allocation_size(CodeBuffer* cb, int header_size);
@@ -232,18 +239,21 @@ class CodeBlob {
232239
void dump_for_addr(address addr, outputStream* st, bool verbose) const;
233240
void print_code();
234241

235-
// Print the comment associated with offset on stream, if there is one
242+
// Print to stream, any comments associated with offset.
236243
virtual void print_block_comment(outputStream* stream, address block_begin) const {
237-
#ifndef PRODUCT
238-
intptr_t offset = (intptr_t)(block_begin - code_begin());
239-
_strings.print_block_comment(stream, offset);
240-
#endif
244+
#ifndef PRODUCT
245+
ptrdiff_t offset = block_begin - code_begin();
246+
assert(offset >= 0, "Expecting non-negative offset!");
247+
_asm_remarks.print(uint(offset), stream);
248+
#endif
241249
}
242250

243251
#ifndef PRODUCT
244-
void set_strings(CodeStrings& strings) {
245-
_strings.copy(strings);
246-
}
252+
AsmRemarks &asm_remarks() { return _asm_remarks; }
253+
DbgStrings &dbg_strings() { return _dbg_strings; }
254+
255+
void use_remarks(AsmRemarks &remarks) { _asm_remarks.share(remarks); }
256+
void use_strings(DbgStrings &strings) { _dbg_strings.share(strings); }
247257
#endif
248258
};
249259

src/hotspot/share/code/icBuffer.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,7 @@ class ICStub: public Stub {
5656
protected:
5757
friend class ICStubInterface;
5858
// This will be called only by ICStubInterface
59-
void initialize(int size,
60-
CodeStrings strings) { _size = size; _ic_site = NULL; }
59+
void initialize(int size) { _size = size; _ic_site = NULL; }
6160
void finalize(); // called when a method is removed
6261

6362
// General info

src/hotspot/share/code/stubs.cpp

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,7 @@ Stub* StubQueue::stub_containing(address pc) const {
109109

110110
Stub* StubQueue::request_committed(int code_size) {
111111
Stub* s = request(code_size);
112-
CodeStrings strings;
113-
if (s != NULL) commit(code_size, strings);
112+
if (s != NULL) commit(code_size);
114113
return s;
115114
}
116115

@@ -127,8 +126,7 @@ Stub* StubQueue::request(int requested_code_size) {
127126
assert(_buffer_limit == _buffer_size, "buffer must be fully usable");
128127
if (_queue_end + requested_size <= _buffer_size) {
129128
// code fits in at the end => nothing to do
130-
CodeStrings strings;
131-
stub_initialize(s, requested_size, strings);
129+
stub_initialize(s, requested_size);
132130
return s;
133131
} else {
134132
// stub doesn't fit in at the queue end
@@ -145,8 +143,7 @@ Stub* StubQueue::request(int requested_code_size) {
145143
// Queue: |XXX|.......|XXXXXXX|.......|
146144
// ^0 ^end ^begin ^limit ^size
147145
s = current_stub();
148-
CodeStrings strings;
149-
stub_initialize(s, requested_size, strings);
146+
stub_initialize(s, requested_size);
150147
return s;
151148
}
152149
// Not enough space left
@@ -155,12 +152,12 @@ Stub* StubQueue::request(int requested_code_size) {
155152
}
156153

157154

158-
void StubQueue::commit(int committed_code_size, CodeStrings& strings) {
155+
void StubQueue::commit(int committed_code_size) {
159156
assert(committed_code_size > 0, "committed_code_size must be > 0");
160157
int committed_size = align_up(stub_code_size_to_size(committed_code_size), CodeEntryAlignment);
161158
Stub* s = current_stub();
162159
assert(committed_size <= stub_size(s), "committed size must not exceed requested size");
163-
stub_initialize(s, committed_size, strings);
160+
stub_initialize(s, committed_size);
164161
_queue_end += committed_size;
165162
_number_of_stubs++;
166163
if (_mutex != NULL) _mutex->unlock();

0 commit comments

Comments
 (0)