Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/compiler/disassembler.cpp
32285 views
1
/*
2
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#include "precompiled.hpp"
26
#include "classfile/javaClasses.hpp"
27
#include "code/codeCache.hpp"
28
#include "compiler/disassembler.hpp"
29
#include "gc_interface/collectedHeap.hpp"
30
#include "memory/cardTableModRefBS.hpp"
31
#include "runtime/fprofiler.hpp"
32
#include "runtime/handles.inline.hpp"
33
#include "runtime/stubCodeGenerator.hpp"
34
#include "runtime/stubRoutines.hpp"
35
#ifdef TARGET_ARCH_x86
36
# include "depChecker_x86.hpp"
37
#endif
38
#ifdef TARGET_ARCH_aarch32
39
# include "depChecker_aarch32.hpp"
40
#endif
41
#ifdef TARGET_ARCH_aarch64
42
# include "depChecker_aarch64.hpp"
43
#endif
44
#ifdef TARGET_ARCH_sparc
45
# include "depChecker_sparc.hpp"
46
#endif
47
#ifdef TARGET_ARCH_zero
48
# include "depChecker_zero.hpp"
49
#endif
50
#ifdef TARGET_ARCH_arm
51
# include "depChecker_arm.hpp"
52
#endif
53
#ifdef TARGET_ARCH_ppc
54
# include "depChecker_ppc.hpp"
55
#endif
56
#ifdef SHARK
57
#include "shark/sharkEntry.hpp"
58
#endif
59
60
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
61
62
void* Disassembler::_library = NULL;
63
bool Disassembler::_tried_to_load_library = false;
64
65
// This routine is in the shared library:
66
Disassembler::decode_func_virtual Disassembler::_decode_instructions_virtual = NULL;
67
Disassembler::decode_func Disassembler::_decode_instructions = NULL;
68
69
static const char hsdis_library_name[] = "hsdis-" HOTSPOT_LIB_ARCH;
70
static const char decode_instructions_virtual_name[] = "decode_instructions_virtual";
71
static const char decode_instructions_name[] = "decode_instructions";
72
static bool use_new_version = true;
73
#define COMMENT_COLUMN 40 LP64_ONLY(+8) /*could be an option*/
74
#define BYTES_COMMENT ";..." /* funky byte display comment */
75
76
bool Disassembler::load_library() {
77
if (_decode_instructions_virtual != NULL || _decode_instructions != NULL) {
78
// Already succeeded.
79
return true;
80
}
81
if (_tried_to_load_library) {
82
// Do not try twice.
83
// To force retry in debugger: assign _tried_to_load_library=0
84
return false;
85
}
86
// Try to load it.
87
char ebuf[1024];
88
char buf[JVM_MAXPATHLEN];
89
os::jvm_path(buf, sizeof(buf));
90
int jvm_offset = -1;
91
int lib_offset = -1;
92
{
93
// Match "jvm[^/]*" in jvm_path.
94
const char* base = buf;
95
const char* p = strrchr(buf, '/');
96
if (p != NULL) lib_offset = p - base + 1;
97
p = strstr(p ? p : base, "jvm");
98
if (p != NULL) jvm_offset = p - base;
99
}
100
// Find the disassembler shared library.
101
// Search for several paths derived from libjvm, in this order:
102
// 1. <home>/jre/lib/<arch>/<vm>/libhsdis-<arch>.so (for compatibility)
103
// 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so
104
// 3. <home>/jre/lib/<arch>/hsdis-<arch>.so
105
// 4. hsdis-<arch>.so (using LD_LIBRARY_PATH)
106
if (jvm_offset >= 0) {
107
// 1. <home>/jre/lib/<arch>/<vm>/libhsdis-<arch>.so
108
strcpy(&buf[jvm_offset], hsdis_library_name);
109
strcat(&buf[jvm_offset], os::dll_file_extension());
110
_library = os::dll_load(buf, ebuf, sizeof ebuf);
111
if (_library == NULL) {
112
// 2. <home>/jre/lib/<arch>/<vm>/hsdis-<arch>.so
113
strcpy(&buf[lib_offset], hsdis_library_name);
114
strcat(&buf[lib_offset], os::dll_file_extension());
115
_library = os::dll_load(buf, ebuf, sizeof ebuf);
116
}
117
if (_library == NULL) {
118
// 3. <home>/jre/lib/<arch>/hsdis-<arch>.so
119
buf[lib_offset - 1] = '\0';
120
const char* p = strrchr(buf, '/');
121
if (p != NULL) {
122
lib_offset = p - buf + 1;
123
strcpy(&buf[lib_offset], hsdis_library_name);
124
strcat(&buf[lib_offset], os::dll_file_extension());
125
_library = os::dll_load(buf, ebuf, sizeof ebuf);
126
}
127
}
128
}
129
if (_library == NULL) {
130
// 4. hsdis-<arch>.so (using LD_LIBRARY_PATH)
131
strcpy(&buf[0], hsdis_library_name);
132
strcat(&buf[0], os::dll_file_extension());
133
_library = os::dll_load(buf, ebuf, sizeof ebuf);
134
}
135
if (_library != NULL) {
136
_decode_instructions_virtual = CAST_TO_FN_PTR(Disassembler::decode_func_virtual,
137
os::dll_lookup(_library, decode_instructions_virtual_name));
138
}
139
if (_decode_instructions_virtual == NULL) {
140
// could not spot in new version, try old version
141
_decode_instructions = CAST_TO_FN_PTR(Disassembler::decode_func,
142
os::dll_lookup(_library, decode_instructions_name));
143
use_new_version = false;
144
} else {
145
use_new_version = true;
146
}
147
_tried_to_load_library = true;
148
if (_decode_instructions_virtual == NULL && _decode_instructions == NULL) {
149
tty->print_cr("Could not load %s; %s; %s", buf,
150
((_library != NULL)
151
? "entry point is missing"
152
: (WizardMode || PrintMiscellaneous)
153
? (const char*)ebuf
154
: "library not loadable"),
155
"PrintAssembly is disabled");
156
return false;
157
}
158
159
// Success.
160
tty->print_cr("Loaded disassembler from %s", buf);
161
return true;
162
}
163
164
165
class decode_env {
166
private:
167
nmethod* _nm;
168
CodeBlob* _code;
169
CodeStrings _strings;
170
outputStream* _output;
171
address _start, _end;
172
173
char _option_buf[512];
174
char _print_raw;
175
bool _print_pc;
176
bool _print_bytes;
177
address _cur_insn;
178
int _total_ticks;
179
int _bytes_per_line; // arch-specific formatting option
180
181
static bool match(const char* event, const char* tag) {
182
size_t taglen = strlen(tag);
183
if (strncmp(event, tag, taglen) != 0)
184
return false;
185
char delim = event[taglen];
186
return delim == '\0' || delim == ' ' || delim == '/' || delim == '=';
187
}
188
189
void collect_options(const char* p) {
190
if (p == NULL || p[0] == '\0') return;
191
size_t opt_so_far = strlen(_option_buf);
192
if (opt_so_far + 1 + strlen(p) + 1 > sizeof(_option_buf)) return;
193
char* fillp = &_option_buf[opt_so_far];
194
if (opt_so_far > 0) *fillp++ = ',';
195
strcat(fillp, p);
196
// replace white space by commas:
197
char* q = fillp;
198
while ((q = strpbrk(q, " \t\n")) != NULL)
199
*q++ = ',';
200
// Note that multiple PrintAssemblyOptions flags accumulate with \n,
201
// which we want to be changed to a comma...
202
}
203
204
void print_insn_labels();
205
void print_insn_bytes(address pc0, address pc);
206
void print_address(address value);
207
208
public:
209
decode_env(CodeBlob* code, outputStream* output, CodeStrings c = CodeStrings());
210
211
address decode_instructions(address start, address end);
212
213
void start_insn(address pc) {
214
_cur_insn = pc;
215
output()->bol();
216
print_insn_labels();
217
}
218
219
void end_insn(address pc) {
220
address pc0 = cur_insn();
221
outputStream* st = output();
222
if (_print_bytes && pc > pc0)
223
print_insn_bytes(pc0, pc);
224
if (_nm != NULL) {
225
_nm->print_code_comment_on(st, COMMENT_COLUMN, pc0, pc);
226
// this calls reloc_string_for which calls oop::print_value_on
227
}
228
229
// Output pc bucket ticks if we have any
230
if (total_ticks() != 0) {
231
address bucket_pc = FlatProfiler::bucket_start_for(pc);
232
if (bucket_pc != NULL && bucket_pc > pc0 && bucket_pc <= pc) {
233
int bucket_count = FlatProfiler::bucket_count_for(pc0);
234
if (bucket_count != 0) {
235
st->bol();
236
st->print_cr("%3.1f%% [%d]", bucket_count*100.0/total_ticks(), bucket_count);
237
}
238
}
239
}
240
// follow each complete insn by a nice newline
241
st->cr();
242
}
243
244
address handle_event(const char* event, address arg);
245
246
outputStream* output() { return _output; }
247
address cur_insn() { return _cur_insn; }
248
int total_ticks() { return _total_ticks; }
249
void set_total_ticks(int n) { _total_ticks = n; }
250
const char* options() { return _option_buf; }
251
};
252
253
decode_env::decode_env(CodeBlob* code, outputStream* output, CodeStrings c) :
254
_nm((code != NULL && code->is_nmethod()) ? (nmethod*)code : NULL),
255
_code(code),
256
_strings(),
257
_output(output ? output : tty),
258
_start(NULL),
259
_end(NULL),
260
_print_raw(0),
261
// by default, output pc but not bytes:
262
_print_pc(true),
263
_print_bytes(false),
264
_cur_insn(NULL),
265
_total_ticks(0),
266
_bytes_per_line(Disassembler::pd_instruction_alignment())
267
{
268
memset(_option_buf, 0, sizeof(_option_buf));
269
_strings.copy(c);
270
271
// parse the global option string:
272
collect_options(Disassembler::pd_cpu_opts());
273
collect_options(PrintAssemblyOptions);
274
275
if (strstr(options(), "hsdis-")) {
276
if (strstr(options(), "hsdis-print-raw"))
277
_print_raw = (strstr(options(), "xml") ? 2 : 1);
278
if (strstr(options(), "hsdis-print-pc"))
279
_print_pc = !_print_pc;
280
if (strstr(options(), "hsdis-print-bytes"))
281
_print_bytes = !_print_bytes;
282
}
283
if (strstr(options(), "help")) {
284
tty->print_cr("PrintAssemblyOptions help:");
285
tty->print_cr(" hsdis-print-raw test plugin by requesting raw output");
286
tty->print_cr(" hsdis-print-raw-xml test plugin by requesting raw xml");
287
tty->print_cr(" hsdis-print-pc turn off PC printing (on by default)");
288
tty->print_cr(" hsdis-print-bytes turn on instruction byte output");
289
tty->print_cr("combined options: %s", options());
290
}
291
}
292
293
address decode_env::handle_event(const char* event, address arg) {
294
if (match(event, "insn")) {
295
start_insn(arg);
296
} else if (match(event, "/insn")) {
297
end_insn(arg);
298
} else if (match(event, "addr")) {
299
if (arg != NULL) {
300
print_address(arg);
301
return arg;
302
}
303
} else if (match(event, "mach")) {
304
static char buffer[32] = { 0, };
305
if (strcmp(buffer, (const char*)arg) != 0 ||
306
strlen((const char*)arg) > sizeof(buffer) - 1) {
307
// Only print this when the mach changes
308
strncpy(buffer, (const char*)arg, sizeof(buffer) - 1);
309
buffer[sizeof(buffer) - 1] = '\0';
310
output()->print_cr("[Disassembling for mach='%s']", arg);
311
}
312
} else if (match(event, "format bytes-per-line")) {
313
_bytes_per_line = (int) (intptr_t) arg;
314
} else {
315
// ignore unrecognized markup
316
}
317
return NULL;
318
}
319
320
// called by the disassembler to print out jump targets and data addresses
321
void decode_env::print_address(address adr) {
322
outputStream* st = _output;
323
324
if (adr == NULL) {
325
st->print("NULL");
326
return;
327
}
328
329
int small_num = (int)(intptr_t)adr;
330
if ((intptr_t)adr == (intptr_t)small_num
331
&& -1 <= small_num && small_num <= 9) {
332
st->print("%d", small_num);
333
return;
334
}
335
336
if (Universe::is_fully_initialized()) {
337
if (StubRoutines::contains(adr)) {
338
StubCodeDesc* desc = StubCodeDesc::desc_for(adr);
339
if (desc == NULL)
340
desc = StubCodeDesc::desc_for(adr + frame::pc_return_offset);
341
if (desc != NULL) {
342
st->print("Stub::%s", desc->name());
343
if (desc->begin() != adr)
344
st->print("%+d 0x%p",adr - desc->begin(), adr);
345
else if (WizardMode) st->print(" " PTR_FORMAT, adr);
346
return;
347
}
348
st->print("Stub::<unknown> " PTR_FORMAT, adr);
349
return;
350
}
351
352
BarrierSet* bs = Universe::heap()->barrier_set();
353
if (bs->kind() == BarrierSet::CardTableModRef &&
354
adr == (address)((CardTableModRefBS*)(bs))->byte_map_base) {
355
st->print("word_map_base");
356
if (WizardMode) st->print(" " INTPTR_FORMAT, (intptr_t)adr);
357
return;
358
}
359
360
oop obj;
361
if (_nm != NULL
362
&& (obj = _nm->embeddedOop_at(cur_insn())) != NULL
363
&& (address) obj == adr
364
&& Universe::heap()->is_in(obj)
365
&& Universe::heap()->is_in(obj->klass())) {
366
julong c = st->count();
367
obj->print_value_on(st);
368
if (st->count() == c) {
369
// No output. (Can happen in product builds.)
370
st->print("(a %s)", obj->klass()->external_name());
371
}
372
return;
373
}
374
}
375
376
// Fall through to a simple (hexadecimal) numeral.
377
st->print(PTR_FORMAT, adr);
378
}
379
380
void decode_env::print_insn_labels() {
381
address p = cur_insn();
382
outputStream* st = output();
383
CodeBlob* cb = _code;
384
if (cb != NULL) {
385
cb->print_block_comment(st, p);
386
}
387
_strings.print_block_comment(st, (intptr_t)(p - _start));
388
if (_print_pc) {
389
st->print(" " PTR_FORMAT ": ", p);
390
}
391
}
392
393
void decode_env::print_insn_bytes(address pc, address pc_limit) {
394
outputStream* st = output();
395
size_t incr = 1;
396
size_t perline = _bytes_per_line;
397
if ((size_t) Disassembler::pd_instruction_alignment() >= sizeof(int)
398
&& !((uintptr_t)pc % sizeof(int))
399
&& !((uintptr_t)pc_limit % sizeof(int))) {
400
incr = sizeof(int);
401
if (perline % incr) perline += incr - (perline % incr);
402
}
403
while (pc < pc_limit) {
404
// tab to the desired column:
405
st->move_to(COMMENT_COLUMN);
406
address pc0 = pc;
407
address pc1 = pc + perline;
408
if (pc1 > pc_limit) pc1 = pc_limit;
409
for (; pc < pc1; pc += incr) {
410
if (pc == pc0)
411
st->print(BYTES_COMMENT);
412
else if ((uint)(pc - pc0) % sizeof(int) == 0)
413
st->print(" "); // put out a space on word boundaries
414
if (incr == sizeof(int))
415
st->print("%08lx", *(int*)pc);
416
else st->print("%02x", (*pc)&0xFF);
417
}
418
st->cr();
419
}
420
}
421
422
423
static void* event_to_env(void* env_pv, const char* event, void* arg) {
424
decode_env* env = (decode_env*) env_pv;
425
return env->handle_event(event, (address) arg);
426
}
427
428
ATTRIBUTE_PRINTF(2, 3)
429
static int printf_to_env(void* env_pv, const char* format, ...) {
430
decode_env* env = (decode_env*) env_pv;
431
outputStream* st = env->output();
432
size_t flen = strlen(format);
433
const char* raw = NULL;
434
if (flen == 0) return 0;
435
if (flen == 1 && format[0] == '\n') { st->bol(); return 1; }
436
if (flen < 2 ||
437
strchr(format, '%') == NULL) {
438
raw = format;
439
} else if (format[0] == '%' && format[1] == '%' &&
440
strchr(format+2, '%') == NULL) {
441
// happens a lot on machines with names like %foo
442
flen--;
443
raw = format+1;
444
}
445
if (raw != NULL) {
446
st->print_raw(raw, (int) flen);
447
return (int) flen;
448
}
449
va_list ap;
450
va_start(ap, format);
451
julong cnt0 = st->count();
452
st->vprint(format, ap);
453
julong cnt1 = st->count();
454
va_end(ap);
455
return (int)(cnt1 - cnt0);
456
}
457
458
address decode_env::decode_instructions(address start, address end) {
459
_start = start; _end = end;
460
461
assert(((((intptr_t)start | (intptr_t)end) % Disassembler::pd_instruction_alignment()) == 0), "misaligned insn addr");
462
463
const int show_bytes = false; // for disassembler debugging
464
465
//_version = Disassembler::pd_cpu_version();
466
467
if (!Disassembler::can_decode()) {
468
return NULL;
469
}
470
471
// decode a series of instructions and return the end of the last instruction
472
473
if (_print_raw) {
474
// Print whatever the library wants to print, w/o fancy callbacks.
475
// This is mainly for debugging the library itself.
476
FILE* out = stdout;
477
FILE* xmlout = (_print_raw > 1 ? out : NULL);
478
return use_new_version ?
479
(address)
480
(*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end,
481
start, end - start,
482
NULL, (void*) xmlout,
483
NULL, (void*) out,
484
options(), 0/*nice new line*/)
485
:
486
(address)
487
(*Disassembler::_decode_instructions)(start, end,
488
NULL, (void*) xmlout,
489
NULL, (void*) out,
490
options());
491
}
492
493
return use_new_version ?
494
(address)
495
(*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end,
496
start, end - start,
497
&event_to_env, (void*) this,
498
&printf_to_env, (void*) this,
499
options(), 0/*nice new line*/)
500
:
501
(address)
502
(*Disassembler::_decode_instructions)(start, end,
503
&event_to_env, (void*) this,
504
&printf_to_env, (void*) this,
505
options());
506
}
507
508
509
void Disassembler::decode(CodeBlob* cb, outputStream* st) {
510
ttyLocker ttyl;
511
if (!load_library()) return;
512
decode_env env(cb, st);
513
env.output()->print_cr("Decoding CodeBlob " PTR_FORMAT, cb);
514
env.decode_instructions(cb->code_begin(), cb->code_end());
515
}
516
517
void Disassembler::decode(address start, address end, outputStream* st, CodeStrings c) {
518
ttyLocker ttyl;
519
if (!load_library()) return;
520
decode_env env(CodeCache::find_blob_unsafe(start), st, c);
521
env.decode_instructions(start, end);
522
}
523
524
void Disassembler::decode(nmethod* nm, outputStream* st) {
525
ttyLocker ttyl;
526
if (!load_library()) return;
527
decode_env env(nm, st);
528
env.output()->print_cr("Decoding compiled method " PTR_FORMAT ":", nm);
529
env.output()->print_cr("Code:");
530
531
#ifdef SHARK
532
SharkEntry* entry = (SharkEntry *) nm->code_begin();
533
unsigned char* p = entry->code_start();
534
unsigned char* end = entry->code_limit();
535
#else
536
unsigned char* p = nm->code_begin();
537
unsigned char* end = nm->code_end();
538
#endif // SHARK
539
540
// If there has been profiling, print the buckets.
541
if (FlatProfiler::bucket_start_for(p) != NULL) {
542
unsigned char* p1 = p;
543
int total_bucket_count = 0;
544
while (p1 < end) {
545
unsigned char* p0 = p1;
546
p1 += pd_instruction_alignment();
547
address bucket_pc = FlatProfiler::bucket_start_for(p1);
548
if (bucket_pc != NULL && bucket_pc > p0 && bucket_pc <= p1)
549
total_bucket_count += FlatProfiler::bucket_count_for(p0);
550
}
551
env.set_total_ticks(total_bucket_count);
552
}
553
554
// Print constant table.
555
if (nm->consts_size() > 0) {
556
nm->print_nmethod_labels(env.output(), nm->consts_begin());
557
int offset = 0;
558
for (address p = nm->consts_begin(); p < nm->consts_end(); p += 4, offset += 4) {
559
if ((offset % 8) == 0) {
560
env.output()->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT " " PTR64_FORMAT, p, offset, *((int32_t*) p), *((int64_t*) p));
561
} else {
562
env.output()->print_cr(" " PTR_FORMAT " (offset: %4d): " PTR32_FORMAT, p, offset, *((int32_t*) p));
563
}
564
}
565
}
566
567
env.decode_instructions(p, end);
568
}
569
570