Mercurial > hg > graal-jvmci-8
comparison src/share/vm/compiler/disassembler.cpp @ 7066:7d815d842ee0
Merge.
author | Christian Haeubl <haeubl@ssw.jku.at> |
---|---|
date | Fri, 23 Nov 2012 11:50:27 +0100 |
parents | 8c5333c80cfd 070d523b96a7 |
children | 7ead04aea1e4 |
comparison
equal
deleted
inserted
replaced
7065:cfacf5d5bade | 7066:7d815d842ee0 |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
53 | 53 |
54 void* Disassembler::_library = NULL; | 54 void* Disassembler::_library = NULL; |
55 bool Disassembler::_tried_to_load_library = false; | 55 bool Disassembler::_tried_to_load_library = false; |
56 | 56 |
57 // This routine is in the shared library: | 57 // This routine is in the shared library: |
58 Disassembler::decode_func_virtual Disassembler::_decode_instructions_virtual = NULL; | |
58 Disassembler::decode_func Disassembler::_decode_instructions = NULL; | 59 Disassembler::decode_func Disassembler::_decode_instructions = NULL; |
59 | 60 |
60 static const char hsdis_library_name[] = "hsdis-"HOTSPOT_LIB_ARCH; | 61 static const char hsdis_library_name[] = "hsdis-"HOTSPOT_LIB_ARCH; |
62 static const char decode_instructions_virtual_name[] = "decode_instructions_virtual"; | |
61 static const char decode_instructions_name[] = "decode_instructions"; | 63 static const char decode_instructions_name[] = "decode_instructions"; |
62 | 64 static bool use_new_version = true; |
63 #define COMMENT_COLUMN 40 LP64_ONLY(+8) /*could be an option*/ | 65 #define COMMENT_COLUMN 40 LP64_ONLY(+8) /*could be an option*/ |
64 #define BYTES_COMMENT ";..." /* funky byte display comment */ | 66 #define BYTES_COMMENT ";..." /* funky byte display comment */ |
65 | 67 |
66 bool Disassembler::load_library() { | 68 bool Disassembler::load_library() { |
67 if (_decode_instructions != NULL) { | 69 if (_decode_instructions_virtual != NULL || _decode_instructions != NULL) { |
68 // Already succeeded. | 70 // Already succeeded. |
69 return true; | 71 return true; |
70 } | 72 } |
71 if (_tried_to_load_library) { | 73 if (_tried_to_load_library) { |
72 // Do not try twice. | 74 // Do not try twice. |
121 strcpy(&buf[0], hsdis_library_name); | 123 strcpy(&buf[0], hsdis_library_name); |
122 strcat(&buf[0], os::dll_file_extension()); | 124 strcat(&buf[0], os::dll_file_extension()); |
123 _library = os::dll_load(buf, ebuf, sizeof ebuf); | 125 _library = os::dll_load(buf, ebuf, sizeof ebuf); |
124 } | 126 } |
125 if (_library != NULL) { | 127 if (_library != NULL) { |
128 _decode_instructions_virtual = CAST_TO_FN_PTR(Disassembler::decode_func_virtual, | |
129 os::dll_lookup(_library, decode_instructions_virtual_name)); | |
130 } | |
131 if (_decode_instructions_virtual == NULL) { | |
132 // could not spot in new version, try old version | |
126 _decode_instructions = CAST_TO_FN_PTR(Disassembler::decode_func, | 133 _decode_instructions = CAST_TO_FN_PTR(Disassembler::decode_func, |
127 os::dll_lookup(_library, decode_instructions_name)); | 134 os::dll_lookup(_library, decode_instructions_name)); |
135 use_new_version = false; | |
136 } else { | |
137 use_new_version = true; | |
128 } | 138 } |
129 _tried_to_load_library = true; | 139 _tried_to_load_library = true; |
130 if (_decode_instructions == NULL) { | 140 if (_decode_instructions_virtual == NULL && _decode_instructions == NULL) { |
131 tty->print_cr("Could not load %s; %s; %s", buf, | 141 tty->print_cr("Could not load %s; %s; %s", buf, |
132 ((_library != NULL) | 142 ((_library != NULL) |
133 ? "entry point is missing" | 143 ? "entry point is missing" |
134 : (WizardMode || PrintMiscellaneous) | 144 : (WizardMode || PrintMiscellaneous) |
135 ? (const char*)ebuf | 145 ? (const char*)ebuf |
146 | 156 |
147 class decode_env { | 157 class decode_env { |
148 private: | 158 private: |
149 nmethod* _nm; | 159 nmethod* _nm; |
150 CodeBlob* _code; | 160 CodeBlob* _code; |
161 CodeComments _comments; | |
151 outputStream* _output; | 162 outputStream* _output; |
152 address _start, _end; | 163 address _start, _end; |
153 | 164 |
154 char _option_buf[512]; | 165 char _option_buf[512]; |
155 char _print_raw; | 166 char _print_raw; |
185 void print_insn_labels(); | 196 void print_insn_labels(); |
186 void print_insn_bytes(address pc0, address pc); | 197 void print_insn_bytes(address pc0, address pc); |
187 void print_address(address value); | 198 void print_address(address value); |
188 | 199 |
189 public: | 200 public: |
190 decode_env(CodeBlob* code, outputStream* output); | 201 decode_env(CodeBlob* code, outputStream* output, CodeComments c = CodeComments()); |
191 | 202 |
192 address decode_instructions(address start, address end); | 203 address decode_instructions(address start, address end); |
193 | 204 |
194 void start_insn(address pc) { | 205 void start_insn(address pc) { |
195 _cur_insn = pc; | 206 _cur_insn = pc; |
216 st->bol(); | 227 st->bol(); |
217 st->print_cr("%3.1f%% [%d]", bucket_count*100.0/total_ticks(), bucket_count); | 228 st->print_cr("%3.1f%% [%d]", bucket_count*100.0/total_ticks(), bucket_count); |
218 } | 229 } |
219 } | 230 } |
220 } | 231 } |
232 // follow each complete insn by a nice newline | |
233 st->cr(); | |
221 } | 234 } |
222 | 235 |
223 address handle_event(const char* event, address arg); | 236 address handle_event(const char* event, address arg); |
224 | 237 |
225 outputStream* output() { return _output; } | 238 outputStream* output() { return _output; } |
227 int total_ticks() { return _total_ticks; } | 240 int total_ticks() { return _total_ticks; } |
228 void set_total_ticks(int n) { _total_ticks = n; } | 241 void set_total_ticks(int n) { _total_ticks = n; } |
229 const char* options() { return _option_buf; } | 242 const char* options() { return _option_buf; } |
230 }; | 243 }; |
231 | 244 |
232 decode_env::decode_env(CodeBlob* code, outputStream* output) { | 245 decode_env::decode_env(CodeBlob* code, outputStream* output, CodeComments c) { |
233 memset(this, 0, sizeof(*this)); | 246 memset(this, 0, sizeof(*this)); |
234 _output = output ? output : tty; | 247 _output = output ? output : tty; |
235 _code = code; | 248 _code = code; |
236 if (code != NULL && code->is_nmethod()) | 249 if (code != NULL && code->is_nmethod()) |
237 _nm = (nmethod*) code; | 250 _nm = (nmethod*) code; |
251 _comments.assign(c); | |
238 | 252 |
239 // by default, output pc but not bytes: | 253 // by default, output pc but not bytes: |
240 _print_pc = true; | 254 _print_pc = true; |
241 _print_bytes = false; | 255 _print_bytes = false; |
242 _bytes_per_line = Disassembler::pd_instruction_alignment(); | 256 _bytes_per_line = Disassembler::pd_instruction_alignment(); |
337 && Universe::heap()->is_in(obj->klass())) { | 351 && Universe::heap()->is_in(obj->klass())) { |
338 julong c = st->count(); | 352 julong c = st->count(); |
339 obj->print_value_on(st); | 353 obj->print_value_on(st); |
340 if (st->count() == c) { | 354 if (st->count() == c) { |
341 // No output. (Can happen in product builds.) | 355 // No output. (Can happen in product builds.) |
342 st->print("(a %s)", Klass::cast(obj->klass())->external_name()); | 356 st->print("(a %s)", obj->klass()->external_name()); |
343 } | 357 } |
344 return; | 358 return; |
345 } | 359 } |
346 } | 360 } |
347 | 361 |
354 outputStream* st = output(); | 368 outputStream* st = output(); |
355 CodeBlob* cb = _code; | 369 CodeBlob* cb = _code; |
356 if (cb != NULL) { | 370 if (cb != NULL) { |
357 cb->print_block_comment(st, p); | 371 cb->print_block_comment(st, p); |
358 } | 372 } |
373 _comments.print_block_comment(st, (intptr_t)(p - _start)); | |
359 if (_print_pc) { | 374 if (_print_pc) { |
360 st->print(" " PTR_FORMAT ": ", p); | 375 st->print(" " PTR_FORMAT ": ", p); |
361 } | 376 } |
362 } | 377 } |
363 | 378 |
443 if (_print_raw) { | 458 if (_print_raw) { |
444 // Print whatever the library wants to print, w/o fancy callbacks. | 459 // Print whatever the library wants to print, w/o fancy callbacks. |
445 // This is mainly for debugging the library itself. | 460 // This is mainly for debugging the library itself. |
446 FILE* out = stdout; | 461 FILE* out = stdout; |
447 FILE* xmlout = (_print_raw > 1 ? out : NULL); | 462 FILE* xmlout = (_print_raw > 1 ? out : NULL); |
448 return (address) | 463 return use_new_version ? |
464 (address) | |
465 (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end, | |
466 start, end - start, | |
467 NULL, (void*) xmlout, | |
468 NULL, (void*) out, | |
469 options(), 0/*nice new line*/) | |
470 : | |
471 (address) | |
449 (*Disassembler::_decode_instructions)(start, end, | 472 (*Disassembler::_decode_instructions)(start, end, |
450 NULL, (void*) xmlout, | 473 NULL, (void*) xmlout, |
451 NULL, (void*) out, | 474 NULL, (void*) out, |
452 options()); | 475 options()); |
453 } | 476 } |
454 | 477 |
455 return (address) | 478 return use_new_version ? |
479 (address) | |
480 (*Disassembler::_decode_instructions_virtual)((uintptr_t)start, (uintptr_t)end, | |
481 start, end - start, | |
482 &event_to_env, (void*) this, | |
483 &printf_to_env, (void*) this, | |
484 options(), 0/*nice new line*/) | |
485 : | |
486 (address) | |
456 (*Disassembler::_decode_instructions)(start, end, | 487 (*Disassembler::_decode_instructions)(start, end, |
457 &event_to_env, (void*) this, | 488 &event_to_env, (void*) this, |
458 &printf_to_env, (void*) this, | 489 &printf_to_env, (void*) this, |
459 options()); | 490 options()); |
460 } | 491 } |
466 env.output()->print_cr("----------------------------------------------------------------------"); | 497 env.output()->print_cr("----------------------------------------------------------------------"); |
467 env.output()->print_cr("%s at [" PTR_FORMAT ", " PTR_FORMAT "] %d bytes", cb->name(), cb->code_begin(), cb->code_end(), ((jlong)(cb->code_end() - cb->code_begin())) * sizeof(unsigned char*)); | 498 env.output()->print_cr("%s at [" PTR_FORMAT ", " PTR_FORMAT "] %d bytes", cb->name(), cb->code_begin(), cb->code_end(), ((jlong)(cb->code_end() - cb->code_begin())) * sizeof(unsigned char*)); |
468 env.decode_instructions(cb->code_begin(), cb->code_end()); | 499 env.decode_instructions(cb->code_begin(), cb->code_end()); |
469 } | 500 } |
470 | 501 |
471 | 502 void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) { |
472 void Disassembler::decode(address start, address end, outputStream* st) { | |
473 if (!load_library()) return; | 503 if (!load_library()) return; |
474 decode_env env(CodeCache::find_blob_unsafe(start), st); | 504 decode_env env(CodeCache::find_blob_unsafe(start), st, c); |
475 env.decode_instructions(start, end); | 505 env.decode_instructions(start, end); |
476 } | 506 } |
477 | 507 |
478 void Disassembler::decode(nmethod* nm, outputStream* st) { | 508 void Disassembler::decode(nmethod* nm, outputStream* st) { |
479 if (!load_library()) return; | 509 if (!load_library()) return; |